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

fix: both %i and %d should parse floats to int according to Formatter docs #48246

Closed

Conversation

joshuapare
Copy link

@joshuapare joshuapare commented May 30, 2023

Fixes #48238

According to the docs at https://console.spec.whatwg.org/#formatter, both %d and %i should parse to an integer.

Matched the parsing method of %d to the same as %i, and corrected tests with improper assertions given this information.

@nodejs-github-bot nodejs-github-bot added needs-ci PRs that need a full CI run. util Issues and PRs related to the built-in util module. labels May 30, 2023
@kamilogorek
Copy link

kamilogorek commented May 30, 2023

Instead of fixing %d, you can modify the switch statement to match both variants, as they are now exactly the same:

case 100: // 100 ('d') and 105 are ('i') should be handled in the exact same way
case 105: {
  // ...
}

This change also requires an update to util.inspect docs table - https://github.com/nodejs/node/blob/main/doc/api/util.md#utilformatformat-args

@kvakil kvakil added the semver-major PRs that contain breaking changes and should be released in the next major version. label May 30, 2023
@kvakil
Copy link
Contributor

kvakil commented May 30, 2023

Marking this as semver-major, since it changes the output of console.log & util.format.

assert.strictEqual(util.format('%d', -0.0), '-0');
assert.strictEqual(util.format('%d', ''), '0');
assert.strictEqual(util.format('%d', 1.5), '1');
assert.strictEqual(util.format('%d', -0.5), '-0');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NIT: in chrome console.log('%d', '-0.5') outputs 0

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry I'm not familiar with that acronym 😅 though this is a good point of difference between both integer formats in server and in browser (confirmed in Firefox as well).

Should this be corrected (likely not in this unit of work) or just noted?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NIT = Nitpick (something that doesn't affect the overall PR and can, but doesn't necessarily have to be updated in order for it to be mergeable) :)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that node and chrome are v8, that seems more important to align with than firefox here?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed 100%, was just noting that Firefox behaved the same as Chrome in this situation with the sign flip, so it's not specific to just Chrome/V8

@targos
Copy link
Member

targos commented May 30, 2023

@nodejs/util

@joshuapare joshuapare force-pushed the correct-digit-formatter-float branch from 9594d66 to 6552e03 Compare May 30, 2023 12:38
@ljharb
Copy link
Member

ljharb commented May 30, 2023

This seems like it's both a breaking change, and also one that makes node strictly less useful solely to conform with browsers. Why is this desirable for a core module? util.format isn't a web API.

@OguzhanUmutlu
Copy link

@ljharb It is the expected behavior of JavaScript.

@ljharb
Copy link
Member

ljharb commented May 30, 2023

@OguzhanUmutlu how so? "the web" isn't the same as "javascript", and while "%i" definitely tells me "integer" (in many languages), "%d" tells me "decimal", which is decidedly not integers (across many languages as well).

@joshuapare
Copy link
Author

@ljharb while I see where you are coming from, I would like to note that the official description of utils.format in the NodeJS docs is:

A printf-like format string.

%d is standard for a decimal signed integer across most other printf implementations, including C/C++. Given this, along with the current behavior of the major browsers, I would think that this is a valid point of consistency to achieve given that it neither matches the behavior of the V8 engine, the browser, or historical behavior of printf.

In addition, I'm not sure how this deviation of %d is useful - if you need floating point precision, you'd want the first position after the decimal even if it was zero, in which case you would use %f. The only difference left (at least from what I can tell, which I could very well be wrong) is Infinity being formatted as NaN instead of 'Infinity', which I wouldn't think is a valid reason to deviate.

However, this is not my call to make, so I'm more than happy to revise based on the feedback from the maintainers.

@aduh95
Copy link
Contributor

aduh95 commented Jun 4, 2023

"%d" tells me "decimal", which is decidedly not integers (across many languages as well).

%d means "integer in base 10" in every languages I've ever used 🤔 (and base 10 is decimal of course). IMO it makes sense to align.

Copy link
Member

@BridgeAR BridgeAR left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am a bit torn what to do here. The suggestion is definitely valid, as it aligns with the "normal" %d behavior. In Node.js it has just always worked as "decimal", and some code might rely upon the current behavior - especially debug logs. I can't think of a situation where changing the behavior now would improve a users experience and therefore, I wonder if it makes sense to keep the current behavior as legacy oversight.

@aduh95
Copy link
Contributor

aduh95 commented Sep 29, 2023

This would need a rebase and a fix for the the linter failure.

Copy link
Contributor

github-actions bot commented Aug 9, 2024

This issue/PR was marked as stalled, it will be automatically closed in 30 days. If it should remain open, please leave a comment explaining why it should remain open.

@avivkeller
Copy link
Member

Hey, I've marked this PR as stalled, as it is currently unable to land. @aduh95 gave suggestions on how to make this landable, but they are so-far unaddressed.

Copy link
Member

@BridgeAR BridgeAR left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about it more and this could definitely cause difficult to detect problems for users to change this. Imagine sensor data is formatted using util.format() and now the decimal part would just be ignored. It is pretty much impossible to detect the changed behavior (integers would still be legit) but it would break the users expected behavior.
For new users, it's easy to switch to %i for integers, as they will immediately see that %d is not used like that (as it is documented).
Overall, I don't think it's worth the risk of breaking applications/causing data loss for that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs-ci PRs that need a full CI run. semver-major PRs that contain breaking changes and should be released in the next major version. stalled Issues and PRs that are stalled. util Issues and PRs related to the built-in util module.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Incorrect behavior of console.log("%d", 1.1) in Node.js