Mysql

儲存大浮點值時值錯誤

  • September 28, 2021

我在使用 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,因此我無法具體說明。)

任何輸出過程都必須決定如何處理不精確的數據。

  1. 它應該顯示多少位小數SELECT 1/3;
  2. 既然FLOAT只有大約 6-7 個有效數字,為什麼還要顯示更多呢?( DOUBLE: 16)
  3. 是否應該設計輸出以便重新讀取字元串將獲得相同的二進制值?

由此,我看到你的例子違反了#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都代表浮點數。

AFLOAT是單精度數,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

引用自:https://dba.stackexchange.com/questions/300214