【mysql】浮點類型

      網友投稿 1043 2025-03-31

      浮點類型

      1. 類型介紹

      2. 數據精度說明

      3. 精度誤差說明

      浮點類型

      1. 類型介紹

      2. 數據精度說明

      3. 精度誤差說明

      浮點類型

      1. 類型介紹

      浮點數和定點數類型的特點是可以處理小數,你可以把整數看成小數的一個特例。因此,浮點數和定點數的使用場景,比整數大多了。 MySQL支持的浮點數類型,分別是 FLOAT、DOUBLE、REAL。

      FLOAT 表示單精度浮點數;

      DOUBLE 表示雙精度浮點數;

      REAL默認就是 DOUBLE。如果把 SQL 模式設定為啟用“REAL_AS_FLOAT”,那 么,MySQL 就認為 REAL 是 FLOAT。如果要啟用“REAL_AS_FLOAT”,可以通過以下 SQL 語句實現:

      SET sql_mode = “REAL_AS_FLOAT”;

      問題1: FLOAT 和 DOUBLE 這兩種數據類型的區別是什么?

      FLOAT 占用字節數少,取值范圍小;DOUBLE 占用字節數多,取值范圍也大。

      問題2: 為什么浮點數類型的無符號數取值范圍,只相當于有符號數取值范圍的一半,也就是只相當于有符號數取值范圍大于等于零的部分呢?

      MySQL 存儲浮點數的格式為:符號(S)、尾數(M)和 階碼(E)。因此,無論有沒有符號,MySQL 的浮點數都會存儲表示符號的部分。因此, 所謂的無符號數取值范圍,其實就是有符號數取值范圍大于等于零的部分。

      2. 數據精度說明

      對于浮點類型,在MySQL中單精度值使用4個字節,雙精度值使用8個字節。

      MySQL允許使用非標準語法(其他數據庫未必支持,因此如果涉及到數據遷移,則最好不要這么用):FLOAT(M,D)或DOUBLE(M,D)。這里,M稱為精度,D稱為標度。(M,D)中 M=整數位+小數位,D=小數位。 D<=M<=255,0<=D<=30。

      例如,定義為FLOAT(5,2)的一個列可以顯示為-999.99-999.99。如果超過這個范圍會報錯。

      FLOAT和DOUBLE類型在不指定(M,D)時,默認會按照實際的精度(由實際的硬件和操作系統決定)來顯示。

      說明:浮點類型,也可以加UNSIGNED,但是不會改變數據范圍,例如:FLOAT(3,2) UNSIGNED仍然只能表示0-9.99的范圍。

      不管是否顯式設置了精度(M,D),這里MySQL的處理方案如下:

      如果存儲時,整數部分超出了范圍,MySQL就會報錯,不允許存這樣的值

      如果存儲時,小數點部分若超出范圍,就分以下情況:

      若四舍五入后,整數部分沒有超出范圍,則只警告,但能成功操作并四舍五入刪除多余的小數位后保存。例如在FLOAT(5,2)列內插入999.009,近似結果是999.01。

      若四舍五入后,整數部分超出范圍,則MySQL報錯,并拒絕處理。如FLOAT(5,2)列內插入999.995和-999.995都會報錯。

      從MySQL 8.0.17開始,FLOAT(M,D) 和DOUBLE(M,D)用法在官方文檔中已經明確不推薦使用,將來可能被移除。另外,關于浮點型FLOAT和DOUBLE的UNSIGNED也不推薦使用了,將來也可能被移除。

      舉例

      CREATE TABLE test_double1( f1 FLOAT, f2 FLOAT(5,2), f3 DOUBLE, f4 DOUBLE(5,2) ); DESC test_double1;

      INSERT INTO test_double1(f1, f2) VALUES(123.45,123.45); SELECT * FROM test_double1;

      存在四舍五入問題

      INSERT INTO test_double1(f3,f4) VALUES(123.45,123.456); #存在四舍五入

      超出范圍,因為 f4(5,2),可以得知 整數位:3,小數位:2,1234.456 超出整數位的訪問了

      INSERT INTO test_double1(f3,f4) VALUES(123.45,1234.456);

      小數位超過就四舍五入,整數位超了就報錯了

      3. 精度誤差說明

      浮點數類型有個缺陷,就是不精準。下面我來重點解釋一下為什么 MySQL 的浮點數不夠精準。比如,我們設計一個表,有f1這個字段,插入值分別為0.47,0.44,0.19,我們期待的運行結果是:0.47 + 0.44 + 0.19 = 1.1。而使用sum之后查詢:

      CREATE TABLE test_double2( f1 DOUBLE ); INSERT INTO test_double2 VALUES(0.47),(0.44),(0.19);

      mysql> SELECT SUM(f1) -> FROM test_double2; +--------------------+ | SUM(f1) | +--------------------+ | 1.0999999999999999 | +--------------------+ 1 row in set (0.00 sec)

      【mysql】浮點類型

      mysql> SELECT SUM(f1) = 1.1,1.1 = 1.1 -> FROM test_double2; +---------------+-----------+ | SUM(f1) = 1.1 | 1.1 = 1.1 | +---------------+-----------+ | 0 | 1 | +---------------+-----------+ 1 row in set (0.00 sec)

      查詢結果是 1.0999999999999999。看到了嗎?雖然誤差很小,但確實有誤差。 你也可以嘗試把數據類型改成 FLOAT,然后運行求和查詢,得到的是, 1.0999999940395355。顯然,誤差更大了。

      那么,為什么會存在這樣的誤差呢?問題還是出在 MySQL 對浮點類型數據的存儲方式上。

      MySQL 用 4 個字節存儲 FLOAT 類型數據,用 8 個字節來存儲 DOUBLE 類型數據。無論哪個,都是采用二進制的方式來進行存儲的。比如 9.625,用二進制來表達,就是 1001.101,或者表達成 1.001101×2^3。如果尾數不是 0 或 5(比如 9.624),你就無法用一個二進制數來精確表達。進而,就只好在取值允許的范圍內進行四舍五入。

      在編程中,如果用到浮點數,要特別注意誤差問題,因為浮點數是不準確的,所以我們要避免使用“=”來判斷兩個數是否相等。 同時,在一些對精確度要求較高的項目中,千萬不要使用浮點數,不然會導致結果錯誤,甚至是造成不可挽回的損失。那么,MySQL 有沒有精準的數據類型呢?當然有,這就是定點數類型:DECIMAL。

      MySQL

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:如何在EXCEL單元格內劃線(如何在單元格里劃線)
      下一篇:excel復制粘貼時怎么保持列寬不變(excel表格復制粘貼行高列寬不變)
      相關文章
      亚洲AV中文无码字幕色三| 亚洲日本一区二区三区在线不卡| 久久精品国产亚洲一区二区三区| 亚洲熟妇成人精品一区| 天堂亚洲国产中文在线| 亚洲AV无码久久久久网站蜜桃| 亚洲精品亚洲人成在线观看麻豆| 337p欧洲亚洲大胆艺术| 亚洲精品不卡视频| 亚洲精品电影天堂网| 亚洲欧洲日产v特级毛片| 337p日本欧洲亚洲大胆精品555588 | 亚洲黄色在线网站| 综合自拍亚洲综合图不卡区| 久久亚洲熟女cc98cm| 亚洲欧洲校园自拍都市| 亚洲一区二区三区在线网站| 狠狠色香婷婷久久亚洲精品| 亚洲熟女www一区二区三区| 亚洲精品无码专区久久| 亚洲精品理论电影在线观看| 无码天堂亚洲国产AV| 亚洲高清国产拍精品青青草原 | 亚洲伦另类中文字幕| 99人中文字幕亚洲区| 亚洲成综合人影院在院播放| 亚洲三级中文字幕| 亚洲日韩精品无码专区加勒比| 亚洲国产一区二区三区在线观看 | 亚洲人成色77777| 亚洲国产精品久久久久婷婷老年| 亚洲视频一区在线播放| 亚洲一区二区三区国产精品无码| 四虎亚洲精品高清在线观看| 亚洲高清国产拍精品熟女| 日批日出水久久亚洲精品tv| 国产精品亚洲精品日韩已方| 久久国产亚洲精品麻豆| 亚洲视频网站在线观看| 亚洲婷婷第一狠人综合精品| 亚洲成AV人片高潮喷水|