''[[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]]