[pgsql-jp: 41816] Re: 【質問】バイナリのnumeric値をdouble値に変換する方法

Tomoaki Sato sato @ sraoss.co.jp
2015年 8月 18日 (火) 23:39:15 JST


佐藤です。

> 宇野と申します。
> 
> libpqライブラリを使用して
> OidがNUMERICOIDの列の値をPQgetvalue関数で取得するのですが、
> それをどのようにdouble値に変換したらよいかわかりません。
> ちなみに問い合わせ結果値はバイナリ形式で受け取っています。
> 
> PQgetvalueで受け取るのはNumericData構造体(numeric.c参照)
> のポインタだと思いますが...

違います。

numeric 型のバイナリ書式は numeric.c の関数 numeric_send で変換されたも
のです。

  pq_sendint(&buf, x.ndigits, sizeof(int16));
  pq_sendint(&buf, x.weight, sizeof(int16));
  pq_sendint(&buf, x.sign, sizeof(int16));
  pq_sendint(&buf, x.dscale, sizeof(int16));
  for (i = 0; i < x.ndigits; i++)
      pq_sendint(&buf, x.digits[i], sizeof(NumericDigit));

例えば、123 であればバイナリ書式は以下のようになります。

  \000\001\000\000\000\000\000\000\000\173

> 参考にするソースとか教えていただければ助かります。

関数 numeric_recv で逆の変換 (NumericVar 型への変換) を行っているので、
バイナリ書式の解析に参考になると思います。また、NumericVar 型から
double 型に変換する関数 numericvar_to_double_no_overflow もあります。

ただ、関数 numericvar_to_double_no_overflow では numeric 型の値を文字列
に変換し、strtod 関数で double 型に変換しているので、テキスト書式で受け
とって strtod 関数で double 型に変換したほうがいいと思います。

  res = PQexec(conn, "SELECT 123::numeric");
  printf("%f\n", strtod(PQgetvalue(res, 0, 0), NULL));


----
Tomoaki Sato <sato @ sraoss.co.jp>
SRA OSS, Inc. Japan


pgsql-jp メーリングリストの案内