使用Intl.Collator对十进制数进行排序,并使用启用numeric的选项对小数进行错误的比较。
在一些浏览器中,将"0.005“和”0.005“进行比较,返回"0”,就像数字一样。
在不同浏览器中的结果:
// Returns 0
console.log(new Intl.Collator(undefined, { numeric: true}).compare(0.000005, 0.05))
有人能告诉我怎么回事吗?
在火狐中报告为bug:bug.cgi?id=1312388
发布于 2016-10-25 15:09:16
正如AndréBargull在Firefox bug报告中所观察到的,数字排序只考虑十进制数字序列,即数字的Unicode类别中的数字序列。也就是说,当将包含小数数的两个相同字符串与小数成分进行比较时,不考虑整个十进制数的数值--因为U+002E句号不在数字类别中(而是在标点符号类别中)。
那么,当我们比较这两个字符串-- "0.000005“和”0.000005“时,我们实际上是在比较这些元素数组:
["0", ".", "05"]
["0", ".", "000005"]然后,当数字序列被它们的数值考虑时,我们在比较
[0, ".", 5]
[0, ".", 5]它们是相等的,所以compare在比较它们时应该返回0。Firefox和Chrome就在这里,IE和Edge都弄错了。
发布于 2022-11-17 10:04:55
解决方案
用100_000_000乘法去除小数
const a = 0.000005;
const b = 0.05;
// NOTE: assume this value is ok for now but prefer
// to get the length of the smallest value and use
// this value in the powers of 10
// for example, [0,09, 0,003] => Math.pow(10, 3)
// But in this case we can go beyond the Number.MAX_SAFE_INTEGER
const NORMALIZE_VALUE = 100_000_000;
const normalizedA = a * NORMALIZE_VALUE;
const normalizedB = b * NORMALIZE_VALUE;
console.log(new Intl.Collator(undefined, { numeric: true}).compare(normalizedA, normalizedB));
https://stackoverflow.com/questions/40107588
复制相似问题