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

formatUnits always generates trailing .0 #1291

Closed
rstormsf opened this issue Feb 14, 2021 · 10 comments
Closed

formatUnits always generates trailing .0 #1291

rstormsf opened this issue Feb 14, 2021 · 10 comments
Labels
enhancement New feature or improvement. fixed/complete This Bug is fixed or Enhancement is complete and published. minor-bump Planned for the next minor version bump.

Comments

@rstormsf
Copy link

Do I have to remove it manually or is there a flag not to generate it ?

> ethers.utils.formatUnits(10, 1)
'1.0'

I'd love to just get 1 vs 1.0

@ricmoo
Copy link
Member

ricmoo commented Feb 14, 2021

The formatUnits function will always include at least 1 whole digit and 1 fractional digit.

This makes it easier to re-format the string, without needing complex logic. So, for your case you could use ethers.utils.formatUnits(10, 1).split(".")[0].

I suppose digits = 1 is a special case where it would make sense to omit the fractional component and decimal place. I will add it to my list for v6, but v5 can't be changed in this way as some people may rely on the current logic...

@ricmoo ricmoo added the discussion Questions, feedback and general information. label Feb 14, 2021
@ricmoo
Copy link
Member

ricmoo commented Feb 16, 2021

Actually, quick note. in v6, it will do this only when decimals = 0. If you want 1 decimal point, it still makes sense to include it. :)

@ricmoo ricmoo added enhancement New feature or improvement. major-bump Planned for the next major version bump and removed discussion Questions, feedback and general information. labels Feb 17, 2021
@ricmoo
Copy link
Member

ricmoo commented Feb 25, 2021

I've added this to my active todo list for v6, so I'm going to close this here.

Thanks! :)

@ricmoo ricmoo closed this as completed Feb 25, 2021
@ricmoo ricmoo added minor-bump Planned for the next minor version bump. on-deck This Enhancement or Bug is currently being worked on. and removed major-bump Planned for the next major version bump labels Apr 23, 2021
@ricmoo
Copy link
Member

ricmoo commented Apr 23, 2021

Adding this to the next minor bump, actually. :)

@ricmoo
Copy link
Member

ricmoo commented May 20, 2021

This has been addressed in 5.2.0.

Please let me know if you still have any issues. Thanks! :)

@ricmoo ricmoo added fixed/complete This Bug is fixed or Enhancement is complete and published. and removed on-deck This Enhancement or Bug is currently being worked on. labels May 20, 2021
@ricmoo ricmoo closed this as completed May 30, 2021
@lomocc
Copy link

lomocc commented Jan 11, 2023

ethers.utils.formatUnits(ethers.utils.parseUnits('1', 18), 18);
// 1.0

I think display 1 would be better.

just like parseFloat('1.0') = 1.

Even if it is a float number, it can be an integer when there is no fractional part.

@ricmoo
Copy link
Member

ricmoo commented Jan 11, 2023

@lomocc

Keep in mind parseFloat("1.0") does not equal "1", it equals 1, which is an IEEE754 number. When you see it as 1 that is because of IEEE754 stringification logic.

The reason for the string representation for formatUnits to always retain a . is that it makes additional formatting easier to perform without additional if confusion. You can always use .split(".") and be guaranteed to have 2 components, which can then be padded/stripped/etc. as desired, then rejoined.

@lomocc
Copy link

lomocc commented Jan 11, 2023

Keep in mind parseFloat("1.0") does not equal "1", it equals 1, which is an IEEE754 number. When you see it as 1 that is because of IEEE754 stringification logic.

The reason for the string representation for formatUnits to always retain a . is that it makes additional formatting easier to perform without additional if confusion. You can always use .split(".") and be guaranteed to have 2 components, which can then be padded/stripped/etc. as desired, then rejoined.

Thanks for your reply, but I also think we can try it just like toFixed (handle it as a default param = 0):

parseFloat('1.000000000').toFixed() // 1
parseFloat('1.000000000').toFixed(1) // 1.0
parseFloat('1.000000000').toFixed(2) // 1.00
ethers.utils.formatUnits(ethers.utils.parseUnits('1', 18), 18); // 1.0
ethers.utils.formatUnits(ethers.utils.parseUnits('1', 18), 18, shortMode=true); // 1

@icetrust0212
Copy link

icetrust0212 commented Apr 16, 2023

Number(1.0); // 1

@AlissonRS
Copy link

It's not nice being required to .split('.')[0] everywhere in the code.

@Ric couldn't it just be an optional parameter where we define decimal precision expected? Could be "1" by default for backwards compatibility.

Like @lomocc suggested above, but I'd think of something like this:

ethers.utils.formatUnits(ethers.utils.parseUnits('1', 18), 18, 0); // 1
ethers.utils.formatUnits(ethers.utils.parseUnits('1', 18), 18, 1); // 1.0 < default
ethers.utils.formatUnits(ethers.utils.parseUnits('1', 18), 18, 2); // 1.00

Alternatively, instead of fixed precision, the parameter could be "maxPrecision", so:

ethers.utils.formatUnits(ethers.utils.parseUnits('1', 18), 18, 0); // 1
ethers.utils.formatUnits(ethers.utils.parseUnits('1', 18), 18, 1); // 1.0 < default
ethers.utils.formatUnits(ethers.utils.parseUnits('1', 18), 18, 2); // 1.0 (still 1.0 because no extra decimals are required)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or improvement. fixed/complete This Bug is fixed or Enhancement is complete and published. minor-bump Planned for the next minor version bump.
Projects
None yet
Development

No branches or pull requests

5 participants