-
Notifications
You must be signed in to change notification settings - Fork 85
Allow BigDecimal accept Float without precision #314
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
Conversation
8850458 to
8cdf5cd
Compare
| assert_equal(BigDecimal("0.01"), BigDecimal(0.01, Float::DIG + 1)) | ||
| assert_raise_with_message(ArgumentError, "can't omit precision for a Float.") { BigDecimal(4.2) } | ||
| assert_nothing_raised { BigDecimal(4.2) } | ||
| assert_equal(BigDecimal(4.2), BigDecimal('4.2')) |
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.
@mrzasa Could you add more assertions to check many cases, especially for numbers that don't have accurate representations in Float?
Moreover, we must compare two values by assert_in_delta and pass an appropriate value to the delta argument for the original Float value; it should be 0.5ulp.
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 reconsidered how to check here.
I suggest comparing the result of to_f with the original Float value, like this: assert_equal(4.2, BigDecimal(4.2).to_f).
This approach is preferable because it doesn’t depend on the specific decimal representation for a given Float value. I’d like to avoid relying on the particular algorithm used for converting a Float to a BigDecimal.
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.
Adding a same test case as BigDecimal(float, 0) is enough.
But since test for BigDecimal(float, 0) is currently missing, adding both will be nice.
assert_equal(BigDecimal("string representation"), BigDecimal(float_literal_here, 0))
assert_equal(BigDecimal("string representation"), BigDecimal(float_literal_here))
# Just like this one on line 166-168
assert_equal(BigDecimal("0.1235"), BigDecimal(0.1234567, 4))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! I've added the floats test cases
tompng
left a comment
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.
Thank you. looks good 👍
Perhaps some tests for BigDecimal(x, various_number) are missing, some test are too strict.
# this test is too strict
assert_equal(BigDecimal("0.01"), BigDecimal(0.01, Float::DIG + 1))
# because:
BigDecimal(0.07, Float::DIG + 1) #=> 0.7000000000000001e-1but let's consider it a separate issue of test.
|
Is this intentional? DEV (main)> BigDecimal(1.1111111111111129).to_s
"1.111111111111113"
DEV (main)> BigDecimal("1.1111111111111129").to_s
"1.1111111111111129"
DEV (main)> RUBY_VERSION
"3.4.5"
DEV (main)> BigDecimal::VERSION
"3.2.3"
DEV (main)> RUBY_PLATFORM
"x86_64-linux" |
|
@henrik Yes, it's intentional. That's what Float number is. 1.1111111111111129 == 1.111111111111113
#=> true
p 1.1111111111111129
#=> 1.111111111111113
BigDecimal(1.1111111111111129) == BigDecimal(1.111111111111113)
#=> true
p 1.100000000000000123456789
# => 1.1
p BigDecimal(1.100000000000000123456789)
#=> 0.11e1 |
|
@tompng Thank you for clarifying! It still does not seem ideal that I know that this was already the case before if you passed an explicit precision argument ( That said, I don't myself have a use case for BigDecimal with this many decimals – I was just experimenting. |
This is at least a breaking API change and should necessitate a major version bump. I have seen multiple cases of production code that expects For usecases like validation - the new API will allow what would have been considered invalid data to now be considered valid. |
|
Yes, agreed, assuming BigDecimal intends to follow semver. It broke code for us and rails/rails@194ff4c above shows the same thing happening to Rails. |
Make sure that conversion from a Float works consistently with the conversion from a string representing that float.
Current
masterstate:After this changes:
When precision is omitted it's set to
0.Fixes #213
Blocked by #313