[#109403] [Ruby master Feature#18951] Object#with to set and restore attributes around a block — "byroot (Jean Boussier)" <noreply@...>

Issue #18951 has been reported by byroot (Jean Boussier).

23 messages 2022/08/01

[#109423] [Ruby master Misc#18954] DevMeeting-2022-08-18 — "mame (Yusuke Endoh)" <noreply@...>

Issue #18954 has been reported by mame (Yusuke Endoh).

10 messages 2022/08/04

[#109449] [Ruby master Feature#18959] Handle gracefully nil kwargs eg. **nil — "LevLukomskyi (Lev Lukomskyi)" <noreply@...>

Issue #18959 has been reported by LevLukomskyi (Lev Lukomskyi).

27 messages 2022/08/08

[#109456] [Ruby master Bug#18960] Module#using raises RuntimeError when called at toplevel from wrapped script — "shioyama (Chris Salzberg)" <noreply@...>

Issue #18960 has been reported by shioyama (Chris Salzberg).

15 messages 2022/08/09

[#109550] [Ruby master Feature#18965] Further Thread::Queue improvements — "byroot (Jean Boussier)" <noreply@...>

Issue #18965 has been reported by byroot (Jean Boussier).

14 messages 2022/08/18

[#109575] [Ruby master Bug#18967] Segmentation fault in stackprof with Ruby 2.7.6 — "RubyBugs (A Nonymous)" <noreply@...>

Issue #18967 has been reported by RubyBugs (A Nonymous).

10 messages 2022/08/19

[#109598] [Ruby master Bug#18970] CRuby adds an invalid header to bin/bundle (and others) which makes it unusable in Bash on Windows — "Eregon (Benoit Daloze)" <noreply@...>

Issue #18970 has been reported by Eregon (Benoit Daloze).

17 messages 2022/08/20

[#109645] [Ruby master Bug#18973] Kernel#sprintf: %c allows codepoints above 127 for 7-bits ASCII encoding — "andrykonchin (Andrew Konchin)" <noreply@...>

Issue #18973 has been reported by andrykonchin (Andrew Konchin).

8 messages 2022/08/23

[#109689] [Ruby master Misc#18977] DevMeeting-2022-09-22 — "mame (Yusuke Endoh)" <noreply@...>

Issue #18977 has been reported by mame (Yusuke Endoh).

16 messages 2022/08/25

[#109707] [Ruby master Feature#18980] Re-reconsider numbered parameters: `it` as a default block parameter — "k0kubun (Takashi Kokubun)" <noreply@...>

Issue #18980 has been reported by k0kubun (Takashi Kokubun).

40 messages 2022/08/26

[#109756] [Ruby master Feature#18982] Add an `exception: false` argument for Queue#push, Queue#pop, SizedQueue#push and SizedQueue#pop — "byroot (Jean Boussier)" <noreply@...>

Issue #18982 has been reported by byroot (Jean Boussier).

11 messages 2022/08/29

[#109773] [Ruby master Misc#18984] Doc for Range#size for Float/Rational does not make sense — "masasakano (Masa Sakano)" <noreply@...>

Issue #18984 has been reported by masasakano (Masa Sakano).

7 messages 2022/08/29

[ruby-core:109695] [Ruby master Feature#18979] Kernel#sprintf formatting BigDecimal without the loss of precision

From: "kstrukov (Kostiantyn Striukov)" <noreply@...>
Date: 2022-08-25 15:31:12 UTC
List: ruby-core #109695
Issue #18979 has been reported by kstrukov (Kostiantyn Striukov).

----------------------------------------
Feature #18979: Kernel#sprintf formatting BigDecimal without the loss of precision
https://bugs.ruby-lang.org/issues/18979

* Author: kstrukov (Kostiantyn Striukov)
* Status: Open
* Priority: Normal
----------------------------------------
Recently I stumbled upon a quirk with `Kernel#sprintf`'s `f` modifier behavior with `BigDecimal`. It seems to be not documented neither in `Kernel` documentation nor in `BegDecimal` one. Also, I didn't find previous discussions about it here.

The "problem" is that formatting BigDecimals with `sprintf` with `f` field type leads to BigDecimal implicit conversion to a float, and to the loss of precision as the result:
```ruby
require "bigdecimal"

b3 = BigDecimal(1).div(BigDecimal(3), 3) #=> 0.333e0
b50 = BigDecimal(1).div(BigDecimal(3), 50) #=> 0.33333333333333333333333333333333333333333333333333e0

sprintf "%.50f" % b3 #=> "0.33300000000000001820765760385256726294755935668945"
sprintf "%.50f" % b50 #=> "0.33333333333333331482961625624739099293947219848633"
```
What makes this arguably even more counter-intuitive is the fact that the same `BigDecimal`, converted to `Rational` before formatting, is being handled accurately:
```ruby
sprintf "%.50f" % b3.to_r #=> "0.33300000000000000000000000000000000000000000000000"
sprintf "%.50f" % b50.to_r #=> "0.33333333333333333333333333333333333333333333333333"
```

I understand that `Rational` is part of the core and `BigDecimal` is not, I [see the difference](https://github.com/ruby/ruby/blob/cb4e2cb55a59833fc4f1f6db2f3082d1ffcafc80/sprintf.c#L794)) and know that the former has it's own API for formatting that preserves the precision. Also, from the architecture point of view the idea that some core feature should be aware of a certain part of the "outer layer" (even if it is a standard library) sounds controversial if not nonsense.

But still, having said that, from the Ruby developer perspective (who in most cases finds stdlib playing nicely with the core), the fact that `BigDecimal` _can_ be accurately converted to `Rational`, `Rational` _can_ be accurately formatted with `sprintf`, but `BigDecimal` _cannot_ be accurately formatted using `sprintf` is quite a subtle thing. 

For the sake of the principle of least surprise, it would be really nice if `Kernel#sprintf` could handle `BigDecimal` on par with `Rational`. If we cannot have this "fixed" (or shouldn't have, from the architecture standpoint or for any other reason), I think this subtlety probably should be explicitly explained in the documentation (at minimum for `BigDecimal`, but maybe for both).



-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>

In This Thread

Prev Next