精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

為什么 0.1 + 0.2 = 0.30000000000000004?

開發
我有點懷疑是否有人能耐心完成以上所有些算術,但它寫出來對我很有幫助,所以我還是發表了這篇文章,希望它能有所幫助。

嗨!昨天我試著寫點關于浮點數的東西,我發現自己對這個 64 位浮點數的計算方法很好奇:

>>> 0.1 + 0.2
0.30000000000000004

我意識到我并沒有完全理解它是如何計算的。我的意思是,我知道浮點計算是不精確的,你不能精確地用二進制表示 0.1,但是:肯定有一個浮點數比 0.30000000000000004 更接近 0.3!那為什么答案是 0.30000000000000004 呢?

如果你不想閱讀一大堆計算過程,那么簡短的答案是: 0.1000000000000000055511151231257827021181583404541015625 + 0.200000000000000011102230246251565404236316680908203125 正好位于兩個浮點數之間,即 0.299999999999999988897769753748434595763683319091796875 (通常打印為 0.3) 和 0.3000000000000000444089209850062616169452667236328125(通常打印為 0.30000000000000004)。答案是 0.30000000000000004,因為它的尾數是偶數。

浮點加法是如何計算的

以下是浮點加法的簡要計算原理:

  • 把它們精確的數字加在一起
  • 將結果四舍五入到最接近的浮點數

讓我們用這些規則來計算 0.1 + 0.2。我昨天才剛了解浮點加法的計算原理,所以在這篇文章中我可能犯了一些錯誤,但最終我得到了期望的答案。

第一步:0.1 和 0.2 到底是多少

首先,讓我們用 Python 計算 0.1 和 0.2 的 64 位浮點值。

>>> f"{0.1:.80f}"
'0.10000000000000000555111512312578270211815834045410156250000000000000000000000000'
>>> f"{0.2:.80f}"
'0.20000000000000001110223024625156540423631668090820312500000000000000000000000000'

這確實很精確:因為浮點數是二進制的,你也可以使用十進制來精確的表示。但有時你只是需要一大堆數字:)

第二步:相加

接下來,把它們加起來。我們可以將小數部分作為整數加起來得到確切的答案:

>>> 1000000000000000055511151231257827021181583404541015625 + 2000000000000000111022302462515654042363166809082031250
3000000000000000166533453693773481063544750213623046875

所以這兩個浮點數的和是 0.3000000000000000166533453693773481063544750213623046875

但這并不是最終答案,因為它不是一個 64 位浮點數。

第三步:查找最接近的浮點數

現在,讓我們看看接近 0.3 的浮點數。下面是最接近 0.3 的浮點數(它通常寫為 0.3,盡管它不是確切值):

>>> f"{0.3:.80f}"
'0.29999999999999998889776975374843459576368331909179687500000000000000000000000000'

我們可以通過 struct.pack 將 0.3 序列化為 8 字節來計算出它之后的下一個浮點數,加上 1,然后使用 struct.unpack

>>> struct.pack("!d", 0.3)
b'?\xd3333333'
# 手動加 1
>>> next_float = struct.unpack("!d", b'?\xd3333334')[0]
>>> next_float
0.30000000000000004
>>> f"{next_float:.80f}"
'0.30000000000000004440892098500626161694526672363281250000000000000000000000000000'

當然,你也可以用 math.nextafter

>>> math.nextafter(0.3, math.inf)
0.30000000000000004

所以 0.3 附近的兩個 64 位浮點數是 0.299999999999999988897769753748434595763683319091796875 和 0.3000000000000000444089209850062616169452667236328125

第四步:找出哪一個最接近

結果證明 0.3000000000000000166533453693773481063544750213623046875 正好在 0.299999999999999988897769753748434595763683319091796875 和 0.3000000000000000444089209850062616169452667236328125 的中間。

你可以通過以下計算看到:

>>> (3000000000000000444089209850062616169452667236328125000 + 2999999999999999888977697537484345957636833190917968750) // 2 == 3000000000000000166533453693773481063544750213623046875
True

所以它們都不是最接近的。

如何知道四舍五入到哪一個?

在浮點數的二進制表示中,有一個數字稱為“尾數”。這種情況下(結果正好在兩個連續的浮點數之間),它將四舍五入到偶數尾數的那個。

在本例中為 0.300000000000000044408920985006261616945266723632812500

我們之前就見到了這個數字的尾數:

  • 0.30000000000000004 是 struct.unpack('!d', b'?\xd3333334') 的結果
  • 0.3 是 struct.unpack('!d', b'?\xd3333333') 的結果

0.30000000000000004 的大端十六進制表示的最后一位數字是 4,它的尾數是偶數(因為尾數在末尾)。

我們用二進制來算一下

之前我們都是使用十進制來計算的,這樣讀起來更直觀。但是計算機并不會使用十進制,而是用 2 進制,所以我想知道它是如何計算的。

我不認為本文的二進制計算部分特別清晰,但它寫出來對我很有幫助。有很多數字,讀起來可能很糟糕。

64 位浮點數如何計算:指數和尾數

64 位浮點數由 2 部分整數構成:指數尾數,還有 1 比特 符號位.

以下是指數和尾數對應于實際數字的方程:

例如,如果指數是 1,尾數是 2**51,符號位是正的,那么就可以得到:

它等于 2 * (1 + 0.5),即 3。

步驟 1:獲取 0.1 和 0.2 的指數和尾數

我用 Python 編寫了一些(to 校正:這里原文加了一個 inefficient 形容詞,不知道如何翻譯)函數來獲取正浮點數的指數和尾數:

def get_exponent(f):
    # 獲取前 52 個字節
    bytestring = struct.pack('!d', f)
    return int.from_bytes(bytestring, byteorder='big') >> 52
def get_significand(f):
    # 獲取后 52 個字節
    bytestring = struct.pack('!d', f)
    x = int.from_bytes(bytestring, byteorder='big')
    exponent = get_exponent(f)
    return x ^ (exponent << 52)

我忽略了符號位(第一位),因為我們只需要處理 0.1 和 0.2,它們都是正數。

首先,讓我們獲取 0.1 的指數和尾數。我們需要減去 1023 來得到實際的指數,因為浮點運算就是這么計算的。

>>> get_exponent(0.1) - 1023
-4
>>> get_significand(0.1)
2702159776422298

它們根據 2**指數 + 尾數 / 2**(52 - 指數) 這個公式得到 0.1

下面是 Python 中的計算:

>>> 2**-4 + 2702159776422298 / 2**(52 + 4)
0.1

(你可能會擔心這種計算的浮點精度問題,但在本例中,我很確定它沒問題。因為根據定義,這些數字沒有精度問題 -- 從 2**-4 開始的浮點數以 1/2**(52 + 4) 步長遞增。)

0.2 也一樣:

>>> get_exponent(0.2) - 1023
-3
>>> get_significand(0.2)
2702159776422298

它們共同工作得到 0.2:

>>> 2**-3 + 2702159776422298 / 2**(52 + 3)
0.2

(順便說一下,0.1 和 0.2 具有相同的尾數并不是巧合 —— 因為 x 和 2*x 總是有相同的尾數。)

步驟 2:重新計算 0.1 以獲得更大的指數

0.2 的指數比 0.1 大 -- -3 大于 -4。

所以我們需要重新計算:

2**-4 + 2702159776422298 / 2**(52 + 4)

等于 X / (2**52 + 3)

如果我們解出 2**-4 + 2702159776422298 / 2**(52 + 4) = X / (2**52 + 3),我們能得到:

X = 2**51 + 2702159776422298 /2

在 Python 中,我們很容易得到:

>>> 2**51 + 2702159776422298 //2
3602879701896397

步驟 3:添加符號位

現在我們試著做加法:

2**-3 + 2702159776422298 / 2**(52 + 3) + 3602879701896397 / 2**(52 + 3)

我們需要將 2702159776422298 和 3602879701896397 相加:

>>> 2702159776422298  + 3602879701896397
6305039478318695

棒。但是 6305039478318695 比 2**52-1(尾數的最大值)大,問題來了:

>>> 6305039478318695 > 2**52
True

步驟 4:增加指數

目前結果是:

2**-3 + 6305039478318695 / 2**(52 + 3)

首先,它減去 2**52:

2**-2 + 1801439850948199 / 2**(52 + 3)

完美,但最后的 2**(52 + 3) 需要改為 2**(52 + 2)

我們需要將 1801439850948199 除以 2。這就是難題的地方 -- 1801439850948199 是一個奇數!

>>> 1801439850948199  / 2
900719925474099.5

它正好在兩個整數之間,所以我們四舍五入到最接近它的偶數(這是浮點運算規范要求的),所以最終的浮點結果是:

>>> 2**-2 + 900719925474100 / 2**(52 + 2)
0.30000000000000004

它就是我們預期的結果:

>>> 0.1 + 0.2
0.30000000000000004

在硬件中它可能并不是這樣工作的

在硬件中做浮點數加法,以上操作方式可能并不完全一模一樣(例如,它并不是求解 “X”),我相信有很多有效的技巧,但我認為思想是類似的。

打印浮點數是非常奇怪的

我們之前說過,浮點數 0.3 不等于 0.3。它實際上是:

>>> f"{0.3:.80f}"
'0.29999999999999998889776975374843459576368331909179687500000000000000000000000000'

但是當你打印它時,為什么會顯示 0.3

計算機實際上并沒有打印出數字的精確值,而是打印出了最短的十進制數 d,其中 f 是最接近 d 的浮點數。

事實證明,有效做到這一點很不簡單,有很多關于它的學術論文,比如 快速且準確地打印浮點數如何準確打印浮點數 等。

如果計算機打印出浮點數的精確值,會不會更直觀一些?

四舍五入到一個干凈的十進制值很好,但在某種程度上,我覺得如果計算機只打印一個浮點數的精確值可能會更直觀 -- 當你得到一個奇怪的結果時,它可能會讓你看起來不那么驚訝。

對我來說,0.1000000000000000055511151231257827021181583404541015625 + 0.200000000000000011102230246251565404236316680908203125 = 0.3000000000000000444089209850062616169452667236328125 比 0.1 + 0.2 = 0.30000000000000000004 驚訝少一點。

這也許是一個壞主意,因為它肯定會占用大量的屏幕空間。

PHP 快速說明

有人在評論中指出在 PHP 中 <?php echo (0.1 + 0.2 );?> 會輸出 0.3,這是否說明在 PHP 中浮點運算不一樣?

非也 —— 我在 這里 運行:

<?php echo (0.1 + 0.2 )- 0.3);?>,得到了與 Python 完全相同的答案:5.5511151231258E-17。因此,浮點運算的基本原理是一樣的。

我認為在 PHP 中 0.1 + 0.2 輸出 0.3 的原因是 PHP 顯示浮點數的算法沒有 Python 精確 —— 即使這個數字不是最接近 0.3 的浮點數,它也會顯示 0.3

總結

我有點懷疑是否有人能耐心完成以上所有些算術,但它寫出來對我很有幫助,所以我還是發表了這篇文章,希望它能有所幫助。

責任編輯:龐桂玉 來源: Linux中國
相關推薦

2020-10-12 13:27:21

計算機瀏覽器電腦

2019-10-21 11:20:12

編程小程序開發

2023-11-08 13:32:00

JavaScript浮點數計算

2025-06-04 03:25:00

Java浮點數數學缺陷

2024-08-23 08:43:08

2021-10-29 22:49:57

JavaScript開發精度

2022-07-14 14:27:34

Javascript數字精度二進制

2024-04-03 09:23:31

ES索引分析器

2017-02-16 07:37:19

前端程序軟件

2011-11-28 10:21:52

Nginx特性

2020-05-29 09:49:43

騰訊

2011-02-16 09:42:04

DevOps

2012-09-26 10:02:44

框架開發項目

2021-01-20 08:36:15

工具AtomicRefer JDK

2020-04-07 13:40:13

GraphQLAPI編程語言

2019-05-24 13:47:45

出海以色列

2020-09-25 08:10:55

Rust系統編程

2018-04-10 13:40:14

Kubernetes容器服務器

2023-03-21 08:02:36

Redis6.0IO多線程

2023-06-06 09:03:06

InnodbMySQL
點贊
收藏

51CTO技術棧公眾號

亚洲国产免费看| 黄色免费网址大全| 性高潮免费视频| 人妻偷人精品一区二区三区| 欧美日韩一二| 欧美日韩免费看| 欧美成人免费大片| 黄色aaa级片| 久久综合之合合综合久久| 最新精品国偷自产在线| 午夜亚洲福利老司机| 91最新国产视频| 污污视频网站在线免费观看| 亚洲最大网站| 99久久国产综合色|国产精品| 久久久精品一区| 欧美美女一级片| 国际av在线| 久久精品官网| 亚洲欧洲视频在线| 国产日产欧美视频| 人妻妺妺窝人体色www聚色窝| 丝袜亚洲另类欧美综合| 亚洲免费电影在线观看| 亚洲 高清 成人 动漫| 亚洲欧美激情国产综合久久久| 91精品成人| 5858s免费视频成人| 亚洲国产一区在线| 91亚洲精品国偷拍自产在线观看| 日韩av在线播放网址| 欧美色老头old∨ideo| 欧美一区三区二区在线观看| 黄色片视频免费| 精品国产乱码久久久久久1区2匹| 欧美一区二区国产| 日本福利视频网站| 成人午夜福利视频| 久久99精品久久久| 欧美成人第一页| 美女被到爽高潮视频| 91p九色成人| ...xxx性欧美| 51国产成人精品午夜福中文下载 | 中文在线8资源库| av午夜精品一区二区三区| 97成人精品区在线播放| 亚洲国产无码精品| 国产一区精品福利| 综合中文字幕亚洲| 日韩性感在线| 国产jzjzjz丝袜老师水多| 国模大胆一区二区三区| 亚洲精品suv精品一区二区| 日本一本二本在线观看| www免费网站在线观看| 久久99久久久欧美国产| 国产www精品| 国产美女高潮视频| 超碰一区二区三区| 色视频一区二区| 伊人久久婷婷色综合98网| 丰满人妻一区二区三区无码av| 九九视频精品免费| 成人av在线亚洲| 日韩欧美视频在线免费观看| 成人6969www免费视频| 日韩视频免费直播| 成人在线看视频| 成年人在线观看| 国产片一区二区三区| 99久久99久久精品国产片| 久久亚洲精品石原莉奈| 久久久久久久欧美精品| 91av在线免费观看视频| 亚洲免费黄色网址| 中文字幕一区二区av| 亚洲欧美中文字幕在线一区| 国产中年熟女高潮大集合| 国产亚洲第一伦理第一区| 日韩美女一区二区三区四区| 国产无套粉嫩白浆内谢的出处| av片在线观看永久免费| 国产亚洲一区字幕| 97久草视频| 成人激情四射网| 蜜臀av性久久久久蜜臀aⅴ四虎| 欧美激情小视频| 可以免费看av的网址| 亚洲欧美偷拍自拍| 97激碰免费视频| 国产女人被狂躁到高潮小说| 九九热爱视频精品视频| 亚洲人成五月天| 日本黄色录像视频| 亚洲黄色视屏| 国产精品丝袜久久久久久高清 | 日产精品久久久一区二区福利| 一区二区国产精品精华液| 亚洲动漫精品| 精品99999| 色偷偷中文字幕| 欧美日韩在线精品一区二区三区激情综合 | 免费人成在线观看网站| 成人v精品蜜桃久久一区| 成人a免费视频| 蜜臀av中文字幕| 日本一区二区三区免费乱视频| 91精品国产毛片武则天| 麻豆传媒在线观看| 亚洲国产精品av| 欧美下载看逼逼| 亚洲日本国产精品| 91丨九色丨蝌蚪富婆spa| 国产高清在线一区| 亚洲乱色熟女一区二区三区| 国产一区二区美女诱惑| 成人疯狂猛交xxx| 日韩在线观看视频一区| 中文字幕一区二区三| 亚洲永久激情精品| 免费在线看a| 精品久久在线播放| 精品久久一二三| 国产传媒在线| 亚洲国产视频网站| xxxx18hd亚洲hd捆绑| 9999在线视频| 岛国av一区二区三区| 欧洲美女亚洲激情| 91午夜精品| 日日摸夜夜添一区| 少妇高潮惨叫久久久久| 99久久久久国产精品| 久久国产精品偷| 亚洲永久精品一区| 久久99热99| 日本一区美女| 理论不卡电影大全神| 色综合久久99| 国产一二三区av| 日日狠狠久久| 精品久久久网站| 国产偷人妻精品一区| 精品福利久久久| 2019中文字幕免费视频| 青青视频在线免费观看| 成人国产精品视频| 777久久精品一区二区三区无码| 你懂得影院夜精品a| 欧美日韩国产高清一区二区三区 | 激情综合色综合久久| 亚洲综合成人婷婷小说| 免费看a在线观看| 欧美男人的天堂一二区| www.日本久久| 久久国产亚洲| 国产综合香蕉五月婷在线| 国产农村老头老太视频| av中文字幕不卡| 97超碰在线人人| 日本精品网站| 在线观看国产成人av片| 国产一级理论片| 裸体一区二区| 日本不卡一区二区三区在线观看| 伊人久久视频| 亚洲偷欧美偷国内偷| 国产一区二区播放| 久久国产88| 欧美二区三区在线| 97成人超碰| 俺也去精品视频在线观看| 国产午夜福利精品| 99在线视频精品| 97av视频在线观看| 精品国产美女| 国产一区红桃视频| 日本在线视频网址| 欧美日韩在线亚洲一区蜜芽| 国产又粗又长又硬| 国产乱码精品一品二品| 欧美性xxxx69| 五月天色综合| 欧美精品成人在线| 飘雪影院手机免费高清版在线观看| 亚洲丝袜另类动漫二区| 国产97色在线 | 日韩| 日韩av密桃| 国产精品v欧美精品v日韩| 久久uomeier| 久久精品成人动漫| 日韩中文字幕免费观看| 91九色最新地址| 国产女人被狂躁到高潮小说| 久久久亚洲综合| 97超碰国产精品| 亚洲成a人片777777久久| 九九久久综合网站| 国产免费不卡av| 午夜精品福利一区二区蜜股av| 国产亚洲精品熟女国产成人| 国产乱色国产精品免费视频| 国模吧无码一区二区三区| 国产精品专区一| 亚洲国产综合av| 日韩一级免费| 免费成人在线视频观看| 精品欧美日韩| av官网在线播放| 亚洲国产天堂久久综合网| 亚洲性猛交富婆| 久久亚洲精品国产精品紫薇| a级免费在线观看| 红桃成人av在线播放| 99re国产在线播放| 欧洲成人一区| 亚洲精品影视在线观看| 一本一道久久a久久精品综合| 91成人福利社区| 亚洲香蕉伊综合在人在线视看| 国产美女裸体无遮挡免费视频| 欧美日韩中文字幕| 黄色性视频网站| 1024精品一区二区三区| 亚洲免费在线精品一区| 天天躁日日躁aaaa视频| 国产福利不卡视频| 福利网在线观看| www 久久久| 欧美中文在线视频| 日av在线播放| 欧美刺激脚交jootjob| 在线播放一级片| 国产精品久久久久久久第一福利| 久久免费精品国产| 国内精品视频一区二区三区八戒| 日韩av在线综合| 一区二区视频欧美| 国产综合av一区二区三区| 国产传媒在线| 色综合久久久久久中文网| 暖暖日本在线观看| 中文在线资源观看视频网站免费不卡| 成人黄色免费网| 色哟哟国产精品免费观看| 日韩av在线播| 久久精品欧美一区二区三区麻豆| 性xxxxxxxxx| 夜夜嗨一区二区三区| 激情六月天婷婷| 欧美激情视频一区二区三区免费| 韩日午夜在线资源一区二区| 99久热这里只有精品视频免费观看| 成人中文字幕在线观看| av资源一区| 欧美激情手机在线视频| 美女精品视频| 夜夜嗨av色综合久久久综合网| 四虎在线免费观看| 欧美日本在线播放| 亚洲视频在线观看免费视频| 欧美亚洲高清一区| 538任你躁在线精品视频网站| 国产精品成人免费在线| 日韩在线不卡av| 亚洲欧美日韩久久精品| 99热精品免费| 亚洲一卡二卡三卡四卡无卡久久| 日韩精品无码一区二区三区久久久 | 豆国产96在线|亚洲| 2022亚洲天堂| 久久久久国产一区二区| 午夜在线观看av| 国内精品国产成人国产三级| 成人动漫一区二区三区| 韩国三级视频在线观看| 99久久久久免费精品国产| 欧美一级片黄色| 欧美网站在线| 视频一区免费观看| 国内精品偷拍| 成人免费观看a| 久久精品九色| 国产精品高精视频免费| 电影在线观看一区| 国产97在线视频| 日本一区二区中文字幕| 产国精品偷在线| 亚洲丁香日韩| 中文字幕欧美日韩一区二区三区 | 视频在线一区二区三区| 性欧美69xoxoxoxo| 欧美二区在线视频| 精品在线视频一区| 特级西西人体wwwww| 国产精品久久久久aaaa| 日本一级黄色大片| 欧美人牲a欧美精品| 手机av在线免费观看| 国产亚洲精品精华液| 国产二级片在线观看| 久久综合导航| 亚洲欧美天堂在线| 欧美午夜精品| 天天摸天天碰天天添| 国产一区二区在线看| 三叶草欧洲码在线| 亚洲欧洲色图综合| 亚洲日本视频在线观看| 欧美一级在线免费| 激情小说 在线视频| 欧美黄色三级网站| 日本在线视频www鲁啊鲁| 国产不卡视频在线| 91夜夜蜜桃臀一区二区三区| 婷婷久久青草热一区二区| 亚洲黄色av| 亚洲国产综合av| 欧美激情在线观看视频免费| 国产乡下妇女做爰视频| 欧美精品在线观看播放| 好吊色在线观看| 久久久国产一区二区| 成人不卡视频| 欧美日本亚洲| 99在线热播精品免费99热| 亚洲一区二区中文字幕在线观看| 久久久久成人黄色影片| 日韩三级免费看| 日韩欧美的一区| 国产美女av在线| 亚洲精品小视频| 在线观看免费网站黄| 精品国产91洋老外米糕| av福利精品| 浅井舞香一区二区| 9l视频自拍蝌蚪9l视频成人| 99亚洲精品视频| 久久精品国产精品亚洲精品| 九九久久久久久| 久久久久99精品国产片| 7777在线视频| 神马影视一区二区| 国产高清www| 国产精品一区二区男女羞羞无遮挡 | 手机免费观看av| 91国产成人在线| 黄色美女网站在线观看| 日韩美女免费视频| 国产精品一区2区3区| caopor在线视频| 国产蜜臀av在线一区二区三区| 久久影视中文字幕| 亚洲欧美999| 97成人超碰| 午夜啪啪免费视频| 国产乱理伦片在线观看夜一区| 久久久久久久久久网站| 精品伦理精品一区| 91超碰免费在线| 久久久免费看| 91成人网在线观看| 日本r级电影在线观看| 伊人一区二区三区| 天天干,天天干| 国产一区二区三区在线看 | 好看的日韩av电影| 欧美xxxx日本和非洲| 午夜av一区二区| 狠狠狠综合7777久夜色撩人| 国产精品一区久久久| 中文不卡在线| 亚洲一区二区在线免费| 一本一道久久a久久精品| 国产高清一区在线观看| 欧美精品videofree1080p| 国产成人tv| 亚洲爆乳无码专区| 国产精品九色蝌蚪自拍| 国产xxxx孕妇| 欧美亚洲成人精品| 日韩综合网站| 久久久久久久久久影视| 一本一本久久a久久精品综合麻豆| 8888四色奇米在线观看| 99热在线播放| 日韩精品乱码免费| 18禁裸乳无遮挡啪啪无码免费| 欧美伊人精品成人久久综合97| 国产成人在线视频免费观看| 国产精品丝袜久久久久久不卡| 91精品啪在线观看国产18| 毛茸茸free性熟hd| 欧美日韩一区二区在线视频| 日本精品600av| 欧美国产一二三区| 国产麻豆91精品| 亚洲天堂一区在线| 日韩视频免费直播|