From: shevegen@... Date: 2018-01-15T22:25:52+00:00 Subject: [ruby-core:84885] [Ruby trunk Feature#14362] use BigDecimal instead of Float by default Issue #14362 has been updated by shevegen (Robert A. Heiler). > I realize this goes against the 3x3 goal but I think BigDecimal > is preferable over Float for developer happiness. That's an interesting comment. :) You could ask matz whether 3x3 is more important than making life of developers easier. I am not saying that your proposal makes life easier, mind you; I think that matz probably may prefer making life easier/better for people using ruby. And the speed improvements such as 3x3 may come with that secondary focus. (I have not been following all changes in this respect, but I think that if mjit comes, then 3x3 will be achieved mostly already since ruby 2.5.x is already quite a lot faster than 2.0 was). There are some secondary considerations though. Note that I have no real pro of con opinion, but to me, "Float" is easer to remember and use than "BigDecimal". Granted, I do not use it directly (there is no Float.new either), I only use the numbers. But in my mind, I think of 3.5 as float and never as a "big decimal". (Actually, the name big decimal is also more limited than float, semantic-wise. It would insinuate a big float right? Not a small float necessarily...) Anyway, I don't want to discourage you in the slightest. I guess you have to see what matz says on it. > A change this significant would likely target Ruby 3 Agreed. Matz wrote somewhat that backwards-incompatible changes should go into 3.x preferentially. For the speed penalty, if there is one, I think it would be nice if someone could add a table to show the differences (if there are any). ---------------------------------------- Feature #14362: use BigDecimal instead of Float by default https://bugs.ruby-lang.org/issues/14362#change-69592 * Author: AaronLasseigne (Aaron Lasseigne) * Status: Open * Priority: Normal * Assignee: * Target version: ---------------------------------------- When writing a decimal the default type assigned is `Float`: ```ruby > 1.2.class => Float ``` This is great for memory savings and for application speed but it comes with accuracy issues: ```ruby > 129.95 * 100 => 12994.999999999998 ``` Ruby's own `BigDecimal` docs say: > Decimal arithmetic is also useful for general calculation, because it provides the correct answers people expect���whereas normal binary floating point arithmetic often introduces subtle errors because of the conversion between base 10 and base 2. What if `BigDecimal` was moved into the Ruby core and made the default for numbers like `1.2`? ```ruby > 1.2.class => BigDecimal ``` I realize this goes against the 3x3 goal but I think `BigDecimal` is preferable over `Float` for developer happiness. I've seen lots of developers stumble when first learning about the pitfalls of `Float`. I've see test suites where a range is tested for because of answers like `12994.999999999998` instead of `12995.0`. At one point trading accuracy for performance made sense. I'm not sure that's still the case today. Right now a decimal generates the faster and less accurate `Float`. Developers have to opt-in to the slower but safer `BigDecimal` by manually requesting a `BigDecimal`. By flipping this we default to the safer version and ask developers to opt-in to the faster but less accurate `Float` if needed. ```ruby > 1.2.class => Decimal > Float.new('1.2') => 1.2 ``` There could also be a shorthand for float where the number is followed by an `f` (similar to Rational). ```ruby 1.2f # => Float ``` The change would help "provide the correct answers people expect". The change would be mostly seamless from an interface standpoint. The only methods on `Float` and not on `BigDecimal` appear to be `rationalize`, `next_float`, and `prev_float`. I suspect those methods are rarely used. The increased accuracy seems unlikely to cause code issues for people. The two largest downsides that I can come up with are speed and display. I'm not sure what kind of hit is taken by handling all decimals as `BigDecimal`. Would an average Rails application see a large hit? Additionally, the display value of `BigDecimal` is engineering notation. This is also the default produced by `to_s`. It's harder to read and might mess up code by displaying things like "0.125e2" instead of "12.5". Certainly the default produced by `to_s` could change to the conventional floating point notation. A change this significant would likely target Ruby 3 so there would be time to make some changes like adding a `BigDecimal#rationalize` method or changing the default output of `BigDecimal#to_s`. Thank you for considering this. -- https://bugs.ruby-lang.org/ Unsubscribe: