RSpec 3 имеет BigDecimal эк:
x.should eq(y)
expect(x).to eq(y)
Если вы сравниваете BigDecimal в Float, быть в курсе точность может повлиять на сравнение.
Вы можете использовать это:
x.should be_within(delta).of(y)
expect x.to be_within(delta).of(y)
Если вы сравниваете два числа BigDecimal, которые имеют разные Precisions, следует помнить, что эти цифры могут показать результаты, отличные от inspect
, а также от hash
в зависимости от вашей платформы и что версию Ruby BigDecimal, которую вы запускаете.
Например, это может произойти:
BigDecimal.new("2").hash == BigDecimal.new("2.0").hash
=> false
Ваш вывод показывает, что ваши BigDecimal строковые представления немного отличаются.
Вот что означают ваши строки:
- Часть 1 является адрес объекта.
- Часть 2 - это числовое значение, представленное в виде строки.
- Часть 3 - это количество значащих цифр, а затем максимальное количество значащих цифр.
Ваш вывод показывает, что ваши строки имеют разные адреса объектов, одинаковые значения числа (т. Е. Часть 2), одинаковые значащие цифры (первое число в части 3), но разные числа максимальных значащих цифр.
На ваш вопрос, используя RSpec 2 и сравнивая хеши BigDecimal
, вы можете решить вашу проблему, используя сопряжение rspec be_within
.
Обратите внимание, что Рубин BigDecimal
числа и Float
числа как числа с плавающей точкой:
Вы можете увидеть представление с плавающей запятой в десятичной BigDecimal
, делая это:
require 'bigdecimal'
x=BigDecimal.new(100)
=> #<BigDecimal:7f8e62038570,'0.1E3',9(27)>
мантиссы часть «0.1», а показатель часть «E3».
Обратите внимание, что это типичная Ruby MRI/KRI VM.Реализации могут отличаться от других Ruby VM, таких как JRuby, потому что Java имеет свой собственный код bignum.
При сравнении двух разных типов чисел с плавающей запятой, таких как BigDecimal и Float, вы можете получить результаты, которые могут показаться противоречивыми, поскольку типы используют разные базы (десятичные или двоичные), различные префиксы и разные Рубиновые классы.
Пример:
BigDecimal.new("1.111111111111111") === 1.111111111111111
=> true
BigDecimal.new("1.1111111111111111") === 1.1111111111111111
=> false
Для записи: не правда. Весь смысл usigng BigDecimal в том, что он не * ведет себя как Float; вы должны получить номер, который вы положили. –
@ Энди Я добавил больше подробностей, чтобы ответить на ваш комментарий. – joelparkerhenderson
отлично, но точка моего комментария заключалась в том, что вам не нужно * использовать * be_within' для соответствия BegDecimal. Это не похоже на Float; вам не нужно учитывать ошибку округления из-за способа сохранения номера. –