R 最高有效小数位数(或0.3-0.1=0.1)

R 最高有效小数位数(或0.3-0.1=0.1),r,floating-point,rounding,floor,R,Floating Point,Rounding,Floor,此操作应返回2,但由于浮点数表示,它将返回1: a <- .3 b <- .1 floor((a-b)*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.ch

此操作应返回2,但由于浮点数表示,它将返回1:

a <- .3
b <- .1
floor((a-b)*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)

建议?

这是不可能的,因为信息不再存在: double不能精确地表示十进制数

如果你对近似解没意见, 您可以添加一个小数字,然后截断结果。 例如,如果你知道你的数字最多有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

您希望何时对值进行四舍五入,何时不进行四舍五入?您需要更好地定义所需的行为。例如,0.5-.001应该返回什么?如何将其与0.3-.1区分开来?它不是四舍五入,只是截断。请参见编辑的问题中的示例是的,它看起来只是截断,但由于.3-.1的存储方式,您需要进行四舍五入才能得到.2。哦,试试你最近在1-.9或.9-.8上的尝试。这比看起来更复杂。floorrounda-b*100/10尝试在.5-.001上中断。这就是为什么我会问,什么时候你希望值被四舍五入,什么时候你不想被四舍五入?你是对的。我添加了一个新的替代方案,首先将其转换为字符串,因此我认为我们消除了浮点问题,然后将第三个字符放在pointYep之后,这应该可以工作。所有数字都来自一个最多有4位十进制数字的文件。你认为substringas.charactera-b,first=3,last=3也可以吗?如果它们最多有4位小数,那么你可以加载它们,乘以1e4,四舍五入,然后转换为整数。这样就不必处理浮点错误了。
first_significant_digit <- function(x, epsilon=5e-14)
  floor( (x+epsilon) * 10^-floor(log10(x+epsilon)) )
first_significant_digit(0.12-0.11) # 1