« 2008年5月 | トップページ | 2008年7月 »

2008年6月

2008年6月 7日 (土)

数値型の憂鬱(2)

前回の続きである。

高精度の数値の演算つまり多倍長演算のルーチンを自作するのもいいのだが、なるべくなら既存の信頼におけるものを使いたいものである。Googleなどの検索サイトで多倍長演算ライブラリを検索すれば、様々なライブラリが見つかり、開発環境の言語に合わせて選択できるが、WindowsのOS自体に用意されているライブラリを使う事もできる。

正確に言うと、WindowsのOS自体というより、WindowsのOLEオートメーションで主に使われるバリアントのために用意されているライブラリで、oleaut32.dll

  • VarDecAdd(加算)
  • VarDecSub(減算)
  • VarDecMul(乗算)
  • VarDecDiv(除算)
  • VarDecAbs(絶対値)
  • VarDecFix
  • VarDecInt
  • VarDecRound
  • VarDecNeg
  • VarDecCmp(比較)

などのAPIを使って多倍長演算を行うことができる。これらのAPIは、主に、DECIMAL構造体へのポインタを引数に取り、DECIMAL構造体は次のように宣言されている。

Numeric2_1_3 

wReservedフィールドはバリアントに格納されているデータの型を表し、Decimal型の場合、vt_decimal(14)、scaleフィールドは小数点の位置を表し、signフィールドを符号を表し、hi32、low32、mid32フィールドにスケーリングされた数値が整数値として格納される。

これとODBCを組み合わせてもよいのだが、上述のDecimal構造体のスケーリングされた整数値を格納する領域が96ビットなので、2の96乗つまり最大精度28桁までの数値しか表現できないwobbly。28桁だと最大精度38桁のOracleのNUMBER型はもとよりDB2のNUMBER型すら完全に表現できない・・・

んー。OSで多倍長演算ももっとサポートしてほしいのだが・・あまり、そのような要望はないのだろうか?

2008年6月 6日 (金)

数値型の憂鬱

今回は数値型の憂鬱である。

たいていのデータベースには、高精度の数値を表すデータ型が用意されている。DB2で言えば、DECIMAL/NUMERIC型で、最大精度31桁の巨大な数値を表現することができる。何が憂鬱かというと、これら高精度の数値をクライアント・アプリケーションで入出力するだけなら、高精度の数値を文字列として入出力すれば楽であるが、クライアント・アプリケーションでこられの数値を演算したり比較したりするとなると、途端に面倒になるのである。

というのも、たいていのクライアント・アプリケーションの開発環境では、このような高精度の数値を表現するデータ型がデフォルトで用意されていないからである(JavaならBigIntegerBigDecimalクラス、.NETならDecimal型が用意されているが・・)。

ちなみに、ODBCではこれら高精度の数値を表現するCデータ型としてSQL_C_NUMERICが用意されていて、SQL_NUMERIC_STRUCT構造体として入出力することもできる。SQL_NUMERIC_STRUCT構造体は次のようになる。

Numeric1_3   

precisionフィールドは有効桁数、scaleフィールドは小数点の位置、signフィールドは符号を表し、valフィールドにはスケールされた数値(整数値として)が格納される。ちなみに、valフィールドは16バイト長なので、2の128(16*8)乗つまり最大精度約38桁までの数値を表現できることになる。

と、高精度の数値を表すCデータ型が用意されているのであるが、加減乗除などの演算や比較を行うためのルーチンが用意されていないので、自前で用意するなどしなければならず頭が痛いのであるsad。ちなみに、SQL_NUMBER_STRUCTの使い方はここ

« 2008年5月 | トップページ | 2008年7月 »

自作ソフトウェア

無料ブログはココログ

メモ