странное поведение при сравнении плавающих точек в rspec - PullRequest
5 голосов
/ 05 июня 2011

3-й из следующих тестов не пройден:

  specify { (0.6*2).should eql(1.2) }
  specify { (0.3*3).should eql(0.3*3) }
  specify { (0.3*3).should eql(0.9) } # this one fails

Почему это? Это проблема с плавающей запятой или проблема с рубином или rspec?

Ответы [ 2 ]

12 голосов
/ 05 июня 2011

По состоянию на rspec-2.1

specify { (0.6*2).should be_within(0.01).of(1.2) }

До этого:

specify { (0.6*2).should be_close(1.2, 0.01) }
8 голосов
/ 05 июня 2011

Не сравнивайте числа с плавающей запятой для равенства

Проблема заключается в том, что ни 0,3, ни 0,9 не имеют точного представления 1 в формате с плавающей запятой, и поэтому при умножении 0,3 * 3вы получаете число, очень, очень близкое к 0,9, которое округляется до 0,9 для печати, но не 0,9.

И ваша постоянная 0,9 также не точно равна 0,9, и эти два числаочень немного отличается.

Использование точных сравнений равенства для чисел с плавающей запятой обычно является ошибкой на любом языке.


1.Все целые числа примерно до 2 52 имеют точные представления FP, но дроби состоят из последовательности 1/2 n членов, Большинство десятичных дробей строк повторяются в базе 2.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...