''[[FrontPage]]''
* 可変長数値表現を実装する [#tecf7608]

可変長数値表現とは、あらかじめ大きさの分からない数値を、少ないバイト数で表現しようとする工夫である。~
オクテットのうち最上位ビットを、次のオクテットが続くかの判定に用い、残りの7ビットを数値表現に使う。~
したがって、127以下の数値が頻繁に登場するようなデータをファイルに出力する場合などに、大きな効果が期待できる。~
有名なのは、Standard MIDI Fileのデルタ値表現である。~
~
今回は、INT型の数値を可変長数値表現で表すコードを載せてみます。~

#ref(http://bj006.com/bjwiki/image/VLNE.png)

** C++による可変長数値表現のテスト [#c406bea4]
 #include        <stdio.h>                                       //  標準入出力                                    //
                                                                 //                                                //
 int numInBytes( unsigned char* vd_bytes, int vd_data );         //  可変長数値表現を行う関数                      //
                                                                 //                                                //
 /* VLNE Test **************************************************//*  可変長数値表現のテスト                        */
 int main( void )                                                //                                                //
 {                                                               //                                                //
     int data = 0;                                               //  元となるデータ                                //
     int byteCnt = 0;                                            //  消費したバイト数の受取り用                    //
     int cnt = 0;                                                //  ループカウンタ                                //
     unsigned char bytes[4] = { 0, 0, 0, 0 };                    //  最大で4バイトの消費を見込む                   //
                                                                 //                                                //
     for( ; ; )                                                  //  無限ループ                                    //
     {                                                           //                                                //
         printf( "input >" );                                    //  画面表示                                      //
         scanf( "%d", &data );                                   //  元となるデータの取得                          //
                                                                 //                                                //
         byteCnt = numInBytes( bytes, data );                    //  可変長数値表現を依頼                          //
                                                                 //                                                //
         for( ; byteCnt > cnt; cnt++ )                           //  消費したバイト数分繰り返す                    //
         {                                                       //                                                //
             printf( "%#2x " , bytes[cnt] );                     //  画面表示                                      //
         }                                                       //                                                //
                                                                 //                                                //
         break;                                                  //  ループを抜ける                                //
     }                                                           //                                                //
                                                                 //                                                //
     return( 0 );                                                //  処理終了                                      //
 }                                                               //                                                //
 //*VLNE Test **************************************************//*  可変長数値表現のテスト                        */
 /* Variable Length Numeric Expression *************************//*  可変長数値表現を行う関数                      */
 int numInBytes( unsigned char* vd_bytes, int vd_data )          //                                                //
 {                                                               //                                                //
     int rtnNum = 0;                                             //  消費したバイト数を返すリターンコード          //
                                                                 //                                                //
     if( 0x7F >= vd_data )                                       //  デルタ値が1バイトで表せるか                   //
     {                                                           //  デルタ値が1バイトで表せる場合                 //
         vd_bytes[0] = (char)vd_data;                            //  1バイト目にそのまま格納                       //
         rtnNum = 1;                                             //  消費したバイト数をリターンに設定              ///
     }                                                           //                                                //
     else if( 0x3FFF >= vd_data )                                //  デルタ値が2バイトで表せるか                   //
     {                                                           //  デルタ値が2バイトで表せる場合                 //
         vd_bytes[0] = 0x80 | ((vd_data & 0x3F80) >> 7);         //  1バイト目を編集                               //
         vd_bytes[1] = 0x7F & vd_data;                           //  2バイト目を編集                               //
         rtnNum = 2;                                             //  消費したバイト数をリターンに設定              //
     }                                                           //                                                //
     else if( 0x1FFFFF >= vd_data )                              //  デルタ値が3バイトで表せるか                   //
     {                                                           //  デルタ値が3バイトで表せる場合                 //
         vd_bytes[0] = 0x80 | ((vd_data & 0x1FC000) >> 14);      //  1バイト目を編集                               //
         vd_bytes[1] = 0x80 | ((vd_data & 0x3F80) >> 7);         //  2バイト目を編集                               //
         vd_bytes[2] = 0x7F & vd_data;                           //  3バイト目を編集                               //
         rtnNum = 3;                                             //  消費したバイト数をリターンに設定              //
     }                                                           //                                                //
     else if( 0x0FFFFFFF >= vd_data )                            //  デルタ値が4バイトで表せるか                   ///
     {                                                           //  デルタ値が4バイトで表せる場合                 ///
         vd_bytes[0] = 0x80 | ((vd_data & 0x0FE00000) >> 21);    //  1バイト目を編集                               // 
         vd_bytes[1] = 0x80 | ((vd_data & 0x1FC000) >> 14);      //  2バイト目を編集                               // 
         vd_bytes[2] = 0x80 | ((vd_data & 0x3F80) >> 7);         //  3バイト目を編集                               // 
         vd_bytes[3] = 0x7F & vd_data;                           //  4バイト目を編集                               // 
         rtnNum = 4;                                             //  消費したバイト数をリターンに設定              ///
     }                                                           //                                                //
                                                                 //                                                //
     return( rtnNum );                                           //  消費したバイト数を返して終了                  //
 }                                                               //                                                //
 //*Variable Length Numeric Expression *************************//*  可変長数値表現を行う関数                      */

** 表示結果: [#a722e213]
 input >16384
 0x81 0x80  0

*** 修正履歴 [#scd64431]
~

*** 課題 [#g5834b51]
-備考~
~

*** 参考ページ [#bde7f346]
[[Wikipedia:http://ja.wikipedia.org/wiki/%E5%8F%AF%E5%A4%89%E9%95%B7%E6%95%B0%E5%80%A4%E8%A1%A8%E7%8F%BE]]

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS