Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Intl.NumberFormat disregards maximumSignificantDigits #22156

Closed
jskeate opened this issue Aug 6, 2018 · 15 comments
Closed

Intl.NumberFormat disregards maximumSignificantDigits #22156

jskeate opened this issue Aug 6, 2018 · 15 comments
Assignees
Labels
i18n-api Issues and PRs related to the i18n implementation.

Comments

@jskeate
Copy link

jskeate commented Aug 6, 2018

  • Version: 10.7, 10.8 (possibly others, tested these two)
  • Platform: Darwin 15.6.0, Linux 4.17.10-1-ARCH
$ node
> new Intl.NumberFormat(undefined, { maximumSignificantDigits: 3 }).format(1234500)
'1,234,500'
> new Intl.NumberFormat(undefined, { maximumSignificantDigits: 3 }).format(1234560)
'1,234,560'
> new Intl.NumberFormat(undefined, { maximumSignificantDigits: 1 }).format(1234560)
'1,234,560'

Previously (node v9.2, at least), this behaved correctly:

> new Intl.NumberFormat(undefined, { maximumSignificantDigits: 3 }).format(1234500)
'1,230,000'
> new Intl.NumberFormat(undefined, { maximumSignificantDigits: 3 }).format(1234560)
'1,230,000'
> new Intl.NumberFormat(undefined, { maximumSignificantDigits: 1 }).format(1234560)
'1,000,000'
@devsnek devsnek added the i18n-api Issues and PRs related to the i18n implementation. label Aug 6, 2018
@devsnek
Copy link
Member

devsnek commented Aug 6, 2018

@nodejs/intl @nodejs/v8

@vsemozhetbyt
Copy link
Contributor

vsemozhetbyt commented Aug 6, 2018

These are results with some relevant Node.js and V8 (Windows 7 x64, common Node.js builds with small-icu):

new Intl.NumberFormat(undefined, { maximumSignificantDigits: 1 }).format(1234560)
Node.js 06.14.3 V8 5.1
'1,000,000'

Node.js 08.11.3 V8 6.2
'1,000,000'

Node.js 10.8.0 V8 6.7
'1,234,560'

Node.js 11.0.0.2018-08-01.nightly V8 6.8
'1,234,560'

Node.js 11.0.0.2018-07-14.v8-canary V8 6.9
'1,000,000'

Node.js 11.0.0.2018-08-01.v8-canary V8 7.0
'1,234,560'

@srl295
Copy link
Member

srl295 commented Aug 6, 2018

undefined

  • thought 1: it shouldn't matter but it is probably better to pin this to something such as the following, to remove uncertainty

new Intl.NumberFormat(['en-US'], { maximumSignificantDigits: 1 }).format(1234560)

  • thought 2: does this work in v8 (d8) directly? what is the behavior there?

@srl295
Copy link
Member

srl295 commented Aug 6, 2018

  • thought 3 - 'there oughtta be a test for this'

@devsnek
Copy link
Member

devsnek commented Aug 6, 2018

@srl295

V8 version 6.9.0 (candidate)
d8> new Intl.NumberFormat(['en-US'], { maximumSignificantDigits: 1 }).format(1234560)
"1,000,000"

@srl295
Copy link
Member

srl295 commented Aug 6, 2018

so right now i'm concerned about this

> new Intl.NumberFormat(['en'], { minimumSignificantDigits:1, maximumSignificantDigits: 3 }).resolvedOptions().maximumSignificantDigits
6

and 3 kinda ≠ 6

@vsemozhetbyt
Copy link
Contributor

-p "new Intl.NumberFormat(['en-US'], { maximumSignificantDigits: 1 }).format(1234560)"
Node.js 06.14.3 V8 5.1
1,000,000
Node.js 08.11.3 V8 6.2
1,000,000
Node.js 10.8.0 V8 6.7
1,234,560
Node.js 11.0.0.2018-08-01.nightly V8 6.8
1,234,560
Node.js 11.0.0.2018-07-14.v8-canary V8 6.9
1,000,000
Node.js 11.0.0.2018-08-01.v8-canary V8 7.0
1,234,560

@srl295
Copy link
Member

srl295 commented Aug 6, 2018

@vsemozhetbyt
Copy link
Contributor

V8 version 7.0.167
d8> new Intl.NumberFormat(['en-US'], { maximumSignificantDigits: 1 }).format(1234560)
"1,000,000"
> process.versions.node
'11.0.0-v8-canary2018080644d0a70123'
> process.versions.v8
'7.0.158-node.1'
> new Intl.NumberFormat(['en-US'], { maximumSignificantDigits: 1 }).format(1234560)
'1,234,560'

@srl295
Copy link
Member

srl295 commented Aug 6, 2018

There's an ICU bug. https://unicode-org.atlassian.net/browse/ICU-20063 // @sffc

@srl295
Copy link
Member

srl295 commented Aug 6, 2018

v8 is broken too unless they've mitigated this.

here's a hackaround that will should work for any ICU version:

diff --git a/deps/v8/src/objects/intl-objects.cc b/deps/v8/src/objects/intl-objects.cc
index 60c3a0721b..adbb6b460e 100644
--- a/deps/v8/src/objects/intl-objects.cc
+++ b/deps/v8/src/objects/intl-objects.cc
@@ -274,20 +274,31 @@ void SetNumericSettings(Isolate* isolate, icu::DecimalFormat* number_format,
     number_format->setMaximumFractionDigits(digits);
   }
 
-  bool significant_digits_used = false;
+  int32_t mndig = -1;
+  int32_t mxdig = -1;
+  bool mndig_used = false;
+  bool mxdig_used = false;
   if (ExtractIntegerSetting(isolate, options, "minimumSignificantDigits",
-                            &digits)) {
-    number_format->setMinimumSignificantDigits(digits);
-    significant_digits_used = true;
+                            &mndig)) {
+    mndig_used = true;
   }
 
   if (ExtractIntegerSetting(isolate, options, "maximumSignificantDigits",
-                            &digits)) {
-    number_format->setMaximumSignificantDigits(digits);
-    significant_digits_used = true;
+                            &mxdig)) {
+    mxdig_used = true;
   }
 
-  number_format->setSignificantDigitsUsed(significant_digits_used);
+  // per https://unicode-org.atlassian.net/browse/ICU-20063
+  // the following call trashes the min/max settings. So call it first.
+  number_format->setSignificantDigitsUsed(mndig_used || mxdig_used);
+
+  // Now it's safe to call set min/max
+  if(mndig_used) {
+    number_format->setMinimumSignificantDigits(digits);
+  }
+  if(mxdig_used) {
+    number_format->setMaximumSignificantDigits(digits);
+  }
 
   number_format->setRoundingMode(icu::DecimalFormat::kRoundHalfUp);
 }

@srl295
Copy link
Member

srl295 commented Aug 6, 2018

v8 does NOT have a mitigation for this that I could see… https://github.com/v8/v8/blob/master/src/objects/intl-objects.cc#L294 … so v8 is broken, depending on the ICU version used.

but :( looks like v8 put a hack into its ICU version — here is the patch

it might be better to just put this same patch into node's ICU for this specific version.

@srl295 srl295 mentioned this issue Aug 7, 2018
2 tasks
@srl295
Copy link
Member

srl295 commented Aug 7, 2018

@jskeate @vsemozhetbyt I committed a workaround patch in
srl295@b53db21 if you add this file into node and rebuild, it should mitigate the problem. it only applies to ICU 62, in future versions this should be fixed.

@JasonKleban
Copy link

JasonKleban commented Sep 25, 2018

node 10.11 still has this issue - the history is a little hard for me to read, other than that this issue is still marked Open. Can I please get a recap?

node -e "console.log(new Intl.NumberFormat('en-US', { maximumSignificantDigits: 4 }).format(10.001))"

expected: 10 got 10.001.

Chrome debugger 69.0.3497.100 (Official Build) (64-bit) gives the right answer - no idea if that's relevant. ICU's tracked issue looks to be marked resolved 3 days ago.

@srl295
Copy link
Member

srl295 commented Oct 19, 2018

@JasonKleban OK, sorry. Looks like I did not open a PR for master...srl295:patch-icu-62-sigdig … and also #23715 brings in 63.1 which fixes this. let me see what I can do.

@srl295 srl295 mentioned this issue Oct 19, 2018
3 tasks
@srl295 srl295 self-assigned this Oct 19, 2018
mcollina pushed a commit to mcollina/node that referenced this issue Oct 23, 2018
ICU 62.1 had a bug where certain orders of operations would not
work with the minimum significant digit setting. Fixed in
ICU 63.1. Applied the following patch from v8.

https://chromium-review.googlesource.com/c/chromium/deps/icu/+/1128503

ICU Bug:
https://unicode-org.atlassian.net/browse/ICU-20063

Fixes: nodejs#22156

PR-URL: nodejs#23764
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Refael Ackermann <refack@gmail.com>
targos pushed a commit that referenced this issue Oct 24, 2018
ICU 62.1 had a bug where certain orders of operations would not
work with the minimum significant digit setting. Fixed in
ICU 63.1. Applied the following patch from v8.

https://chromium-review.googlesource.com/c/chromium/deps/icu/+/1128503

ICU Bug:
https://unicode-org.atlassian.net/browse/ICU-20063

Fixes: #22156

PR-URL: #23764
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Refael Ackermann <refack@gmail.com>
MylesBorins pushed a commit that referenced this issue Nov 26, 2018
ICU 62.1 had a bug where certain orders of operations would not
work with the minimum significant digit setting. Fixed in
ICU 63.1. Applied the following patch from v8.

https://chromium-review.googlesource.com/c/chromium/deps/icu/+/1128503

ICU Bug:
https://unicode-org.atlassian.net/browse/ICU-20063

Fixes: #22156

PR-URL: #23764
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Refael Ackermann <refack@gmail.com>
MylesBorins pushed a commit that referenced this issue Nov 26, 2018
ICU 62.1 had a bug where certain orders of operations would not
work with the minimum significant digit setting. Fixed in
ICU 63.1. Applied the following patch from v8.

https://chromium-review.googlesource.com/c/chromium/deps/icu/+/1128503

ICU Bug:
https://unicode-org.atlassian.net/browse/ICU-20063

Fixes: #22156

PR-URL: #23764
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Refael Ackermann <refack@gmail.com>
rvagg pushed a commit that referenced this issue Nov 28, 2018
ICU 62.1 had a bug where certain orders of operations would not
work with the minimum significant digit setting. Fixed in
ICU 63.1. Applied the following patch from v8.

https://chromium-review.googlesource.com/c/chromium/deps/icu/+/1128503

ICU Bug:
https://unicode-org.atlassian.net/browse/ICU-20063

Fixes: #22156

PR-URL: #23764
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Refael Ackermann <refack@gmail.com>
rvagg pushed a commit that referenced this issue Nov 28, 2018
ICU 62.1 had a bug where certain orders of operations would not
work with the minimum significant digit setting. Fixed in
ICU 63.1. Applied the following patch from v8.

https://chromium-review.googlesource.com/c/chromium/deps/icu/+/1128503

ICU Bug:
https://unicode-org.atlassian.net/browse/ICU-20063

Fixes: #22156

PR-URL: #23764
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Refael Ackermann <refack@gmail.com>
MylesBorins pushed a commit that referenced this issue Nov 29, 2018
ICU 62.1 had a bug where certain orders of operations would not
work with the minimum significant digit setting. Fixed in
ICU 63.1. Applied the following patch from v8.

https://chromium-review.googlesource.com/c/chromium/deps/icu/+/1128503

ICU Bug:
https://unicode-org.atlassian.net/browse/ICU-20063

Fixes: #22156

PR-URL: #23764
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Refael Ackermann <refack@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
i18n-api Issues and PRs related to the i18n implementation.
Projects
None yet
Development

No branches or pull requests

5 participants