Python为什么要四舍五入呢?

时间:2019-12-13 17:43:21

标签: python numpy floating-point precision ieee-754

我正在使用IEEE 754定义的64位浮点运算。最小的次正规数是:
2^-1074 = 5e-324 = 5 * 10^-16 * 10^-308

将后者添加到realmin结果为:
2^-1022 + 2^-1074 = 2.2250738585072014 * 10^-308 + 5 * 10^-16 * 10^-308 = (2.2250738585072014 + 0.0000000000000005) * 10^-308 = 2.2250738585072019 * 10^-308

在Python中执行加法时,结果略有不同。这是简单的脚本:

import numpy as np

realmin = np.power(2.0, -1022)
print( "realmin\t\t" + str(realmin) )

smallestSub = np.power(2.0, -1074)
print( "smallest sub\t" + str(smallestSub) )

realminSucc = realmin + smallestSub
print( "sum\t\t" + str(realminSucc) )

输出为:

realmin         2.2250738585072014e-308
smallest sub    5e-324
sum             2.225073858507202e-308

为什么要四舍五入?如realmin输出所示,还有多余的一位数字。

1 个答案:

答案 0 :(得分:0)

Python对浮点行为并不严格,因此以下某些内容是推测性的-它取决于实现。

Java和JavaScript要求将浮点值默认转换为字符串,以仅使用足够的十进制数字来唯一区分浮点值。例如,如果某些浮点格式的可表示值是3、3.0625、3.125、3.1875,依此类推,则将3.0625转换为字符串会产生“ 3.06”,因为这将其与3和3.125唯一地区分开来。之所以这么长,是因为较短的“ 3.1”无法将其与3.125区别开来。但是将3.125转换为字符串会产生“ 3.1”,因为这已经足够了;将3.1转换为最接近的可表示值将得出3.125。

由于Java和JavaScript要求这样做,所以进行这些转换的子例程变得很常见,并且Python实现很容易使用它们。此行为将解释您在Python实现中看到的结果。

尽管问题指出“ 2 ^ -1074 = 5e-24”,但事实并非如此。 2 -1074 正是4.940656458412465441765687928682213723650598026143247644255856825006755072702087518652998363616359923797965646954457177309266567103559397963987747960107818781263007131903114045278458171678489821036887186360569987307230500063874091535649843873124733972731696151400317153853980741262385655911710266585566867681870395603106249319452715914924553293054565444011274801297099995419319894090804165633245247571478690147267801593552386115501348035264934720193790268107107491703332226844753335720832431936092382893458368060106011506169809753078342277318329247904982524730776375927247874656084778203734469699533647017972677717585125660551199131504891101451037862738167250955837389733598993664809941164205702637090279242767544565229087538682506419718265533447265625•10 -324 。浮点数的确切值在格式中很重要。在2 −1022 附近,可表示的值为:

  • 2 -1022 - 2 -1074 = 2.2250738585072008 890245868760858598876504231122409594654935248025624400092282356951787758888037591552642309780950434312085877387158357291821993020294379224223559819827501242041788969571311791082261043971979604000454897391938079198936081525613113376149842043271751033627391549782731594143828136275113838604094249464942286316695429105080201815926642134996606517803095075913058719846423906068637102005108723282784678843631944515866135041223479014792369585208321597621066375401613736583044193603714778355306682834535634005074073040135602968046375918583163124224521599262546494300836851861719422417646455137135420132217031370496583210154654068035397417906022589503023501937519773030945763173210852507299305089761582519159720757232455434770912461317493580281734466552734375•10 -308
  • 2 -1022 = 2.2250738585072013 83090232717332404064219215980462331830553327416887204434813918195854283159012511020564067339731035811005152434161553460108856012385377718821130777993532002330479610147442583636071921565046942503734208375250806650616658158948720491179968591639648500635908770118304874799780887753749949451580451605050915399856582470818645113537935804992115981085766051992433352114352390148795699609591288891602992641511063466313393663477586513029371762047325631781485664350872122828637642044846811407613911477062801689853244110024161447421618567166150540154285084716752901903161322778896729707373123334086988983175067838846926092773977972858659654941091369095406136467568702398678315290680984617210924625396728515625•10 -308
  • 2 -1022 + 2 -1074 = 2.2250738585072018 771558785585789482407880088486837041956131300312119688603996006965297904292212628858639037013670281908017171296072711910355127227413175152199055740043138804567803233377539881639177387328959246074229270113078053813397081653361296447449529789521218979090783852583365901851789618799885150427514782636076021680436220311292700454832073964845713103912225963935608322440623896907276890186717054549275173986589324810401738228328251245795065655738191038008646911615828719989708647293221449796971546706720399791990809160347625980385995424739847678861180095072511543762389603716215171729816011544604359531284325406441938645324905389137795680915804792405099227413854274942620542640408839836919187418172987793340279242767544565229087538682506419718265533447265625•10 -308
  • 2 −1022 + 2•2 −1074 = 2.2250738585072023 •10 −308

现在我们可以看到为什么2 −1022 必须显示为“ 2.22507385850720142014-308”。如果显示的位数少一位,如“ 2.225073858507201201-308”,则它比2 −2更接近2 −1022 − 2 −1074 1022 ,所以这是错误的。

但是,对于2 −1022 + 2 −1074 ,“ 2.225073858507202e-308”就足够了,因为与此最接近的可表示值为2 −1022 < / sup> + 2 −1074 。 2 −1022 + 2•2 −1074 更远。