Skip to content

BigDecimal modulo loses negative zero sign (inconsistent with Float) #440

@ianks

Description

@ianks

Problem

BigDecimal 3.3.0's modulo operation loses negative zero sign when operating with Infinity, inconsistent with Ruby's Float behavior.

Version

require 'bigdecimal'
BigDecimal::VERSION  # => "3.3.0"

Reproduce

require 'bigdecimal'

# Float (correct - preserves sign)
-0.0 % Float::INFINITY           # => -0.0
1.0 / (-0.0 % Float::INFINITY)   # => -Infinity ✓

# BigDecimal (loses sign)
bd_result = BigDecimal('-0.0') % BigDecimal('Infinity')
bd_result                        # => 0.0 (should be -0.0)
bd_result.sign                   # => 1 (should be -1)
1.0 / bd_result.to_f             # => Infinity (should be -Infinity)

Expected Behavior

BigDecimal('-0.0') % BigDecimal('Infinity') should return a BigDecimal with negative zero (sign = -1) to match Float behavior.

Impact

This violates IEEE 754 signed zero semantics:

  • Negative zero is mathematically significant
  • 1.0 / -0.0 should give -Infinity, not +Infinity
  • Causes behavioral differences between Float and BigDecimal for edge cases

Context

BigDecimal v3.3.0 introduced changes to align with Float's modulo/infinity behavior (commit 8ca3249). However, signed zero preservation was not included in this alignment.

Note: BigDecimal correctly preserves negative zero in other contexts (e.g., BigDecimal('-0.0').sign == -1), but the modulo operation specifically loses it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions