Skip to content

RubySpec tests not compatible with IEEE 754 round-nearest-to-even mode #294

@noahgibbs

Description

@noahgibbs

Right now, MRI's sprintf uses IEEE 754 round-nearest-to-even mode (https://en.wikipedia.org/wiki/IEEE_floating_point#Roundings_to_nearest). We're trying to get Float#round to match that behavior (https://bugs.ruby-lang.org/issues/12548). It breaks RubySpec in a few places.

Looking at tests, some are clearly incompatible with that mode. For instance, from core/float/round_spec.rb around line 70:

it "returns rounded values for big values" do
    +2.5e20.round(-20).should   eql( +3 * 10 ** 20  )

This should round to (+2 * 10 ** 20) in that mode, not (+3 * 10 ** 20).

All four test failures below are similar -- they seem to depending on the rounding behavior of various types not following IEEE 754 round-nearest-to-even.

Here's Nobuyoshi Nakada's test output when using a local implementation of that mode:

1)
Float#round returns rounded values for big values FAILED
Expected 200000000000000000000
to have same value and type as 300000000000000000000

spec/rubyspec/core/float/round_spec.rb:70:in `block (2 levels) in <top (required)>'
spec/rubyspec/core/float/round_spec.rb:3:in `<top (required)>'

2)
Integer#round returns itself rounded if passed a negative value FAILED
Expected 200
 to have same value and type as 300

spec/rubyspec/core/integer/round_spec.rb:22:in `block (2 levels) in <top (required)>'
spec/rubyspec/core/integer/round_spec.rb:4:in `<top (required)>'

3)
Rational#round with no arguments (precision = 0) returns the truncated value toward the nearest integer FAILED
Expected 0
 to equal 1

spec/rubyspec/shared/rational/round.rb:17:in `block (3 levels) in <top (required)>'
spec/rubyspec/core/rational/round_spec.rb:3:in `<top (required)>'

4)
Time#strftime rounds an offset to the nearest second when formatting with %z FAILED
Expected "+01:01:04"
 to equal "+01:01:05"

spec/rubyspec/core/time/strftime_spec.rb:50:in `block (2 levels) in <top (required)>'
spec/rubyspec/core/time/strftime_spec.rb:7:in `<top (required)>'

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