UPDATE some_table SET some_float_field=1919.987 WHERE id=123
SELECT * FROM some_table WHERE id=123
ここで、some_float_fieldは、「float」として定義されたフィールドです(特定のサイズ値はありません)。
結果として期待される値は1919.987です。代わりに、1919.99に丸められます
どうして? 32ビット(単精度)浮動小数点数は、それを正しく格納するのに十分な精度を備えています。
クエリを実行すると:
SELECT * FROM some_table WHERE id = 123
浮動小数点数のフォーマットは、ユーザーインターフェイスに依存しています。使用しているインターフェースは、2文字以上ではなく2文字を使用しています。結局のところ、表示する「正しい」番号に関する情報はありません。
数値を文字列または小数としてフォーマットすることにより、正しい数値を表示するようにインターフェイスを説得できます。例えば:
select format(some_float_field, 3)
これを小数点以下3桁の文字列に変換します。注意:不要なコンマも追加されます。これも機能するはずです:
select cast(some_float_field as decimal(8, 3))
また、トリックを行う必要があります。
次のような操作を行うことで、データが正しいことを簡単に検証できることに注意してください。
select *
from some_table
where some_float_field between 1919.987 - 0.0001 and 1919.987 + 0.0001;
浮動小数点値に=
を使用したくないが、すでに理解していることに注意してください。
FLOAT
のマニュアルから:
FLOAT
およびDOUBLE
タイプは、おおよその数値データ値を表します。 MySQLは単精度値に4バイトを使用します。
ここでの強調は、近似にあります。 exact値を格納する必要がある場合は、実際には DECIMAL
データ型を使用する必要があります。
FLOAT
の場合、 MySQLはバイナリ浮動小数点演算にIEEE標準754を使用して、数値の任意の部分を4バイト(またはDOUBLEの場合は8)に「圧縮」します 。
これは、値(小数部と小数)couldに関係なく、任意の値に適用されることに注意してください。 4バイトで正確に表現されます!たとえば、浮動小数点での0.01の表現は、正確に0.009999999776482582092285156250です。ただし、0.01は別のストレージ形式を使用して32ビットのメモリに完全に適合します。
ウィキペディアは浮動小数点の概念をかなりよく説明しています 。
アルゴリズムは、列定義で指定された精度の影響を受けることに注意してください。
このSQLフィドルの例を参照してください。