在R中添加和打印非常小的数字

时间:2019-05-31 18:22:23

标签: r for-loop floating-point

我在R中运行一个for循环,使用以下代码查看上半部分的加和最终是否达到1(.5 + .25 + .125 + .0625 + .03125,...):

temp = 0
for(i in 2^seq(1, 60, by = 1))  { 
  temp = temp + 1/i
  print(sprintf("%.40f", temp))
  flush.console()
  }

但是,在第54次迭代之后,它确实达到了1次,但显然不再添加任何东西(甚至增加了%.40f参数):

result.52 "0.9999999999999997779553950749686919152737"
result.53 "0.9999999999999998889776975374843459576368"
result.54 "1.0000000000000000000000000000000000000000"
result.55 "1.0000000000000000000000000000000000000000"
result.56 "1.0000000000000000000000000000000000000000"
result.57 "1.0000000000000000000000000000000000000000"
result.58 "1.0000000000000000000000000000000000000000"
result.59 "1.0000000000000000000000000000000000000000"

如何打印所有数字?我想这与更深入地了解R的数学标准有关

1 个答案:

答案 0 :(得分:0)

包装Rmpfr可以得到更高的精度。在下面的示例中,我将使用100位精度。

library(Rmpfr)

d <- 100
zero <- mpfr(0, precBits = d)
one <- mpfr(1, precBits = d)
powers <- mpfr(2^(1:60), precBits = d)

result <- vector("list", length = length(powers))
temp2 <- zero
for(i in seq_along(powers)) {
  temp2 = temp2 + one/powers[i]
  iszero <- mpfrIs0(one/powers[i])
  result[[i]] <- list(Exp = i, InvIsZero = iszero, Sum = temp2)
}

在问题中,OP表示

  

过去第54次迭代,它确实达到了一次,但显然没有   再添加一些东西(甚至增加%.40f参数)。

显然,这与sprintf有关,与结果无关。
使用print.mpfr方法:

for(i in 52:60){
  print(result[[i]][[3]], digits = 60)
  flush.console()
}
#1 'mpfr' number of precision  100   bits 
#[1] 0.9999999999999997779553950749686919152736663818359375
#1 'mpfr' number of precision  100   bits 
#[1] 0.99999999999999988897769753748434595763683319091796875
#1 'mpfr' number of precision  100   bits 
#[1] 0.999999999999999944488848768742172978818416595458984375
#1 'mpfr' number of precision  100   bits 
#[1] 0.9999999999999999722444243843710864894092082977294921875
#1 'mpfr' number of precision  100   bits 
#[1] 0.99999999999999998612221219218554324470460414886474609375
#1 'mpfr' number of precision  100   bits 
#[1] 0.999999999999999993061106096092771622352302074432373046875
#1 'mpfr' number of precision  100   bits 
#[1] 0.9999999999999999965305530480463858111761510372161865234375
#1 'mpfr' number of precision  100   bits 
#[1] 0.99999999999999999826527652402319290558807551860809326171875
#1 'mpfr' number of precision  100   bits 
#[1] 0.999999999999999999132638262011596452794037759304046630859375

使用sprintf

for(i in 52:60){
  print(sprintf("%d - %.60f", i, result[[i]][[3]]))
  flush.console()
}
#[1] "52 - 0.999999999999999777955395074968691915273666381835937500000000"
#[1] "53 - 0.999999999999999888977697537484345957636833190917968750000000"
#[1] "54 - 1.000000000000000000000000000000000000000000000000000000000000"
#[1] "55 - 1.000000000000000000000000000000000000000000000000000000000000"
#[1] "56 - 1.000000000000000000000000000000000000000000000000000000000000"
#[1] "57 - 1.000000000000000000000000000000000000000000000000000000000000"
#[1] "58 - 1.000000000000000000000000000000000000000000000000000000000000"
#[1] "59 - 1.000000000000000000000000000000000000000000000000000000000000"
#[1] "60 - 1.000000000000000000000000000000000000000000000000000000000000"