日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

3 float py 位小数 裁剪_对一个 float 精度问题的分析

發布時間:2025/3/12 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 3 float py 位小数 裁剪_对一个 float 精度问题的分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

原問題見:

有1個c語音的源代碼不清楚它為什么輸出這個數,所以想請教一下??www.zhihu.com

大概說一下問題,對于程序:

float a = 123456.789e5; float b = a + 20; printf("%fn", b);

將輸出什么?是12345678920.000000 嗎?

下面僅考慮 float 為使用 IEEE 754 32 位單精度浮點數的情況,

即 float 為 32 位,其中 1 為符號位,接下來,8 位階碼,最后,23 位尾碼

任何一個浮點數(除 0 以外),都可以表示為:

V = (-1)^s * M * 2^E

  • 當 (-1)^s 為 1 時,表示正數,為 -1 時,表示負數,在計算機內存儲時,0 表示正數,1 表示負數
  • M 表示尾碼,范圍為 [1, 2),可以寫成 1.xxxxx 的形式,由于, 1 肯定存在,所以,在計算機內只存儲小數部分
  • E 表示階碼,階碼可正可負,在計算機內存儲時,會將實際的階碼加一個偏移量存儲,對于 32 為 float,偏移量為 127
  • 接下來分析這個數:

    123456.789e5

    = 12345678900

    = 8589934592 + 2147483648 + 1073741824 + 268435456 + 134217728 + 67108864 + 33554432 + 16777216 + 8388608 + 4194304 + 1048576 + 524288 + 262144 + 4096 + 2048 + 1024 + 32 + 16 + 4

    = 2^33 + 2^31 + 2^30 +2^28 + 2^27 + 2^26 + 2^25+2^24+2^23 + 2^22 + 2^20 + 2^19 + 2^18 + 2^12+2^11 + 2^10 + 2^5 + 2^4 + 2^2

    = 10 1101 1111 1101 1100 0001 1100 0011 0100(二進制)

    = 1.0 1101 1111 1101 1100 0001 1100 0011 0100 * 2^33 (二進制)

    此數大于 0,所以符號位部分存儲為 0

    此數,階碼為33,偏移量為 127,33 + 127 = 160 = 1010 0000,

    階碼部分存儲為 1010 0000

    如上所述,對于 1.0 1101 1111 1101 1100 0001 1100 0011 0100,最前面的 1 不存儲,只存儲小數位,由于,尾碼只有 23 為,而 1.0 1101 1111 1101 1100 0001 1100 0011 0100,小數部分有 33 位,所以只能忽略點最后 10 位,即,尾碼部分為 011 0111 1111 0111 0000 0111(此處損失了精度)

    最后此數在計算機內表示為:0101 0000 0011 0111 1111 0111 0000 0111

    將其轉化為浮點數為:12345678848.000000,所以,float 類型的 123456.789e5 在計算機內表示為:12345678848.000000

    接下來,在考慮 a + 20,int 和 float 相加,int 將先轉換為 float

    所以,20 = 2^4 + 2^2 = 1.01 * 2 ^ 4,即:

    符號位表示為:0

    階碼為 4,加上偏移量 127,4 + 127 = 131 = 1000 0011,階碼部分存儲為 1000 0011

    尾碼,對于 1.01 不存儲最前面的 1,階碼共 23 位 ,而小數部分只有兩位,不足用 0 填,所以,尾碼,存儲為:010 0000 0000 0000 0000 0000

    所以 float 類型的 20,存儲為 0100 0001 1010 0000 0000 0000 0000 0000

    現在,再考慮兩數相加,

    0101 0000 0011 0111 1111 0111 0000 0111(123456.789e5)

    0100 0001 1010 0000 0000 0000 0000 0000(20)

    首先,進行,階碼對齊,123456.789e5 的階碼為:1010 0000(160),20 的階碼為 1000 0011(130),

    小階碼向大階碼對齊,所以,將 0100 0001 1010 0000 0000 0000 0000 0000(20)的階碼轉化為 1010 0000 (160),將尾碼(包括未存儲的 1)向右移 30 位,空位用 0 填充, 即轉換為 0101 0000 0(0)000 0000 0000 0000 0000 0000(此處有精度損失)

    現在:

    0101 0000 0(1)011 0111 1111 0111 0000 0111(123456.789e5)

    0101 0000 0(0)000 0000 0000 0000 0000 0000(20)

    接下來,階碼不變,由于兩數都是正數,所以尾碼相加(需要加上尾碼未存儲的1),尾碼部分結果為:(1)011 0111 1111 0111 0000 0111

    然后,進行格式化,這個例子不需要格式化,(此步可能損失精度)

    所以,加上符號位和階碼,最終結果為:

    0101 0000 0011 0111 1111 0111 0000 0111(12345678848.000000)

    結論:浮點數,進行存儲或運算時,可能會有精度損失

    此外,還有幾個特殊的浮點數:

  • 符號位,指數部分,尾數部分都為 0,表示 0.0
  • 0000 0000 0000 0000 0000 0000 0000 0000

    2. 符號位為 1,指數部分,尾數部分都為 0,表示 -0.0

    1000 0000 0000 0000 0000 0000 0000 0000

    3. 符號位為 0,指數部分都為 1,尾數部分都為 0,表示正無窮大

    0111 1111 1000 0000 0000 0000 0000 0000

    4. 符號位為 1,指數部分都為 1,尾數部分都為 0,表示負無窮大

    1111 1111 1000 0000 0000 0000 0000 0000

    5. 符號位無所謂,指數部分都為 1,尾數部分為非 0,表示不是一個數字,是 NaN

    *111 1111 1 + 非0

    總結

    以上是生活随笔為你收集整理的3 float py 位小数 裁剪_对一个 float 精度问题的分析的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。