处理接近无穷大的数字(大和小)

Handling numbers near infinity (large and small)

我正在尝试使用 Ruby 执行此操作:

1.2679769534809603e-175
*
792621072814943158937574954417696054502273470568077747007887743862285047941581535541498718312275086275679893343076013862361579680670972527976009279036348551929550827607601145450876014530359530008733947699274904382825445634899233107885545828612637824213482759975963581961375904743254634250508637523339809985946128242523687347261107994804323593105039052556442336528920420940313

我知道答案是 1.005025(截断到小数点后 6 位),但我一直得到上​​面的等式 returning infinity。这是为什么?我不会比第一个数字小,也不会比第二个数字大。

那么两个问题:为什么它是return无穷大?我怎样才能得到 return 的正确答案?

经过一番尝试,我相信您的问题出在自动提升第二个数字以执行浮点运算。

puts "Original math"
z = 1.2679769534809603e-175 * 792621072814943158937574954417696054502273470568077747007887743862285047941581535541498718312275086275679893343076013862361579680670972527976009279036348551929550827607601145450876014530359530008733947699274904382825445634899233107885545828612637824213482759975963581961375904743254634250508637523339809985946128242523687347261107994804323593105039052556442336528920420940313
puts z

无限

puts
puts "Save variables individually and inspect" 
x = 1.2679769534809603e-175
y = 792621072814943158937574954417696054502273470568077747007887743862285047941581535541498718312275086275679893343076013862361579680670972527976009279036348551929550827607601145450876014530359530008733947699274904382825445634899233107885545828612637824213482759975963581961375904743254634250508637523339809985946128242523687347261107994804323593105039052556442336528920420940313
puts x

1.2679769534809603e-175

puts y

792621072814943158937574954417696054502273470568077747007887743862285047941581535541498718312275086275679893343076013862361579680670972527976009279036348551929550827607601145450876014530359530008733947699274904382825445634899233107885545828612637824213482759975963581961375904743254634250508637523339809985946128242523687347261107994804323593105039052556442336528920420940313

z = x * y
puts z

无限

puts "What? none of the numbers was Infinity??"

puts "Or was it?? auto promoted y"
y = 792621072814943158937574954417696054502273470568077747007887743862285047941581535541498718312275086275679893343076013862361579680670972527976009279036348551929550827607601145450876014530359530008733947699274904382825445634899233107885545828612637824213482759975963581961375904743254634250508637523339809985946128242523687347261107994804323593105039052556442336528920420940313.0
puts y

无限

在大多数语言中任何东西 * Infinity = +- infinity

如果您想最大程度地减少精度问题,请使用 Rational。

irb(main):001:0> a = 1.2679769534809603e-175.to_r
=> (4519585589664361/35644067325173400145634153169533525975728347712879374457649941546088087243817792082077443838416964060770643043543706307114755505635745609361348916560329798345718708393439569922522454626926592)
irb(main):002:0> b = 792621072814943158937574954417696054502273470568077747007887743862285047941581535541498718312275086275679893343076013862361579680670972527976009279036348551929550827607601145450876014530359530008733947699274904382825445634899233107885545828612637824213482759975963581961375904743254634250508637523339809985946128242523687347261107994804323593105039052556442336528920420940313
=> 792621072814943158937574954417696054502273470568077747007887743862285047941581535541498718312275086275679893343076013862361579680670972527976009279036348551929550827607601145450876014530359530008733947699274904382825445634899233107885545828612637824213482759975963581961375904743254634250508637523339809985946128242523687347261107994804323593105039052556442336528920420940313
irb(main):003:0> a * b
=> (3582318778758723293544808766608477208802528713781684733988516016569614012687037578637365969280014511731955915723620354805192948677648150726285518854921630223111683624006805801219885647290056974705691181872855057825408797944671825308998484595184690885834492619019604611321846034964892047367198046135813425296123973237329110031154221763204044754826429491855167243281047603348342563725684284993/35644067325173400145634153169533525975728347712879374457649941546088087243817792082077443838416964060770643043543706307114755505635745609361348916560329798345718708393439569922522454626926592)
irb(main):004:0> (a * b).to_f
=> 1.005025253172702e+200