Sorting decimal numbers using Intl.Collator
and the option to enable numeric
pares decimals incorrectly.
On some browsers paring "0.005" and "0.05" returns "0" as in the numbers are the same.
Results in different browsers:
- Chrome 54 = 0
- Firefox 49 = 0
- Edge = -1
- IE 11 = -1
// Returns 0
console.log(new Intl.Collator(undefined, { numeric: true})pare(0.000005, 0.05))
Sorting decimal numbers using Intl.Collator
and the option to enable numeric
pares decimals incorrectly.
On some browsers paring "0.005" and "0.05" returns "0" as in the numbers are the same.
Results in different browsers:
- Chrome 54 = 0
- Firefox 49 = 0
- Edge = -1
- IE 11 = -1
// Returns 0
console.log(new Intl.Collator(undefined, { numeric: true}).pare(0.000005, 0.05))
Anyone that can tell me whats wrong?
Reported as bug in Firefox: https://bugzilla.mozilla/show_bug.cgi?id=1312388
Share Improve this question edited Oct 26, 2016 at 20:23 Jeff Walden 7,1182 gold badges40 silver badges55 bronze badges asked Oct 18, 2016 at 11:54 NisdNisd 1,15311 silver badges22 bronze badges 2- 1 i get -1 on edge. – Nina Scholz Commented Oct 18, 2016 at 12:02
- Thanks @NinaScholz, I have updated the question with the different results I get. – Nisd Commented Oct 18, 2016 at 13:25
2 Answers
Reset to default 5As André Bargull observes in the Firefox bug report, numeric sorting considers only decimal digit sequences, i.e. in the Unicode category of Number, by their numeric values. That is, when paring two otherwise-identical strings containing decimal numbers with fractional ponents, the entire decimal numbers aren't considered for their numeric value -- because U+002E FULL STOP isn't in the Number category (it's instead in the Punctuation category).
So then, when we pare these two strings -- "0.05" and "0.000005" -- we effectively are paring these arrays of elements:
["0", ".", "05"]
["0", ".", "000005"]
and then when digit sequences are considered by their numeric values, we're paring
[0, ".", 5]
[0, ".", 5]
which are equal, and so pare
should return 0 when paring them. Firefox and Chrome are right here, and IE and Edge are mistaken.
Workaround
Multiply values by 100_000_000 to get rid of decimals
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}).pare(normalizedA, normalizedB));
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745368030a4624671.html
评论列表(0条)