This question already has an answer here:
这个问题在这里已有答案:
- Is floating point math broken? 24 answers
- 浮点数学是否破碎? 24个答案
The function follows:
功能如下:
qual <- function(x, y, z)
{if ((abs(x - y) <= .15)&(abs(x - z) <= .15)&(abs(y - z) <= .15)){print("grade A")}
else if((abs(x - y) <= .15)|(abs(x - z) <= .15)){print("grade B")}
else if((abs(x - y) <= .2)|(abs(x - z) <= .2)){print("grade C")}
else if((abs(x - y) <= .25)|(abs(x - z) <= .25)){print("grade D")}
else {print("check manually")}}
It seems that, e.g., the output of qual(1.19, 1.04, 1.06)
and qual(1.10, .95, .97)
should be "grade A". However, the output is "grade A" and "grade B", respectively.
看来,例如,qual(1.19,1.04,1.06)和qual(1.10,.95,.97)的输出应该是“A级”。但是,输出分别是“A级”和“B级”。
Why is this?
为什么是这样?
1 个解决方案
#1
0
I think you are hitting some floating point precision problems. See Why are these numbers not equal for a full explanation.
我认为你正在遇到一些浮点精度问题。请参阅为什么这些数字不相等以获得完整的解释。
To fix this, you can use a short function that takes into account minor precision errors when comparing:
要解决此问题,您可以使用一个简短的函数,在比较时考虑较小的精度错误:
less_equal_safe <- function(x, y) {
(x < y) | dplyr::near(x, y)
}
qual <- function(x, y, z) {
if (less_equal_safe(abs(x - y), .15) & (abs(x - z) <= .15) &(abs(y - z) <= .15)) {
print("grade A")
} else if ((abs(x - y) <= .15) | (abs(x - z) <= .15)) {
print("grade B")
} else if ((abs(x - y) <= .2) | (abs(x - z) <= .2)) {
print("grade C")
}
else if ((abs(x - y) <= .25) | (abs(x - z) <= .25)) {
print("grade D")
} else {
print("check manually")
}
}
(note that you need the dplyr
package to be installed to use dplyr::near
)
(请注意,您需要安装dplyr软件包才能使用dplyr :: near)
I've only replaced the first comparison, which is the one that was causing the issue, but ideally you should replace all comparisons in your function with the float-safe function.
我只更换了第一个比较,这是造成问题的比较,但理想情况下你应该用float-safe函数替换函数中的所有比较。
#1
0
I think you are hitting some floating point precision problems. See Why are these numbers not equal for a full explanation.
我认为你正在遇到一些浮点精度问题。请参阅为什么这些数字不相等以获得完整的解释。
To fix this, you can use a short function that takes into account minor precision errors when comparing:
要解决此问题,您可以使用一个简短的函数,在比较时考虑较小的精度错误:
less_equal_safe <- function(x, y) {
(x < y) | dplyr::near(x, y)
}
qual <- function(x, y, z) {
if (less_equal_safe(abs(x - y), .15) & (abs(x - z) <= .15) &(abs(y - z) <= .15)) {
print("grade A")
} else if ((abs(x - y) <= .15) | (abs(x - z) <= .15)) {
print("grade B")
} else if ((abs(x - y) <= .2) | (abs(x - z) <= .2)) {
print("grade C")
}
else if ((abs(x - y) <= .25) | (abs(x - z) <= .25)) {
print("grade D")
} else {
print("check manually")
}
}
(note that you need the dplyr
package to be installed to use dplyr::near
)
(请注意,您需要安装dplyr软件包才能使用dplyr :: near)
I've only replaced the first comparison, which is the one that was causing the issue, but ideally you should replace all comparisons in your function with the float-safe function.
我只更换了第一个比较,这是造成问题的比较,但理想情况下你应该用float-safe函数替换函数中的所有比较。