-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[SR-3131] String(someDouble) incorrectly switches to scientific notation for large integers #45719
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
Comments
Using scientific notation is not really a bug here. The bug is simply that the final value has been printed with too few digits. This is the same root issue as #42728, swiftlang/swift-corelibs-foundation#4412, and several others. |
Kevin: Do you agree this is a duplicate of #42728? |
If we take it as a given that using scientific notation is fine and the only problem is it's using it too early, then yes. However, I'm not sure I agree that using scientific notation in general isn't a problem. I'm concerned about the effect this might have when trying to produce a specific machine-readable output based on data that contains floating-point numbers. I suppose I'm willing to say that using scientific notation is ok, but we should have a mechanism that guarantees a non-scientific-notation string representation of a floating-point value as well (and |
The description and debugDescription properties explicitly try to produce short strings, so they will switch between scientific and decimal forms depending on the value. If scientific form is unacceptable for your application, then description and debugDescription are not appropriate. |
Since |
It sounds like my forthcoming change for #42728 will address your concerns. It adds no new API to the stdlib (so it will not give you a way to request non-exponential format) but it does fix the current inconsistent and inaccurate formatting. |
Please try this again with Swift master. I believe #15474 might have addressed your concern here. |
@tbkka I just tested with the |
Thanks for checking that. The hard part is to determine the exact criteria that should be used. Once we can settle that, actually implementing it won't be hard. One possible criteria is shortness of the output. Certainly, your specific example is shorter without the exponential notation. For reference, here is the code that decides between exponential and decimal formatting. As you can see, it currently only considers the base-10 exponent. That decision could be made more sophisticated, of course. Any changes would affect these tests. |
Shortness is important, but clearly not the most important, because |
Would you expect Would it make sense to just change the existing cutoff to |
Ok, let me rephrase. By "exactly represented as a |
In terms of unit tests, then, you would like to see the following for Float, Double, and Float80? expectDescription("16777216.0", Float(1 << 24))
expectDescription("1.6777218e+7", Float(1 << 24).nextUp)
expectDescription("9007199254740992.0", Double(1 << 53))
expectDescription("9.007199254740994e+15", Double(1 << 53).nextUp)
// `Float80(1 << 62) * 4.0` avoids integer overflows
expectDescription("18446744073709551616.0", Float80(1 << 62) * 4.0)
expectDescription("1.8446744073709551618e+19", (Float80(1 << 62) * 4.0).nextUp) If you could verify these values, I'd greatly appreciate. It will be another week or so before I can get the PR together. |
Those values look good to me. I'd probably also add tests for the negative versions. |
Please see #15805. |
Thanks for doing this! |
The fix in #15805 has been merged. |
old comment:
no! - äh yes! ... you are right, it shouldn't ;-) |
Environment
Apple Swift version 3.0.1 (swiftlang-800.0.58.6 clang-800.0.42.1)
Target: x86_64-apple-macosx10.9
Additional Detail from JIRA
md5: 1b1ce68db85995c555c91183810f4d55
duplicates:
Issue Description:
The string representation of a
Double
incorrectly uses scientific notation for large integers that are still within the range that can be precisely represented using a Double. This happens at some point between1 << 49
and1 << 50
.Example:
The text was updated successfully, but these errors were encountered: