儲存大浮點值時值錯誤
我在使用 mariadb 時遇到了一個奇怪的問題。
CREATE DATABASE testdb; USE testdb; CREATE TABLE testing (afloat FLOAT NULL); INSERT INTO testing VALUES(123456789.0); SELECT * FROM testing;
但不是返回
123456789
,而是返回123457000
。我知道 IEEE 754 中浮點數的精度,但即使考慮到這一點,實際儲存的值也是
123456792
.我遇到了這個文件,但我對 ISO C 標準沒有那麼豐富的經驗。 https://dev.mysql.com/doc/internals/en/floating-point-types.html
有人可以解釋一下為什麼 mariadb 沒有儲存預期值嗎?
PS:我知道可以使用雙精度解決問題,但我想了解為什麼它不能使用浮點數。
為什麼浮點數被解釋為 123457000
outout格式化過程就是這樣做的。(由於您沒有指定使用什麼工具來執行此操作
SELECT
,因此我無法具體說明。)任何輸出過程都必須決定如何處理不精確的數據。
- 它應該顯示多少位小數
SELECT 1/3;
?- 既然
FLOAT
只有大約 6-7 個有效數字,為什麼還要顯示更多呢?(DOUBLE
: 16)- 是否應該設計輸出以便重新讀取字元串將獲得相同的二進制值?
由此,我看到你的例子違反了#3:
hex float check 4ceb79a3 --> 123456792 --> 4ceb79a3 4ceb79bd --> 123457000 --> 4ceb79bd - off by 26 ULPs
從這些,我看到輸出應該使用 8 位數字來滿足#3:
4ceb79a4 --> 123456800 --> 4ceb79a4 - 7 digits is not quite close enough (1 ULP)
隨時針對有問題的特定產品送出錯誤報告。在此處提供連結,我可能會添加我的 2 美分價值。
“為什麼 mariadb 沒有儲存預期值”——嘗試
SELECT 1.0*flt FROM ...
查看儲存的內容。那應該提供顯示為的值DOUBLE
。我聲稱問題出在顯示器上,而不是儲存上。
FLOAT
並且DOUBLE
都代表浮點數。A
FLOAT
是單精度數,aDOUBLE
是雙精度數。浮點數和十進制(數字)數有很大的不同,您可以將其與 DECIMAL 數據類型一起使用。這用於儲存精確的數字數據值,與浮點數不同,在浮點數中保持精確的精度很重要,例如貨幣數據。
範例:浮點數會四捨五入,而小數則不會。Decimal(9,3) 例如可以是 123456.789,如果您嘗試儲存 123456.789,它將作為浮點數插入 123456.0。
檢查以獲得更好的理解:https ://stackoverflow.com/questions/2160810/mysql-whats-the-difference-between-float-and-double
檢查浮點數問題:https ://dev.mysql.com/doc/refman/8.0/en/problems-with-float.html