2016-04-27 49 views
1

私は、次の(最も近いものではない)小数点以下第四位まで四捨五入するPostgres主導のアプリケーションを持っています。したがって、0.00341は0.0035になります。PostgreSQLの浮動小数点演算とタイプ

これを実装するにあたって、0.0012 の場合でも、それはしないでください。それは0.0012です。実際には、でもceil()一目見ただけで、同意する:

postgres=> SELECT ceil(((0.0012) * 10000))/10000; 
     ?column?   
------------------------ 
0.00120000000000000000 
(1 row) 

我々が導入なし任意の精度がないことを知っている:図0.0012は計算の仕方によって到達したとき、

postgres=> SELECT (ceil(((0.0012) * 10000))/10000) = 0.0012; 
?column? 
---------- 
t 
(1 row) 

しかし、、状況が変わる:

postgres=> SELECT (12::double precision/60) * 0.006; 
?column? 
---------- 
    0.0012 
(1 row) 

postgres=> SELECT ((12::double precision/60) * 0.006) = 0.0012; 
?column? 
---------- 
f 
(1 row) 

計算された0.0012は0.0012実際よりも大きくなるように思われます。

postgres=> SELECT ((12::double precision/60) * 0.006) > 0.0012; 
?column? 
---------- 
t 
(1 row) 

予想通り、この式も0.0012と評価された場合、明らかに間違っている0.0013に「アップ」0.0012を丸める丸めメカニズム、リード:明らかに、私は何かが欠けてる、だから、

postgres=> SELECT ceil(((12::double precision/60) * 0.006) * 10000)/10000; 
?column? 
---------- 
    0.0013 
(1 row) 

を式の評価方法および/または関連するデータ型のキャスト方法については、こちらを参照してください。導入されるべきではない追加の精度が導入されました。

助けていただけたら幸いです!

+1

これは決してPostgresに特有のものではありません。私は多くのプログラミング言語で同じ結果を得ているので、明らかに型と精度について何か不足しています。 –

+1

PostgreSQL(など)は独自の算術演算を使用せず、代わりにCPU/OSを使用します。 [浮動小数点演算の制限事項](https://en.wikipedia.org/wiki/Floating_point#Accuracy_problems)に関する多くの情報があります。適切な結果を得るために、適切な精度/スケールを指定します。例えば、 'SELECT((12 :: numeric(16,8)/ 60)* 0.006)= 0.0012;' ''を返す ' – Abelisto

+0

http://floating-point-gui.de/ –

答えて

2

私は自分の方法の誤りを見ます。これは、PostgreSQLのnumericタイプの仕事です。正確な計算を提供するために意図された任意の精度タイプです。 http://www.postgresql.org/docs/9.5/static/datatype-numeric.htmlから

8.1.2。任意の精度の数値

数値型は、非常に大きい桁数の数字を格納し、正確に計算を実行できます。特に、 に金額とその他正確な数値が格納されている場合は、 が必要です。ただし、数値の算術演算は、整数型、または 次のセクションで説明されている浮動小数点型に対して、 と比較して非常に遅いです。

関連する問題