自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

面試官瘋了嗎,問我為什么浮點(diǎn)數(shù)不精確?

開發(fā) 開發(fā)工具
很多人都知道,Java 中的浮點(diǎn)數(shù)并不精確,需要用 BigDecimal進(jìn)行精確計(jì)算,但是,很少有人知道為什么浮點(diǎn)數(shù)不精確呢?不精確為什么還要用呢?本文就來(lái)展開分析一波。

[[434999]]

很多人都知道,Java 中的浮點(diǎn)數(shù)并不精確,需要用 BigDecimal進(jìn)行精確計(jì)算,但是,很少有人知道為什么浮點(diǎn)數(shù)不精確呢?不精確為什么還要用呢?本文就來(lái)展開分析一波。

我們知道,計(jì)算機(jī)的數(shù)字的存儲(chǔ)和運(yùn)算都是通過二進(jìn)制進(jìn)行的,對(duì)于,十進(jìn)制整數(shù)轉(zhuǎn)換為二進(jìn)制整數(shù)采用"除2取余,逆序排列法。

具體做法是:

  • 用2整除十進(jìn)制整數(shù),可以得到一個(gè)商和余數(shù);
  • 再用2去除商,又會(huì)得到一個(gè)商和余數(shù),如此進(jìn)行,直到商為小于1時(shí)為止
  • 然后把先得到的余數(shù)作為二進(jìn)制數(shù)的低位有效位,后得到的余數(shù)作為二進(jìn)制數(shù)的高位有效位,依次排列起來(lái)。

如,我們想要把127轉(zhuǎn)換成二進(jìn)制,做法如下:

那么,十進(jìn)制小數(shù)轉(zhuǎn)換成二進(jìn)制小數(shù),又該如何計(jì)算呢?

十進(jìn)制小數(shù)轉(zhuǎn)換成二進(jìn)制小數(shù)采用"乘2取整,順序排列"法。

具體做法是:

  • 用2乘十進(jìn)制小數(shù),可以得到積
  • 將積的整數(shù)部分取出,再用2乘余下的小數(shù)部分,又得到一個(gè)積
  • 再將積的整數(shù)部分取出,如此進(jìn)行,直到積中的小數(shù)部分為零,此時(shí)0或1為二進(jìn)制的最后一位?;蛘哌_(dá)到所要求的精度為止。

如嘗試將0.625轉(zhuǎn)成二進(jìn)制:

但是0.625是一個(gè)特列,用同樣的算法,請(qǐng)計(jì)算下0.1對(duì)應(yīng)的二進(jìn)制是多少:

我們發(fā)現(xiàn),0.1的二進(jìn)制表示中出現(xiàn)了無(wú)限循環(huán)的情況,也就是(0.1)10 = (0.000110011001100…)2

這種情況,計(jì)算機(jī)就沒辦法用二進(jìn)制精確的表示0.1了。

所以,為了解決部分小數(shù)無(wú)法使用二進(jìn)制精確表示的問題,于是就有了IEEE 754規(guī)范。

IEEE二進(jìn)制浮點(diǎn)數(shù)算術(shù)標(biāo)準(zhǔn)(IEEE 754)是20世紀(jì)80年代以來(lái)最廣泛使用的浮點(diǎn)數(shù)運(yùn)算標(biāo)準(zhǔn),為許多CPU與浮點(diǎn)運(yùn)算器所采用。

浮點(diǎn)數(shù)和小數(shù)并不是完全一樣的,計(jì)算機(jī)中小數(shù)的表示法,其實(shí)有定點(diǎn)和浮點(diǎn)兩種。因?yàn)樵谖粩?shù)相同的情況下,定點(diǎn)數(shù)的表示范圍要比浮點(diǎn)數(shù)小。所以在計(jì)算機(jī)科學(xué)中,使用浮點(diǎn)數(shù)來(lái)表示實(shí)數(shù)的近似值。

IEEE 754規(guī)定了四種表示浮點(diǎn)數(shù)值的方式:?jiǎn)尉_度(32位)、雙精確度(64位)、延伸單精確度(43比特以上,很少使用)與延伸雙精確度(79比特以上,通常以80位實(shí)現(xiàn))。

其中最常用的就是32位單精度浮點(diǎn)數(shù)和64位雙精度浮點(diǎn)數(shù)。

單精度浮點(diǎn)數(shù)在計(jì)算機(jī)存儲(chǔ)器中占用4個(gè)字節(jié)(32 bits),利用“浮點(diǎn)”(浮動(dòng)小數(shù)點(diǎn))的方法,可以表示一個(gè)范圍很大的數(shù)值。

比起單精度浮點(diǎn)數(shù),雙精度浮點(diǎn)數(shù)(double)使用 64 位(8字節(jié)) 來(lái)存儲(chǔ)一個(gè)浮點(diǎn)數(shù)。

IEEE并沒有解決小數(shù)無(wú)法精確表示的問題,只是提出了一種使用近似值表示小數(shù)的方式,并且引入了精度的概念。

一個(gè)浮點(diǎn)數(shù)a由兩個(gè)數(shù)m和e來(lái)表示:a = m × b^e。

在任意一個(gè)這樣的系統(tǒng)中,我們選擇一個(gè)基數(shù)b(記數(shù)系統(tǒng)的基)和精度p(即使用多少位來(lái)存儲(chǔ))。m(即尾數(shù))是形如±d.ddd…ddd的p位數(shù)(每一位是一個(gè)介于0到b-1之間的整數(shù),包括0和b-1)。

如果m的第一位是非0整數(shù),m稱作規(guī)格化的。有一些描述使用一個(gè)單獨(dú)的符號(hào)位(s 代表+或者-)來(lái)表示正負(fù),這樣m必須是正的。e是指數(shù)。

最后,由于計(jì)算機(jī)中保存的小數(shù)其實(shí)是十進(jìn)制的小數(shù)的近似值,并不是準(zhǔn)確值,所以,千萬(wàn)不要在代碼中使用浮點(diǎn)數(shù)來(lái)表示金額等重要的指標(biāo)。 

建議使用BigDecimal或者Long(單位為分)來(lái)表示金額。

 

責(zé)任編輯:武曉燕 來(lái)源: 51CTO專欄
相關(guān)推薦

2021-12-02 08:19:06

MVCC面試數(shù)據(jù)庫(kù)

2021-06-03 08:55:54

分布式事務(wù)ACID

2020-09-15 12:57:46

C 語(yǔ)言浮點(diǎn)數(shù)內(nèi)存

2022-07-19 07:02:47

JVMGC分代收集

2022-07-06 13:48:24

RedisSentinel機(jī)制

2023-07-05 08:00:58

Redis數(shù)據(jù)庫(kù)

2023-12-06 09:10:28

JWT微服務(wù)

2021-05-20 08:54:16

Go面向對(duì)象

2020-04-16 08:22:11

HTTPS加解密協(xié)議

2010-08-23 15:06:52

發(fā)問

2022-05-24 08:03:28

InnoDBMySQL數(shù)據(jù)

2020-10-24 15:50:54

Java值傳遞代碼

2021-02-19 10:02:57

HTTPSJava安全

2021-01-21 07:53:29

面試官Promis打印e

2021-10-25 08:49:32

索引數(shù)據(jù)庫(kù)MySQL

2017-10-16 10:42:27

前端JavaScript浮點(diǎn)數(shù)

2020-06-22 11:50:38

TCPIP協(xié)議

2021-12-20 10:30:33

forforEach前端

2023-12-20 14:35:37

Java虛擬線程

2023-06-20 12:02:39

WhileFor(;;)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)