所以我的情况是这样的,我在 JavaScript 上开发的软件需要操作精确的数值,但有时可能会发生这些值太接近,我需要区分。
这是一个案例:
0:(2) [112.02598008561951, 9.12963236661007]
1:(2) [112.02598008561952, 9.129632366610064]
2:(2) [9.751846481442218, 3.5376744911193576]
在此数组中,位置 0 和 1 具有相似的值,但小数点末尾略有不同,但重要的是位置 0,因为这两个数字非常接近,这会扰乱接下来的过程.
那么,我该如何区分接近的数字并只使用给出的相似数字中的第一个?
最后的结果将是一个像这样的数组:
0:(2) [112.02598008561951, 9.12963236661007]
1:(2) [9.751846481442218, 3.5376744911193576]
我尝试进行 chop ,但我需要使用整个数字。
编辑:作为询问点是否可以变化的评论之一,在我真正的问题中,我得到了一系列我通常排序的数字,我得到了 3 分,或者最好的情况我得到 2 分。
有时,当我接近数字并且第一层排序无法按预期工作并且下一部分无法正常工作时,就会出现此问题。
简而言之,你需要考虑它总是像 3 个坐标位置。
最佳答案
简而言之,最简单的选择是四舍五入到固定的小数位数。这是因为 JS(以及一般的计算机科学)中的浮点可能是一件棘手的事情。例如,这应该会让你想扔掉你的电脑:
var x = 0.1 * 0.2; //-> 0.020000000000000004
有不同的用例需要超精确的精度(例如,在处理金钱、卫星轨迹等时),但大多数用例只需要“足够好”的精度。对于您的情况,最好将所有数字四舍五入为固定的十进制长度,这样您就不会遇到低级错误。
var ACCURACY = 100000000;
var round= (num) => Math.round(num * ACCURACY) / ACCURACY;
var x = round(0.1 * 0.2); //-> 0.2
如果您相信自己拥有的数字,并且只需要过滤掉与另一对接近的数字对,则需要编写一个小函数来应用您的启发式方法。
var areClose = (x, y) => Math.abs(x - y) < 0.0000000001;
var filterPoints = (arr) => {
return arr.filter(([x, y], i) => {
for(var n = i - 1; n >= 0; n--) {
if (areClose(x, arr[n][0]) && areClose(y, arr[n][1])) {
return false;
}
}
return true;
});
}
filterPoints([
[112.02598008561951, 9.12963236661007],
[112.02598008561952, 9.129632366610064],
[9.751846481442218, 3.5376744911193576],
]);
// [
// [112.02598008561951, 9.12963236661007],
// [9.751846481442218, 3.5376744911193576]]
// ]
Note: this will keep the "first" set of values. If you wish to keep the "last" set, then you can flip the inner loop to crawl upwards:
for(var n = i + 1; n < arr.length; n++) { ...
关于javascript - 如何区分两个非常接近的数字?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71876552/