3

私はPostgreSQLテーブルに少数あります:

test=# CREATE TABLE test (r real);
CREATE TABLE
test=# INSERT INTO test VALUES (0.00000000000000000000000000000000000000000009);
INSERT 0 1

次のクエリを実行すると、数値が次のように返されます8.96831e-44

test=# SELECT * FROM test;
      r      
-------------
 8.96831e-44
(1 row)

値を科学表記法ではなくpsql10 進形式 ( )で表示するにはどうすればよいですか? 0.00000000000000000000000000000000000000000009私も嬉しい0.0000000000000000000000000000000000000000000896831です。残念ながら、テーブルを変更することはできず、精度の低下はあまり気にしません。

(私はto_charしばらくの間遊んでいましたが、成功しませんでした。)

4

1 に答える 1

2

Postgresの実数は浮動小数点データ型で、4 バイト、つまり 32 ビットで格納されます。

あなたの価値、

0.00000000000000000000000000000000000000000009

32 ビット IEEE754 浮動小数点数では正確に表現できません。この計算機で正確な値を確認できます

計算機によると、正確な表現のように思われる倍精度(64 ビット) を使用して保存しようとします。 真実ではありませんパトリシアは、明示的にしないように要求しているにもかかわらず、値を丸めるだけの計算機であることを示しました...倍精度はもう少し精度が高いことを意味しますが、この数値は有限数の2進数を使用して表現できないため、正確な値ではありません. (ありがとう、パトリシア、(再び)学んだ教訓:あなたがIntertubezで見るものを信じないでください)

通常の状況では、数値を正確に格納して正しい値を取得する NUMERIC(precision, scale) 形式を使用する必要があります。

ただし、保存する値は、正確な10進数表現でpostgresが許可する(30のように見える)よりも大きいスケールを持っているようです。計算をしたくない場合は、それらを保存するだけです(これはあまり一般的な状況ではないことは認めます)。それらを文字列として保存することもできます...(しかし、これは醜いです...)

編集

この to_char の問題は既知のバグのようです...

見積もり:

それに対する私の即時の反応は、float8 値には 57 桁の精度がないということです。そのフォーマット文字列が何か役に立つことを期待している場合は、それを倍精度列ではなく数値列に適用する必要があります。

この特定のケースを期待どおりに機能させるために、私たちが何かを仕掛けることができる可能性がありますが、精度がそこにないために機能しない、似たようなケースが常にあるでしょう.

コードをざっと見てみると、「0」が得られる理由が分かります。ガベージを印刷しないように、15 桁の後に四捨五入されます。値が 1 よりもはるかに小さい場合は少し賢くなるかもしれませんが、単純な変更ではありません。

ここから

しかし、これは擁護できないと思います。IMHO a double (正確には IEEE754 64 ビット浮動小数点) は、値が型に適合する場合、常に ~15 の有効な 10 進数を持ちます...

推奨読書:

于 2013-09-18T10:16:36.293 に答える