mysql float, double精度


float、double精度可能丟失,decimal精度不會丟失,所以建議decimal來存儲金額值。

在mysql中,我們用【小數數據類型(總長度,小數點長度)】來表示小數的總長度和小數點后面的長度。decimal(m,n)。n就是小數點后面的 數字個數。float(m,n)、double(m,n)含義差不多,都是定義長度和精度的。

下面看實操演示

-- total_price精度為小數點后六位
CREATE TABLE `order` ( `id` bigint(11) NOT NULL, `total_price` float(10,6) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- insert
INSERT INTO `co_job`.`order`(`total_price`) VALUES (32.214);

-- query
SELECT * FROM `order` WHERE `id` = 1;


第一種情況: 存入小數精度不夠6位

那么mysql會盡可能以近似的值存儲,以保證精度。這里會出現精度丟失

 

第二種情況: 存入小數精度剛好6位

INSERT INTO `order`(`total_price`) VALUES (32.214412);
SELECT * FROM `order` WHERE `id` = 2;

 

 

仍然發生了精度丟失。

在查閱資料可知,單精度類型float和雙精度類型double在計算機中存儲的時候,由於計算機只能存儲二進制,所以浮點型數據在存儲的時候,必須轉化成二進制。在計算機中,float型數據的存儲格式為

 

 比如8.25用二進制表示可表示為1000.01,轉成指數的形式1.00001*2^3,在計算機中

 

我們知道對於float類型的數據,只分配了32位的存儲空間,對於double類型值分配了64位,但是並不是所有的實數都能轉成32位或者64位的二進制形式,如果超過了,就會出現截斷,這就是誤差的來源。

比如131072.32轉成二進制后的數據為:100000000000000000.0101000111101011100001010001111010111000010100011111… 這是一個無窮數,對於float類型,只能截取前32位進行存儲,對於double只能截取前64位進行存儲。所以 131072.32保存為float類型是存儲形式為:01001000000000000000000000010100; 131072.32保存為double類型的格式為:0100000100000000000000000000001010001111010111000010100011110101

針對float情況,至少我們可以得出結論:

1.如果一個float型數據轉成二進制后的第32位之后都是0,那么數據是准的

2.如果一個float型數據轉成二進制后的第32位之后不全為0,則數據就會存在誤差

 

第三種情況:存入小數精度大於6位

這種情況不必多說,一定會出現精度丟失。

 

 

 

參考資料:https://cloud.tencent.com/developer/article/1866266

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM