You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
However, spec shows %d or %i uses %parseInt%(element, 10) for type conversion.
What specifier is the best for BigInt? Has this already been discussing?
Keep in mind that Node.js is currently violating the spec for the %d specifier where it uses the Number constructor which outputs those undesired scientific prefixes. The specced parseInt on the other hand can output series of digits for BigInt because its toString method which does not include the notion of a scientific notation.
Actually upon deeper investigation parseInt is also unsuitable for BigInt because it has NumberToString baked into it which represents everything above 1e21 using exponents.
So I think we'd actually need a console spec change, I see two options:
Let %i and %d also handle BigInt. This would introduce different behavior depending on the type.
Introduce a new %I dedicated for BigInt to retain a 1:1 mapping of type to conversion function.
I would prefer to define %d and %i specifiers to handle BigInt. The current description does not state int32, but instead "Element which substitutes is converted to an integer" which is vague enough.
On the other hand, BigInt.ToNumber() is defined to throw an error, and I'm unsure if using the same formatters will cause confusion with developers.
Options (1) and (2) do not look mutually exclusive: the %d and %i specifiers could handle BigInt values by returning NaN just like they do for Symbol values, while the proposed %I specifier could still produce specific results for BigInt formatting.
The Chrome implementation appends the n suffix to the formatted number but I think it would be more generally useful to hide such implementation details and output just the number.
Thank you all for your comments.
Chrome 70 is now stable.
In my local Chrome, Both console.log("%d",1180591620717411303424n) and console.log("%i", 1180591620717411303424n) output 1180591620717411303424n.
Do you think it should be added to the specification that %d and %i support BigInt and that if it is BigInt 'n' suffix is given?
Please comment if you have any opinions.
@domfarolino
Sorry for the delay on the response.
I recently implemented that %d and %i work for BigInt.
So all major browsers support %d and %i for BigInt.
Chrome 114.0.5735.106
Firefox 114.0.1
Safari 16.2
However, each browser differently work for %f now.
Chrome 114.0.5735.106
Firefox 114.0.1
Safari 16.2
I think that %d and %i should be defined as standards to support the format specifier of BigInt. But I’m still not sure that %f should be defined for that. Should we first start adding only %d and %i onto the spec? Or should we wait until we decide if %f should be supported?
Thanks for following-up on this and reminding be about this thread. I'm trying to figure out what action needs to be taken based on the desired result here. Years ago Chrome would output NaN for BigInts with the %d format specifier as the OP points, out which is obviously undesirable. Since then, parseInt() has been given support for BigInt, and Chrome follows the spec by outputting exactly what parseInt()/parseFloat() would output on BigInts for the %d/%f specifiers respectively. So if we're OK with this behavior & the spec, then no action needs to be taken — we get this result for free.
However, Firefox and Safari seem to have prettier outputs by actually listing all the integers without scientific notation (and Safari even puts commas in the right places etc.). If we want this special pretty output for BigInts, then I think we need to add the special case for BigInt to the %d and %i specifiers in Formatter as Domenic suggested earlier. I'm fine with this; it seems like a good outcome and mostly matches what two browsers are doing today. I imagine the special case would just consist of a call to BigInt::toString(), which just returns the concatenation of all digits in the BigInt, without the complicated scientific notation stuff that Number::toString() has.
Does this sound right to everyone, and does anyone have strong opinions on just delegating to parseInt() etc., vs creating special pretty output without scientific notation? I'm just trying to catch up on this thread and make sure we're all on the same page, since it should be pretty easy to resolve this issue.
As an alternative , we could specify %i and %d print the result of converting a BigInt to Number and formatting like normal (it sounds like Chrome might be doing this already). We could add %g to format the BigInt with full precision, and %e that you specifically want the scientific notation?
As an alternative , we could specify %i and %d print the result of converting a BigInt to Number and formatting like normal (it sounds like Chrome might be doing this already).
Doesn't the spec already do this? Since we don't special-case anything now, the spec will just call %parseInt()% on BigInts for the %d and %i specifiers, which I think is the same result as calling parseInt(bigIntFoo) (Chrome appears to do this).
So I guess I'm trying to figure out if we agree that the current spec just passes BigInts to %parseInt()%, and then after that we can figure out if we want to go a step further by spec'ing the special-casing that Firefox and Safari appear to do.
I think the behavior of going through %parseInt()% as Chrome does is the correct behavior. Instead of changing how %d and %i work to special case the Firefox and Safari behavior, the alternative is to add a new specifier for "Big" types.
Right. I'm personally a fan of less specifiers and instead special-casing BigInt support for %d and %i, since those are just the canonical integer specifiers, and big integers are indeed integers, just... big.
sprintf already has formatters for larger precision, and adding them wouldn't change the meaning of the existing formatters (and potentially break anyone expecting the current Chrome format).
Also, what's the status of BigDecimal? If it were to be added, would we have to add another special case?
BigDecimal is stage 1 apparently: https://github.com/tc39/proposal-decimal#ecma-tc39-javascript-decimal-proposal. I guess I was just assuming we could squeeze it into the %f specifier should the time come. It is true that other languages provide additional syntax to specify precision, but it seems that's usually provided in addition to a specifier like %d, %i, or %f, as opposed to a new specifiers altogether.
but it seems that's usually provided in addition to a specifier like %d, %i, or %f, as opposed to a new specifiers altogether.
And you could continue using those, you'd just get the behavior of %parseInt()% and %parseFloat()% as requested. I can be convinced otherwise, but I'd hate to change the existing meanings, which are currently very clear of what will happen.
Activity
silverwind commentedon Aug 9, 2018
Keep in mind that Node.js is currently violating the spec for the
%dspecifier where it uses theNumberconstructor which outputs those undesired scientific prefixes. The speccedparseInton the other hand can output series of digits for BigInt because its toString method which does not include the notion of a scientific notation.So I think, we may not even need a spec change.
silverwind commentedon Aug 9, 2018
Actually upon deeper investigation
parseIntis also unsuitable for BigInt because it has NumberToString baked into it which represents everything above1e21using exponents.So I think we'd actually need a console spec change, I see two options:
%iand%dalso handle BigInt. This would introduce different behavior depending on the type.%Idedicated for BigInt to retain a 1:1 mapping of type to conversion function.terinjokes commentedon Aug 9, 2018
I believe the issue isn't
NumberToString(sinceBigIntisn't a Number), butparseInt's call toToInt32.I would prefer to define
%dand%ispecifiers to handleBigInt. The current description does not state int32, but instead "Element which substitutes is converted to an integer" which is vague enough.On the other hand,
BigInt.ToNumber()is defined to throw an error, and I'm unsure if using the same formatters will cause confusion with developers.domenic commentedon Aug 9, 2018
My two cents: agreed handling BigInt is good. Probably https://console.spec.whatwg.org/#formatter step 3.2 should add another special-case for BigInt, like it currently does for Symbol. Also the third column of https://console.spec.whatwg.org/#formatting-specifiers should be updated I guess, not sure how though.
silverwind commentedon Aug 9, 2018
Maybe add a additional column before it for the source type. This could also include the Symbol special case.
fmartin5 commentedon Aug 9, 2018
Options (1) and (2) do not look mutually exclusive: the
%dand%ispecifiers could handle BigInt values by returningNaNjust like they do forSymbolvalues, while the proposed%Ispecifier could still produce specific results for BigInt formatting.shisama commentedon Aug 13, 2018
If new specifier is necessary for BigInt, the proposed
%Ilooks good.paulirish commentedon Aug 13, 2018
In Chrome, we just allowed
console.log("%d")to support BigInts:https://chromium-review.googlesource.com/c/chromium/src/+/1169777 cc @ak239
If this group decides we need different behavior, we can align.
terinjokes commentedon Aug 13, 2018
I don't mind expanding
%iand%dto support BigInt, and updating our table to include it.Paul, does Chrome have interest in also supporting
%i?Do we have input from Firefox, Safari, or Edge?
alexkozy commentedon Aug 13, 2018
In Chrome we support both and both of them support BigInt.
terinjokes commentedon Aug 13, 2018
@ak239 thanks for confirming. Gerrit wasn't loading well for me on Muni.
shisama commentedon Aug 14, 2018
@paulirish @ak239 Thanks. Now I confirmed
console.log("%d", 1n);andconsole.log("%i", 1n);print1non console in Chrome Canary(version 70.0.3521.0).silverwind commentedon Sep 17, 2018
The Chrome implementation appends the
nsuffix to the formatted number but I think it would be more generally useful to hide such implementation details and output just the number.shisama commentedon Oct 18, 2018
Thank you all for your comments.
Chrome 70 is now stable.
In my local Chrome, Both
console.log("%d",1180591620717411303424n)andconsole.log("%i", 1180591620717411303424n)output1180591620717411303424n.Do you think it should be added to the specification that
%dand%isupport BigInt and that if it is BigInt 'n' suffix is given?Please comment if you have any opinions.
domfarolino commentedon Oct 31, 2018
Sorry for the delay on getting to this. Plan on carving out time for this soon if nobody gets to it first.
tuchida commentedon Mar 1, 2022
What is the correct display when passing BigInt to
%f?Chrome/96.0.4664.110
Firefox/97.0
shisama commentedon Jun 11, 2023
@domfarolino
Sorry for the delay on the response.
I recently implemented that
%dand%iwork for BigInt.So all major browsers support
%dand%ifor BigInt.Chrome 114.0.5735.106

Firefox 114.0.1

Safari 16.2

However, each browser differently work for
%fnow.Chrome 114.0.5735.106

Firefox 114.0.1

Safari 16.2

I think that %d and %i should be defined as standards to support the format specifier of BigInt. But I’m still not sure that
%fshould be defined for that. Should we first start adding only%dand%ionto the spec? Or should we wait until we decide if%fshould be supported?domfarolino commentedon Jul 11, 2023
Thanks for following-up on this and reminding be about this thread. I'm trying to figure out what action needs to be taken based on the desired result here. Years ago Chrome would output
NaNfor BigInts with the%dformat specifier as the OP points, out which is obviously undesirable. Since then,parseInt()has been given support for BigInt, and Chrome follows the spec by outputting exactly whatparseInt()/parseFloat()would output on BigInts for the%d/%fspecifiers respectively. So if we're OK with this behavior & the spec, then no action needs to be taken — we get this result for free.However, Firefox and Safari seem to have prettier outputs by actually listing all the integers without scientific notation (and Safari even puts commas in the right places etc.). If we want this special pretty output for BigInts, then I think we need to add the special case for
BigIntto the%dand%ispecifiers in Formatter as Domenic suggested earlier. I'm fine with this; it seems like a good outcome and mostly matches what two browsers are doing today. I imagine the special case would just consist of a call toBigInt::toString(), which just returns the concatenation of all digits in the BigInt, without the complicated scientific notation stuff thatNumber::toString()has.Does this sound right to everyone, and does anyone have strong opinions on just delegating to
parseInt()etc., vs creating special pretty output without scientific notation? I'm just trying to catch up on this thread and make sure we're all on the same page, since it should be pretty easy to resolve this issue.terinjokes commentedon Jul 11, 2023
As an alternative , we could specify
%iand%dprint the result of converting a BigInt to Number and formatting like normal (it sounds like Chrome might be doing this already). We could add%gto format the BigInt with full precision, and%ethat you specifically want the scientific notation?domfarolino commentedon Jul 11, 2023
Doesn't the spec already do this? Since we don't special-case anything now, the spec will just call %parseInt()% on BigInts for the
%dand%ispecifiers, which I think is the same result as callingparseInt(bigIntFoo)(Chrome appears to do this).So I guess I'm trying to figure out if we agree that the current spec just passes BigInts to
%parseInt()%, and then after that we can figure out if we want to go a step further by spec'ing the special-casing that Firefox and Safari appear to do.terinjokes commentedon Jul 11, 2023
I think the behavior of going through
%parseInt()%as Chrome does is the correct behavior. Instead of changing how%dand%iwork to special case the Firefox and Safari behavior, the alternative is to add a new specifier for "Big" types.domfarolino commentedon Jul 11, 2023
Right. I'm personally a fan of less specifiers and instead special-casing BigInt support for
%dand%i, since those are just the canonical integer specifiers, and big integers are indeed integers, just... big.terinjokes commentedon Jul 11, 2023
sprintfalready has formatters for larger precision, and adding them wouldn't change the meaning of the existing formatters (and potentially break anyone expecting the current Chrome format).Also, what's the status of BigDecimal? If it were to be added, would we have to add another special case?
domfarolino commentedon Jul 11, 2023
BigDecimal is stage 1 apparently: https://github.com/tc39/proposal-decimal#ecma-tc39-javascript-decimal-proposal. I guess I was just assuming we could squeeze it into the
%fspecifier should the time come. It is true that other languages provide additional syntax to specify precision, but it seems that's usually provided in addition to a specifier like%d,%i, or%f, as opposed to a new specifiers altogether.terinjokes commentedon Jul 11, 2023
And you could continue using those, you'd just get the behavior of
%parseInt()%and%parseFloat()%as requested. I can be convinced otherwise, but I'd hate to change the existing meanings, which are currently very clear of what will happen.