-3

此操作应该返回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)

建议?

4

1 回答 1

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
于 2013-06-08T09:01:53.260 回答