成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

浮點運算潛在的結果不一致問題

開發 開發工具
昨天發現了項目中的一個 bug ,是因為浮點運算的前后不一致導致的。明明是完全相同的 C 代碼,參數也嚴格一致,但是計算出了不相同的結果。我對這個現象非常感興趣,仔細研究了一下成因。

[[201284]]

昨天阿楠發現了項目中的一個 bug ,是因為浮點運算的前后不一致導致的。明明是完全相同的 C 代碼,參數也嚴格一致,但是計算出了不相同的結果。我對這個現象非常感興趣,仔細研究了一下成因。

原始代碼比較繁雜。在弄清楚原理后,我簡化了出問題的代碼,重現了這個問題:

  1. static void 
  2. foo(float x) { 
  3.     float xxx = x * 0.01f; 
  4.     printf("%d\n", (int)(x * 0.01f)); 
  5.     printf("%d\n", (int)xx); 
  6.  
  7. int 
  8. main() { 
  9.     foo(2000.0f); 
  10.     return 0; 

使用 gcc 4.9.2 ,強制使用 x87 浮點運算編譯運行,你會發現令人詫異的結果。

  1. gcc a.c -mfpmath=387 
  2.  
  3. 19 
  4. 20 
前一次的輸出是 19 ,后一次是 20 。

這是為什么呢?讓我們來看看 gcc 生成的代碼,我截取了相關的段落:

  1. flds    16(%rbp) 
  2.  flds    .LC0(%rip) 
  3.  fmulp   %st, %st(1) 
  4.  fstps   -4(%rbp)          ; 1. x * 0.01f 結果保存到內存中的 float 變量中 
  5.  flds    16(%rbp) 
  6.  flds    .LC0(%rip) 
  7.  fmulp   %st, %st(1) 
  8.  fisttpl -20(%rbp)        ; 2. x * 0.01f 結果直接轉換為整型 
  9.  movl    -20(%rbp), %eax 
  10.  movl    %eax, %edx 
  11.  leaq    .LC1(%rip), %rcx 
  12.  call    printf 
  13.  flds    -4(%rbp)                 ; 3. 讀出 1. 保存的乘法結果 
  14.  fisttpl -20(%rbp) 
  15.  movl    -20(%rbp), %eax 
  16.  movl    %eax, %edx 
  17.  leaq    .LC1(%rip), %rcx 
  18.  call    printf 

這里我做了三行注釋。

首先,0.01 是無法精確表示成 2 進制的,所以 * 0.01 這個操作一定會存在誤差。

兩次運算都是 x * 0.01f ,雖然按 C 語言的轉換規則,表達式中都是 float 時,按 float 精度運算。但這里 gcc 生成的代碼并沒有嚴格設置 FPU 的精度控制,在注釋 2 這個地方,乘法結果是直接從浮點寄存器轉換為整數的。而在注釋 1 這個地方,把乘法結果通過 fstps 以低精度形式保存到內存,再在注釋 3 的地方 flds 讀回。

所以在注釋 2 和注釋 3 的地方,浮點寄存器 st 內的值其實是有差別的,這導致了 fisttpl 轉換為整數后結果不同。

原文鏈接:https://blog.codingnow.com/2017/07/float_inconsistence.html#more

【本文為51CTO專欄作者“云風”的原創稿件,轉載請通過51CTO聯系原作者獲取授權】

戳這里,看該作者更多好文

責任編輯:xinxiaoliang 來源: 51CTO專欄
相關推薦

2024-05-11 07:37:43

數據Redis策略

2017-06-20 09:42:52

網絡安全法數據隱私法網絡安全

2021-04-18 15:01:56

緩存系統數據

2013-12-13 14:46:55

OSPFMTU鄰接關系

2024-04-07 09:00:00

MySQL

2025-04-03 09:51:37

2024-11-18 08:00:00

數據倉庫通用語義層商業智能

2013-03-29 11:16:17

2010-06-02 10:53:28

MySQL版本

2022-03-18 10:53:49

數據系統架構

2018-07-15 08:18:44

緩存數據庫數據

2021-02-03 08:01:35

SQLServerLIKE

2021-05-27 18:06:30

MySQL編碼數據

2018-07-08 07:38:28

數據庫緩存數據

2020-07-20 14:06:38

數據庫主從同步服務

2021-09-02 07:56:46

HDFSHIVE元數據

2022-03-16 15:54:52

MySQL數據format

2021-01-19 10:39:03

Redis緩存數據

2012-01-11 16:22:35

HTML 5

2023-12-22 10:19:19

數據庫鎖機制
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日韩在线观看一区 | av中文字幕在线观看 | 精品三级 | 91精品久久久久久久久久入口 | 欧美一级黄视频 | 亚洲激精日韩激精欧美精品 | 精品国产一区二区在线 | 综合色久 | 日本午夜在线视频 | 久久久精品网 | 国产一区 | 五月天婷婷综合 | 欧美不卡视频 | 亚洲一区二区三区免费视频 | 欧美一级全黄 | 欧美一区二区三区在线观看 | 亚洲精品日韩精品 | 日韩网站免费观看 | 欧美精品一区二区三区四区 在线 | 97伦理 | 久久99久久99久久 | 国产免费一区二区 | 亚洲一区久久 | av中文字幕网站 | 国产精品a免费一区久久电影 | 精品成人在线视频 | 亚洲精品电影 | 99热播放| 久久久久免费精品国产 | 在线中文字幕av | 中文字幕精品一区二区三区精品 | 欧美a免费 | 国产精品日日摸夜夜添夜夜av | 国产精品福利网 | 久久精片 | 色男人的天堂 | 亚洲一区二区精品 | 色狠狠一区 | av网站在线看 | 久久成人免费 | 九七午夜剧场福利写真 |