2016-08-19 13 views
-1

これはanswerと多少関連しています。フロートは高精度のために提案されていないと私は理解しています。しかし、私はちょうど2以下のクエリによって返される値は、Mysqlの浮動小数点はどうなっていますか?

SELECT MY_FLOAT_COL FROM MY_TABLE; 

SELECT MY_FLOAT_COL*1 FROM MY_TABLE; 
を異なる結果を返す

観察1

、以下の結果を経てFLOATで何が起こっているのか得ることはありません

可能な説明は上記のリンクの参照です。浮動小数点数は近似値であり、問​​題はデータ型です。

観測2

クエリ

SELECT MY_FLOAT_COL*1 FROM MY_TABLE; 

SELECT MY_FLOAT_COL FROM MY_TABLE; 

私はリスSQL(ジャワ)を使用して実行すると同じ結果を返すが、ハイジSQL(オブジェクトパスカル)とPythonを介して実行されたときに異なる結果を返しますスクリプト。したがって、これはクライアントに問題があるという結論につながります。

MysqlのFloatデータ型ではどういうことが起こっているのですか。私は2つ以上の観測を理解しようとしています。

編集:私はさらに気になります観測2観測1しかし、後者は今のところ神秘的です。

+0

異なるSQLエンジンは、異なるいくつかのものを実装しています。あなたの質問は何ですか? –

+0

すべての観測値は同じサーバーにあります。私の質問は、観測の意味を理解しようとしたように... – Kannan

答えて

2

1を乗算すると、結果はDOUBLEに変換されます。これにより精度が向上し、その結果、小数点近似の誤差を見ることができます。 DOUBLE列にFLOAT列を割り当てることで同じことが分かります。

CREATE TABLE `my_table` (
    `my_float_col` float, 
    `my_double_col` double 
); 
INSERT INTO my_table (my_float_col) values (1.2355); 
UPDATE my_table SET my_double_col = my_float_col; 
SELECT my_float_col, my_double_col, my_float_col * 1 FROM my_table; 
+--------------+--------------------+--------------------+ 
| my_float_col | my_double_col  | my_float_col * 1 | 
+--------------+--------------------+--------------------+ 
|  1.2355 | 1.2354999780654907 | 1.2354999780654907 | 
+--------------+--------------------+--------------------+ 

documentationが言うので、私は、それは乗算からDOUBLEを返している理由は本当にわからない:

+のオペランドのいずれかの場合は、-/*%がAで、実数または文字列の値の場合、結果の精度は最大精度のオペランドの精度になります。

しかし、明らかに何が起こっているのですか。私は以下の持っているBarmarの答えをわずかに変更して説明することができます何が起こっている

+0

Barmar、私はケースが私が発掘された謎のマニュアルページで解決されたと思います。 – Drew

+0

うれしい私はあなたを正しい軌道に乗せることができました。 – Barmar

+0

あなたはいつもBarmarを実行します:p – Drew

2

:Barmarため

drop table if exists my_table2; 
CREATE TABLE `my_table2` (
    `my_float_col` float(18,16), -- FLOAT(M,D) 
    `my_double_col` double(18,16) 
); 
INSERT INTO my_table2 (my_float_col) values (1.2355); -- 1.2354999780654907 
UPDATE my_table2 SET my_double_col = my_float_col; 
SELECT my_float_col, my_double_col, my_float_col * 1 FROM my_table2; 
+--------------------+--------------------+--------------------+ 
| my_float_col  | my_double_col  | my_float_col * 1 | 
+--------------------+--------------------+--------------------+ 
| 1.2354999780654907 | 1.2354999780654907 | 1.2354999780654907 | 
+--------------------+--------------------+--------------------+ 

フロート(コラム1)は鉱山があると同じようにCのfloatデータ型です。しかし、彼は精度(M,D)を指定していないので、Cの内部実装はCフロートとしてペグしますが、同じ値を持ちますが、実際はBarmarのものではなくなります。彼のディスプレイの幅はそれを丸めるだけです。それを示すことができる私が下で作成した関数に注意してください。

そして、このユーモラスなMySQLマニュアルページFLOAT and DOUBLE Data Type Representationをチェックしてみてください。それを掘り下げている人にとっては非常に分かりやすいでしょう。とにかく、私たちは数学の頭部になるだろうから:

ここで、MySQLリファレンスマニュアル がどこから離れるのか話をしましょう。

以下の説明は、ディスプレイ の幅と小数点が与えられていない場合を中心に説明しています。つまり、FLOATはCタイプのfloatが何であっても として格納され、REALまたはDOUBLE [PRECISION]はCタイプのdoubleであれば として格納されます。フィールド長は、 MySQLコードによって選択されます。

だから出力のBarmarの最初の列にもかかわらず、それは1.2355としてそこにはなかった、と上記のマニュアルページは巧みとユーモラスにヘッドバンギングの人が通過したことを説明しています。

ヘルパーFCN関心の場合:

DROP FUNCTION IF EXISTS returnFloatFromDec; 
DELIMITER $$ 
CREATE FUNCTION returnFloatFromDec(n DECIMAL(18,16)) 
returns FLOAT 
BEGIN 
    DECLARE theRet FLOAT; 
    SET theRet=n; -- note that CAST can't take a FLOAT 
    return(theRet); 
END;$$ 
DELIMITER ; 
+0

ありがとうございます。しかし、私はObservation 2を推論することができません。 – Kannan

+0

データはC浮動小数点として保存されていることは明らかであり、表示の問題です。上記のリンクはそれを綴ります – Drew

関連する問題