-
Notifications
You must be signed in to change notification settings - Fork 21
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
BigDecimal.isValidDouble behaves unexpectedly #6699
Comments
Imported From: https://issues.scala-lang.org/browse/SI-6699?orig=1 |
Sergii Zashchelkin (sergz72) said (edited on Dec 6, 2012 11:09:27 AM UTC): I have no rights to commit to Scala git repository, so please find below the working code for BigDecimal.isValidDouble: def isValidDouble = { |
@acruise said: The proper procedure in this case is to fork, create a branch, fix it in your branch, add some tests, make sure the main Scala tests pass as well as your new ones, then submit a pull request. I'd be happy to review your contribution once it's up on github. :) |
Sergii Zashchelkin (sergz72) said: I've submitted a pull request for #6699 fix. Thanks, |
@adriaanm said: |
@Ichoran said: This keeps you consistent with the printed-out version of your doubles, but it doesn't keep you consistent in any other way. All your internal numbers may be randomly different from each other (after a bit of math). I recommend switching to purely non-string-based conversions wherever possible. Here's an example of the problem as it currently exists: val l = (1L << 62L)
val d = l.toDouble
l == d // true
BigDecimal(l) == BigDecimal(d) // false?!
l == BigDecimal(l) // true
d == BigDecimal(d) // false?! To recover transitivity of equals, it is necessary to switch away from taking the Unfortunately, if people are relying upon this strange string conversion thing for BigDecimal, changing it could break e.g. financial software. That's generally something you don't want broken. |
@adriaanm said: |
@adriaanm said: |
@adriaanm @Ichoran why it was closed without a fix?
|
Not sure what's going on the PR description mentioned this bug as fixed: scala/scala#3316 |
I suppose it's actually down to the choice of the number, and explained by https://stackoverflow.com/questions/21895756/why-are-floating-point-numbers-inaccurate
|
|
Maybe this will make things clear:
Innocent-looking things like |
(Sorry, I can't create anything less than a BLOCKER bug report.)
I would expect that creating a
BigDecimal
from aDouble
would produce aBigDecimal
that returnsBigDecimal.isValidDouble = true
, e.g.(Note: in the following, we don't care about loss of precision when inputting a double literal, the fact that whatever is stored is represented as a
Double
is enough)println(BigDecimal(10.1: Double).isValidDouble) // false
but the above actually prints
false
.WORKAROUND: I use my own replacement for
.isValidDouble
which is to create a new BigDecimal from the output of atoDouble
conversionval sd = BigDecimal(10.1: Double)
println(sd == BigDecimal(sd.toDouble)) // true
If the
BigDecimal
->Double
conversion loses precision, then this test fails. e.g.val ssd = BigDecimal("1.0000000000000003")
println(ssd == BigDecimal(ssd.toDouble)) // false
as expected.
The text was updated successfully, but these errors were encountered: