-
Notifications
You must be signed in to change notification settings - Fork 30.1k
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
util: format specifier %d
use parseInt
#23321
Conversation
@nodejs/util @nodejs/tsc PTAL I am somewhat on the edge about this. It has always been like this in Node.js and AFAIK there was never any complaint about it. But following the spec does seem to be the right thing in the end. |
Assuming CITGM is clean and gzemnid doesn't find any big surprises: I'm in favor of this, but not enough to want to push it through over the objections of other TSC folks should there be any. Call it a +0.5. So I'm going to wait a bit and see what others say... |
Can we go through deprecation cycle? |
I don't think that's possible here without making things much worse for the end user (e.g., removing We're changing behavior, but not deprecating a feature. If it's possible to detect that someone is using |
Yup, this is what I had in mind. Detect if the user is passing a floating point number for |
I would think |
Ideally, yes. But, today, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will need a rebase because of recent BigInt changes landed.
2a16287
to
c027028
Compare
@silverwind Thank you for reviewing. I rebased and fixed bigint test. |
assert.strictEqual(util.format('%d %d', 42, 43), '42 43'); | ||
assert.strictEqual(util.format('%d %d', 42), '42 %d'); | ||
assert.strictEqual( | ||
util.format('%d', 1180591620717411303424), | ||
'1.1805916207174113e+21' | ||
'1' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I’m a bit surprised by this one, tbh … at least for me locally, `${parseInt('1180591620717411303424')}` === '1.1805916207174113e+21'
? Do you know why there’s a discrepancy?
Interestingly, Firefox seems to provide 0
here, and Chrome the exponential notation…
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens here is not ${parseInt('1180591620717411303424')}
but ${parseInt(1180591620717411303424)}
which is equivalent to ${parseInt('1.1805916207174113e+21')}
and returns 1.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So … just to make sure, these are browser bugs?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure... It could also be a spec bug because no browser has the "correct" behavior.
To summarize, with console.log('%d', 1180591620717411303424)
:
- Edge and Chrome:
1.1805916207174113e+21
- Firefox:
0
- Safari:
1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To me it seems like the browsers deviate from the spec in this case. However, it does seem to be a a good idea to follow Chrome and Edge in this case. Especially, since the spec does not seem to follow any browser implementation in this case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Safari logs 1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
1
should be correct according to the latest parseInt spec. NumberToString
has to convert the number to expotential notation and then the following spec text applies:
If S contains a code unit that is not a radix-R digit, let Z be the substring of S consisting of all code units before the first such code unit
Let mathInt be the mathematical integer value that is represented by Z
.
is not a radix-R digit, so parsing stops there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So in summary for console.log('%d', number)
:
- Chrome uses
Number
- Edge uses
Number
- Safari uses
parseInt
(this is spec-compliant) - Firefox uses neither
Number
norparseInt
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Chrome may not use Number
for %d
.
at least chrome 70(stable) on my macbook, I think %d
is not equal Number
.
the results are:
console.log('%d', 1.2)
: 1
Number(1.2)
: 1.2
This is going to need another rebase |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, to re-iterate from #22885 (comment), especially given browser behavior difference:
I'd rather keep the minor difference (which the Node.js ecosystem is probably used to) rather than loose functionality
I actually think we may want to consider this a spec bug and file against the spec repo. The spec is fairly new and was supposed to modal somewhat what browsers did and here it certainly does not. The spec is in the minority.
Change spec of %d specifier in util.format to follow whatwg spec (https://console.spec.whatwg.org/#formatting-specifiers). This is a breaking change.
64a267d
to
cec2e69
Compare
@Fishrock123 Thank you for your comment. As you think, it may be spec bug. |
The first aim should be to be as compatible as possible. Specs help with that but they are not worth much if no one's going to follow them, which seems to be the case here. I'd suggest we first investigate the current behaviour of all format specifiers in browsers and node and then present the results to WHATWG so they can evaluate possible spec changes. |
@silverwind Is anyone doing that? If not, should we close this since it's not going to reach consensus? (Only other real alternative is to escalate to the TSC.) |
I personally don't have the motivation to do that kind of work for a feature I don't need/use. I think template strings are superior to format specifiers in every way. So I would agree to closing this and related issues. |
@Trott @silverwind OK, thanks. I close this. Thank you all for your reviews. |
Change spec of %d specifier in util.format to follow whatwg spec
(https://console.spec.whatwg.org/#formatting-specifiers).
This is a breaking change.
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passesFixes: #22885