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

Partial replace call to snprintf for formating floatingpoint numbers. #7264

Closed
wants to merge 5 commits into from
Closed

Partial replace call to snprintf for formating floatingpoint numbers. #7264

wants to merge 5 commits into from

Conversation

ghost
Copy link

@ghost ghost commented Nov 8, 2019

Because the description of this PR is long and contains diagrams, I put everything into printFloat.pdf.

TL;DR: Read only the abstract.

Still TL;DR: This only replaces the 'f' specifier for float and double. The algorithm is correct, in most cases faster than the old one (some optimizations are still WIP), it implements rounding according to IEEE754 (with a different tie than the old one), but no internationalisation, because that causes a lot of trouble and should be done elsewhere.

@ghost
Copy link
Author

ghost commented Nov 8, 2019

The failure on eBay/tsv-utils is due to the different tie in rounding. This is intentional (I think the new version is better) but might be discussed.

@ghost ghost marked this pull request as ready for review November 8, 2019 19:33
@ghost ghost requested a review from andralex as a code owner November 8, 2019 19:33
Copy link
Member

@UplinkCoder UplinkCoder left a comment

Choose a reason for hiding this comment

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

this has not gotten enough testing. Try double.max (1.0/3.0) inf -inf machine epsilon pi 2pi and a few other well known constants, at the very least.

@p0nce
Copy link

p0nce commented Nov 9, 2019

There are only 2^32 float so you could do an exhaustive check there. (I don't mean in a commited unittest)

@ghost
Copy link
Author

ghost commented Nov 9, 2019

There are only 2^32 float so you could do an exhaustive check there. (I don't mean in a commited unittest)

I did that allready with two different format strings - see pdf.

@ghost
Copy link
Author

ghost commented Nov 9, 2019

this has not gotten enough testing. Try double.max (1.0/3.0) inf -inf machine epsilon pi 2pi and a few other well known constants, at the very least.

inf (line 7743/7744) and epsilon (line 7788) are allready in the unittests. I'll add max and some special constants.

@dlang-bot
Copy link
Contributor

dlang-bot commented Nov 10, 2019

Thanks for your pull request and interest in making D better, @berni44! We are looking forward to reviewing it, and you should be hearing from a maintainer soon.
Please verify that your PR follows this checklist:

  • My PR is fully covered with tests (you can see the coverage diff by visiting the details link of the codecov check)
  • My PR is as minimal as possible (smaller, focused PRs are easier to review than big ones)
  • I have provided a detailed rationale explaining my changes
  • New or modified functions have Ddoc comments (with Params: and Returns:)

Please see CONTRIBUTING.md for more information.


If you have addressed all reviews or aren't sure how to proceed, don't hesitate to ping us with a simple comment.

Bugzilla references

Auto-close Bugzilla Severity Description
9889 normal Incorrect rounding on floating value formatting
20320 normal format("%f") leeds to wrong output
20371 normal std.format limited to 500 characters for floats

Testing this PR locally

If you don't have a local development environment setup, you can use Digger to test this PR:

dub run digger -- build "master + phobos#7264"

@ghost
Copy link
Author

ghost commented Nov 10, 2019

added more unittests (and sorry @UplinkCoder I overlooked, that the eps-tests where float not double, added the double tests now)

@ghost ghost requested a review from UplinkCoder November 14, 2019 12:07
@ghost
Copy link
Author

ghost commented Nov 17, 2019

While working on %a I discovered a bug in the implementation of the rule "Round to nearest, ties away from zero". It was actually "Round to nearest, ties up", which is different for negative numbers. I fixed this (and the wrong unittests) now.

@p0nce
Copy link

p0nce commented Nov 17, 2019

Just to say that this seems like fantastic work if the PDF says the truth. For localization I also think it fixes more undiscovered bugs than it breaks (there are more people unaware of localization using snprintf unknowingly, than people using D and relying on printf localization)

@ghost
Copy link
Author

ghost commented Nov 17, 2019

Just to say that this seems like fantastic work if the PDF says the truth.

Thanks for compliment! :-) If you want to check the content of the pdf: I put all needed functions in the repo and would be happy, if someone could verify the results...

@ghost
Copy link
Author

ghost commented Dec 4, 2019

Changed tie for rounding to the current behaviour. I'll address this later in a separate PR. I also added improvements suggested in PR #7285.

@ghost
Copy link
Author

ghost commented Dec 4, 2019

Does anyone has an idea, what this 32bit-windows compiler bug is about?

@ghost
Copy link
Author

ghost commented Dec 7, 2019

Merged everything and run the external tests (for %f and %a): all passed.

I changed bias from long to int, because I guess, this is the reason, why win32 crashed after the last change (had something similar resently in an other PR, as far as I remember). Let's see...

I also unified the tests for large precissions. I think there is no merit in having a string literal, which essentially consists of 1000 zeros in the source code. For checking the bug, it's sufficient to just check the length.

@ghost
Copy link
Author

ghost commented Jan 14, 2020

Fixed problem with global import of FloatingPointControl. See #7346 for more details.

@ghost
Copy link
Author

ghost commented Feb 7, 2020

Fixed the merge conflicts.

std/format.d Outdated
Comment on lines 7130 to 7134
return printFloatA(val, f, rm, sgn, exp, mnt, is_upper);
case 'e': case 'E':
return printFloatE(val, f, rm, sgn, exp, mnt, is_upper);
case 'f': case 'F':
return printFloatF(val, f, rm, sgn, exp, mnt, is_upper);
Copy link
Contributor

Choose a reason for hiding this comment

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

Following the success of the float zero factorisation, I'm beginning to think that the best way to organise the printing is not by format specifier (%a,%f,%g,%e) but by "category" (for want of a better term), i.e.

  • inf/nan (handled above),
  • Algorithm A: For large exponents (exp >= T.mant_dig)
  • Algorithm B: For small exponents (exp < T.mant_dig - 61)
  • Algorithm C: For exponents close to 0. (already done)

Since there seems to be much more in common between the different ranges of numbers than there is between the different format specifiers.

@rainers
Copy link
Member

rainers commented Feb 21, 2020

Rebased and adapted to not allocate as in #7393

@thewilsonator
Copy link
Contributor

Implemented in another PR

@rainers
Copy link
Member

rainers commented Feb 28, 2020

Implemented in another PR

I'm not following phobos development closely, but which one would that be?

@thewilsonator
Copy link
Contributor

#7393 No?

@rainers
Copy link
Member

rainers commented Feb 28, 2020

#7393 No?

#7285 and #7318 implemented "%a" and "%e" formatting, and #7393 removed some introduced allocations. This PR implements "%f" formatting. I only rebased it and modified it to not introduce allocations again.

@rainers rainers reopened this Feb 28, 2020
@ljmf00
Copy link
Member

ljmf00 commented Oct 18, 2020

Do you anyone can push this forward @rainers or @thewilsonator ? This PR is crucial to have purity on format for floating point.

@RazvanN7
Copy link
Collaborator

Closing this in favor of #7757

@RazvanN7 RazvanN7 closed this Jan 25, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants