-
-
Notifications
You must be signed in to change notification settings - Fork 727
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 Issue 20288 - std.format with separator and double causes RangeError #7222
Conversation
Thanks for your pull request, @burner! Bugzilla references
Testing this PR locallyIf you don't have a local development environment setup, you can use Digger to test this PR: dub fetch digger
dub run digger -- build "master + phobos#7222" |
Please put the issue title in the commit/PR title, it's impossible to know what "Fix Issue 20288" means without further action. |
35e4b91
to
4bf038e
Compare
This should help -> #7226 (Azure 10 parallel boxes and thus drastically faster start times). |
e58956d
to
bba4b0d
Compare
Shouldn't "-nan" not exist at all? I'm aware, that there are several ways to express nans in the IEEE standard, but I always thought, that D does not distinguish between them and therefore should still output "nan" instead of "-nan" when the sign bit of a nan is set. I'd like to point to issue 19878 which questions the result "-nan" when using writeln. Is there anything official about using -nan or not? I was not able to find anything useful. |
@berni44 I looked at the standard. Section 6.3 of 754 2008 states that the standard does not interpret the sign bit of NaNs, but some operation specify it. IMHO phobos should therefore display the sign. |
rikki cattermole wrote in the Forum in a related thread, that the behaviour of printf is the baseline. According to this -nan is correct and issue 19878 should be marked "invalid". |
printf on which platfrom, win32 win64, glibc, bsd? they all do things differently. |
Shouldn't that be covered by the C standard? |
I don't have the latest standard at hand, but in the latest publicly available one on page 312 it states that
The phrase implementation-defined appears quite a lot in the paragraph. edit: windows does some really strange things. "1.#INF" is a thing More interesting is footnote 277
I therefore think that the implemented behavior of this PR is "correct" in that it makes all platforms act as linux 64bit. |
Interesting. So printf and the C documentation is not really a reliable source... Maybe we (= D community) have to define ourselves, what format() should do and clearly document that. Looks like lot of work... |
eventually yes, but not in this PR. This PR fixes a crash and makes a minor thing behave equal across all platforms. Doing the thing you mentioned, would firstly require phobos to have its own float formatting. Currently we call snprintf. But again, the this PR does a tiny narrow thing. And shouldn't grow to do all that. |
Yes, I agree. In my oppinion, this PR can be merged. Beyond this PR, for me the question is, what's better: Do more of such corrections or provide a complete rewrite of formattedWrite and Co. using regex for parsing the format string, providing our own float formatting and so on. When looking into bugzilla, there are lots of bugs in here and correcting them might be more work than a sound rewrite. |
I think doing our own formatImpl from float/double/real to string would be pretty good already. edit: |
Having had a closer look at the files, I don't understand how the changes in std.conv are related to this bug. |
windows 32 is doing some really crazy stuff with floats, these changes just add some sanity checks. |
and std.conv.to!string( some_float ) uses std.format |
std.format with separator and double causes RangeError trying to find the win32 bug windows nan -nan fix harder workaround name clash fix moving some stuff around making it shorter oh win32_64 what are you doing to me and another try some windows special case and another and again removed some duplicated code make it compile again some debug output I need a win32_64 box and again better infos finding the failing test something strange is going on getting closer I got it maybe less output I think I understand now tighter code making the commit nicer removed an import undoing some debug changes removed an unneeded test
bba4b0d
to
2b2ed40
Compare
wstring ws = to!wstring(a); | ||
assert(ws == "42"w, to!string(ws)); | ||
dstring ds = to!dstring(a); | ||
assert(ds == "42"d, to!string(ds)); |
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.
Is this change necessary?
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 would say yes, while working on std.format this broke and I couldn't see the assert inputs. So this will help the next one person who gets gray hair looking at std.format!double.
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.
Thanks for clarifying, I actually missed that you added the inputs as second argument to the asserts.
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.
no worries, thanks for taking an interest.
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.
Maybe checkaction=context should be enabled for DRuntime (and other repos) unittest builds
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.
yes, please
We have discussed yesterday performance issue with float --> string conversion. The default implementation in libC is painfully slow. PyPy is 2x faster (!!) because they have their own implementation. Something like this in Phobos would be welcome: https://www.reddit.com/r/ProgrammingLanguages/comments/930pch/ryu_a_new_algorithm_to_quickly_convert_floating/ |
@dejlek not only that, but also the usage of libC is making format fundamentally not pure. |
@dejlek Thank for pointing to the ryu-algorithm. I'll go though it and have a look if I can use/implement it. |
I have done a port of a grisu2 implementation which is quite fast and ctfeable. Search for fpconv_ctfe.d |
I ported the ryu algorithm to D in about an hour, source here: https://github.com/dragon-lang/mar/blob/master/src/mar/ryu.d |
Meanwhile I read through the paper on ryu. I may be wrong, but I think this algorithm is not useful for this task, for two reasons: a) The goal is slightly different to that of printf. While ryu tries to print as few digits as possible, printf prints as much as the format string defines. If that's larger than what ryu computes, the remaining digits will be wrong. |
@UplinkCoder I'll have a look at the grisu implementations to see if it can be used for this task. But due to my time schedule this will probably have to wait one or two weeks. |
@marler8997 I'm working on a more robust (than the original) translation that has everything you need to replace the current implementation Benchmarks suggest a not quite 2x bump in speed; maybe 1.8x. |
@moon-chilled great. You'll have to share it. I only ported the 32-bit version of ryu. For the 64-bit version I wasn't sure if it should be completely separate like the original did, or if I should try to combine them and re-use common code. I look forward to seeing your port. |
Here. (Lookup tables end at line 380--I really need to ctfe those, because they kill compile times.) I was planning on mostly re-using code, once I figured out a good architecture for the 64-bit version. Oh, also - I forgot; it'll probably also get a decent speedboost once I get the 128-bit multiplies in hardware. |
This caused a regression: https://issues.dlang.org/show_bug.cgi?id=20623 |
std.format with separator and double causes RangeError
https://issues.dlang.org/show_bug.cgi?id=20288