最高有效十进制数字(或0.3 - 0.1 = 0.1)

时间:2013-06-08 02:26:06

标签: r floating-point rounding floor

此操作应返回2,但由于浮点表示而返回1

a <- .3
b <- .1
floor((a-b)*10)

我基本上想要在实际的基数为10的结果之后的第一个数字,而不是浮点数计算机的结果。在这种情况下,ab只有一个十进制数字,但在大多数情况下会有更多。例子:

  • 0.3-0.1=0.2所以我想要2
  • 0.5-0.001=0.499所以我想要4
  • 0.925-0.113=0.812所以我想要8
  • 0.57-0.11=0.46所以我想要4
  • 0.12-0.11=0.01所以我想要0

即,不是舍入而是截断。我想过用这个:

floor(floor((a-b)*100)/10)

但我不确定这是否是我能做的最好的。

更新:确实,它不起作用(请参阅下面的评论):

floor(floor((.9-.8)*100)/10) # gives 0 instead of 1
floor(round((.5-.001)*100)/10) # gives 5 instead of 1

更新2:认为这确实有效(至少在目前为止列出的所有情况下):

substring(as.character(a-b),first=3,last=3)

建议?

1 个答案:

答案 0 :(得分:1)

这是不可能的,因为信息不再存在: 双打不能完全代表十进制数。

如果您对近似解决方案没问题, 您可以添加一个小数字,并截断结果。 例如,如果您知道您的号码最多有14位数, 以下方法可行:

first_digit <- function(x, epsilon=5e-15)
  floor( (x+epsilon) * 10 )
first_digit( .3   - .1   ) # 2
first_digit( .5   - .001 ) # 4
first_digit( .925 - .113 ) # 8
first_digit( .57  - .11  ) # 4
first_digit( .12  - .11  ) # 0

如果您想要第一个重要数字(表示“第一个非零数字”), 你可以使用:

first_significant_digit <- function(x, epsilon=5e-14)
  floor( (x+epsilon) * 10^-floor(log10(x+epsilon)) )
first_significant_digit(0.12-0.11) # 1