Bug #12780

BigDecimal#round returns different types depending on argument

Added by Gat (Dawid Janczak) almost 4 years ago. Updated 5 months ago.

Target version:
ruby -v:
ruby 2.4.0dev (2016-09-21 trunk 56199) [x86_64-linux]


BigDecimal#round returns Integer when no arguments are given and BigDecimal otherwise. I would have assumed the result to always be BigDecimal.'12.34').round # => 12 (Integer)'12.34').round(0) # => 12 (BigDecimal)

Attached is a patch with possible fix.

I found a similar issue to this one (, but it's in Japanese. If this should be rejected as well could someone provide an explanation in English please? Also in that case documentation should be changed as it clearly states that the result should be BigDecimal: "Round to the nearest integer (by default), returning the result as a BigDecimal."


bigdecimal_round.diff (969 Bytes) bigdecimal_round.diff Gat (Dawid Janczak), 09/21/2016 10:47 AM

Related issues

Related to Ruby master - Feature #13420: Integer#{round,floor,ceil,truncate} should always return an integer, not a floatClosedstomar (Marcus Stollsteimer)Actions

Updated by noahgibbs (Noah Gibbs) almost 4 years ago

The Japanese issue appears to be saying that there's a problem in RubySpec that will need to be fixed, and that fixing it is a problem with (I think?) early 1.9 compatibility.

Updated by shyouhei (Shyouhei Urabe) almost 4 years ago

  • Assignee set to mrkn (Kenta Murata)
  • Status changed from Open to Assigned

Updated by mrkn (Kenta Murata) almost 4 years ago

Float#round returns Fixnum value when the argument is 0 or omitted.

irb(main):005:0> 12.34.round.class
=> Fixnum
irb(main):006:0> 12.34.round(0).class
=> Fixnum

If we will fix BigDecimal#round, we should change the return value for the case of the argument 0 is supplied.

Updated by Gat (Dawid Janczak) almost 4 years ago

Good point, I didn't catch that. If it was up to me I'd rather have Float#round always return Float as well for consistency. I could work on a patch for that too if you agree.

Updated by mrkn (Kenta Murata) almost 4 years ago

We need matz's approval to change Float#round.

Updated by mrkn (Kenta Murata) almost 4 years ago

  • Assignee changed from mrkn (Kenta Murata) to matz (Yukihiro Matsumoto)

Updated by shyouhei (Shyouhei Urabe) over 3 years ago

We (mainly mrkn and matz) discussed why Fixnum#round returns Integer today. The answer is because (unlike other languages, namely C's round(3)) in ruby we can safely store all possible return value that round can theoretically generate, in Integer.

BigDecimal#round's returning BigDecimal instance sounds nice. But matz said he need to think a while for this historic Float behaviour.


Updated by mrkn (Kenta Murata) over 3 years ago

  • Related to Feature #13420: Integer#{round,floor,ceil,truncate} should always return an integer, not a float added

Updated by matz (Yukihiro Matsumoto) 5 months ago

#round with the argument less than 1 (n < 1) should return Integer value.


Also available in: Atom PDF