javascript - Intl.Collator and natural sort with numeric option sorts incorrectly with decimal numbers - Stack Overflow

Sorting decimal numbers using Intl.Collator and the option to enable numeric pares decimals incorrectly

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
Add a ment  | 

2 Answers 2

Reset to default 5

As 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条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信