0

我一生都无法弄清楚为什么 my:generate_receipt方法54.9在我的“进口餐盘项目”应该等于时返回54.65。我编写了 RSpec 测试来确认数组确实返回了正确的值。

47.50 + 4.75 + 2.40 = 54.65

为什么它返回54.9而不是返回54.65?!这种围捕发生在哪里?如何让它返回正确的值?我难住了。

describe :calcualte_sales_tax do

  it "should return the correct array" do
    calculate_sales_tax(@receipt).should eq([0, 4.75])
  end

end

describe :calculate_import_tax do

  it "should return the correct array" do
    calculate_import_tax(@receipt).should eq([0.50, 2.40])
  end

end 

@receipt = {
    "1"=>{:item=>"imported chocolates", :price=>10.00, :quantity=>1},    
    "2"=>{:item=>"imported dinner plates", :price=>47.50, :quantity=>1}
    }

def generate_receipt(receipt)
  n = 0
  while n < receipt.length 
    receipt["#{n+1}"][:price]+=calculate_sales_tax(receipt)[n]
    receipt["#{n+1}"][:price]+=calculate_import_tax(receipt)[n]
    n+=1
  end
  receipt
end

def calculate_import_tax(receipt)
  taxes = []
  receipt.each do |k,v|
    if (v[:item] =~ /imported/)
      subtotal = v[:price]
      # v[:price]+=(((((5 * subtotal)/100)*20.ceil) / 20.0))
      # taxes<<(5 * subtotal)/100
      taxes<<((5 * subtotal/100)*20).ceil/20.0.round(2)
    else
      taxes<<0
    end
  end
  taxes
end

def calculate_sales_tax(receipt)
  tax_free_items = ["book", "chocolate bar", "chocolates", "pills"]
  taxes = []
  receipt.each do |k,v|
    if (v[:item] =~ /chocolate\s/) ||
      (v[:item] =~ /chocolates/) || 
      (v[:item] =~ /book/) || 
      (v[:item] =~ /pills/)
      taxes<<0
    else
      subtotal = v[:price]
      # v[:price]+=(((((10 * subtotal)/100)*20.ceil) / 20.0))
      # taxes<<(10 * subtotal)/100
      taxes<<((10 * subtotal/100)*20).ceil/20.0
    end
  end
  taxes
end
4

2 回答 2

1
def generate_receipt(receipt)
  n = 0
  while n < receipt.length
    puts receipt["#{n+1}"][:price].inspect
    receipt["#{n+1}"][:price]+=calculate_sales_tax(receipt)[n].round(2)
    puts receipt["#{n+1}"][:price].inspect
    puts calculate_import_tax(receipt)[n]
    receipt["#{n+1}"][:price]+=calculate_import_tax(receipt)[n].round(2)
    puts receipt["#{n+1}"][:price].inspect
    puts "-----"
    n+=1
  end
  receipt
end

回报:

47.5
52.25
2.65
54.9

该错误在您的 calculate_import_tax 方法中。它返回 2.65,而不是 2.40。

编辑:

知道了 :)。

    receipt["#{n+1}"][:price]+=calculate_sales_tax(receipt)[n]
    receipt["#{n+1}"][:price]+=calculate_import_tax(receipt)[n]

这些行正在更新收据的价格。因此,您的测试是独立运行的,但在计算进口税之前,销售税会修改原始价格......

于 2013-01-31T21:35:14.973 回答
0

1) Ruby 将没有小数部分的数字视为 INTEGERS。除非计算包括浮点数,否则不会创建具有小数部分的结果。

2) 10 * X / 100 * 20 == X * 2

3)法律计数可能需要指定的准确性,因此您可能需要使用专门的库来进行此类数字运算。

快速的解决方案是将代码更改为:

10.0 * 小计 / 100.0 * 20.0

现在 Ruby 会将所有这些数字视为浮点数。

于 2013-01-31T21:38:40.160 回答