0
我正在測試一個我在Ruby中製作的小而簡單的庫。目標是從EUR
轉換爲CNY
,反之亦然。簡單。除法後乘以浮點不等於
我測試了它,以確保一切正常,但我得到了意想不到的問題。當我使用to_euro
後跟to_yuan
時,應該回到原來的amount
;它不會發生。我試圖.to_f
或round(2)
amount
變量,它修復了一些測試,提出了新的測試,但它永遠不會等於我所期望的全局;我跑出來的想法來解決這個問題:(
class Currency
attr_reader :amount, :currency
def initialize(amount, currency='EUR')
@amount = amount
@currency = currency
end
def to_yuan
update_currency!('CNY', amount * Settings.instance.exchange_rate_to_yuan)
end
def to_euro
update_currency!('EUR', amount/Settings.instance.exchange_rate_to_yuan)
end
def display
"%.2f #{current_symbol}" % amount
end
private
def current_symbol
if currency == 'EUR'
symbol = Settings.instance.supplier_currency.symbol
elsif currency == 'CNY'
symbol = Settings.instance.platform_currency.symbol
end
end
def update_currency!(new_currency, new_amount)
unless new_currency == currency
@currency = new_currency
@amount = new_amount
end
self
end
end
測試
describe Currency do
let(:rate) { Settings.instance.exchange_rate_to_yuan.to_f }
context "#to_yuan" do
it "should return Currency object" do
expect(Currency.new(20).to_yuan).to be_a(Currency)
end
it "should convert to yuan" do
expect(Currency.new(20).to_yuan.amount).to eql(20.00 * rate)
end
it "should convert to euro and back to yuan" do
# state data test
currency = Currency.new(150, 'CNY')
expect(currency.to_euro).to be_a(Currency)
expect(currency.to_yuan).to be_a(Currency)
expect(currency.amount).to eql(150.00)
end
end
context "#to_euro" do
it "should convert to euro" do
expect(Currency.new(150, 'CNY').to_euro.amount).to eql(150/rate)
end
end
context "#display" do
it "should display euros" do
expect(Currency.new(10, 'EUR').display).to eql("10.00 €")
end
it "should display yuan" do
expect(Currency.new(60.50, 'CNY').display).to eql("60.50 ¥")
end
end
end
這是我的RSpec的結果
我敢肯定這個問題很常見,任何想法如何解決很容易嗎?
如果您需要精確的結果,請勿使用Float,但使用BigDecimal。 – user1934428
使用乘法而不是除法。 –
Float幾乎總是不準確的[Nice條款在大多數編程語言中這是如此](http://itreallymatters.net/post/386327451/floating-point-arithmetics-in-19-programming#.V59qqaK1VwA)。對於精確的數學使用'BigDecimal'。 – engineersmnky