Bug #585

BigDecimal#remainder is not correct with small divisors

Added by Pete Bacon Darwin over 6 years ago. Updated almost 4 years ago.

[ruby-core:18796]
Status:Closed
Priority:Normal
Assignee:Yukihiro Matsumoto
ruby -v:- Backport:

Description

=begin
require 'bigdecimal'

# According to the documentation: BigDecimal#remainder is BigDecimal#modulus minus the value divided by, if values have opposite sign

@mixed = BigDecimal("1.23456789")
@pos_int = BigDecimal("2E5555")
@neg_int = BigDecimal("-2E5555")
@pos_frac = BigDecimal("2E-9999")
@neg_frac = BigDecimal("-2E-9999")

# One would expect that
puts @mixed.remainder(@neg_frac) == (@mixed % @neg_frac) - @neg_frac # 0.2E-9998
puts @pos_int.remainder(@neg_frac) == (@pos_int % @neg_frac) - @neg_frac # 0.2E-9998
puts @neg_frac.remainder(@pos_int) == (@neg_frac % @pos_int) - @pos_int # -0.2E-9998
puts @neg_int.remainder(@pos_frac) == (@neg_int % @pos_frac) - @pos_frac # -0.2E-9998

# But in actual fact
puts @mixed.remainder(@neg_frac) == BigDecimal("0.0")
puts @pos_int.remainder(@neg_frac) == BigDecimal("0.0")
puts @neg_frac.remainder(@pos_int) == BigDecimal("-0.2E-9998")
puts @neg_int.remainder(@pos_frac) == BigDecimal("-0.0")

# This appears to be due to some premature rounding optimization in divmod
=end

History

#1 Updated by Shyouhei Urabe about 6 years ago

  • Assignee set to Yukihiro Matsumoto

=begin

=end

#2 Updated by Marc-Andre Lafortune over 5 years ago

  • Status changed from Open to Closed
  • % Done changed from 0 to 100

=begin
Applied in changeset r25020.
=end

#3 Updated by Marc-Andre Lafortune over 5 years ago

  • Category set to doc
  • Status changed from Closed to Open
  • ruby -v set to -

=begin
Documentation was incorrect.

x.remainder(y) = x - (x/y).truncate

Among other things, if y divides x, then modulo == remainder == 0 no matter what the signs involved.
=end

#4 Updated by Marc-Andre Lafortune over 5 years ago

  • Status changed from Open to Closed

=begin

=end

Also available in: Atom PDF