2014-10-09 11 views
5
-:total_cost_with_tax => #<BigDecimal:7fda9d17aaf0,'0.105225E4',18(45)>, 
-:total_cost_without_tax => #<BigDecimal:7fda9d17b450,'0.972E3',9(36)>, 
-:total_last_installment_amount => #<BigDecimal:7fda9d17b978,'0.8011E2',18(45)>, 
-:total_monthly_installment_amount => #<BigDecimal:7fda9d17abb8,'0.8011E2',18(45)>, 
-:total_tax => #<BigDecimal:7fda9d17b068,'0.8025E2',18(45)>, 

+:total_cost_with_tax => #<BigDecimal:7fda9d0184c8,'0.105225E4',18(36)>, 
+:total_cost_without_tax => #<BigDecimal:7fda91ff2b48,'0.972E3',9(27)>, 
+:total_last_installment_amount => #<BigDecimal:7fda91fee548,'0.8011E2',18(36)>, 
+:total_monthly_installment_amount => #<BigDecimal:7fda91fe72c0,'0.8011E2',18(36)>, 
+:total_tax => #<BigDecimal:7fda9d00a2b0,'0.8025E2',18(36)>, 

Vì vậy, chúng được rải rác trong một số thử nghiệm của tôi ... rspec 2, ray 3. Tôi so sánh băm sử dụng .should eq() để so sánh. Tôi dường như không thể có được câu thần chú đúng. Có vẻ như đó là một điều chính xác, có vẻ ngớ ngẩn.rspec đối số thập phân lớn

Trả lời

6

RSpec 3 có BigDecimal eq:

x.should eq(y) 

expect(x).to eq(y) 

Nếu bạn đang so sánh một BigDecimal đến một phao, phải nhận thức được độ chính xác có thể ảnh hưởng đến sự so sánh.

Bạn có thể sử dụng này:

x.should be_within(delta).of(y) 

expect x.to be_within(delta).of(y) 

Nếu bạn đang so sánh hai số BigDecimal có độ chính xác khác nhau, lưu ý rằng những con số này có thể hiển thị kết quả khác nhau từ inspect và cũng từ hash tùy thuộc vào nền tảng của bạn và những gì phiên bản Ruby BigDecimal bạn đang chạy.

Ví dụ, điều này có thể xảy ra:

BigDecimal.new("2").hash == BigDecimal.new("2.0").hash 
=> false 

đầu ra của bạn cho thấy rằng chuỗi đại diện BigDecimal của bạn là hơi khác nhau.

Dưới đây là khái niệm về chuỗi của bạn có nghĩa là:

  • Phần 1 là địa chỉ đối tượng.
  • Phần 2 là giá trị số được biểu thị dưới dạng một chuỗi.
  • Phần 3 là số chữ số có nghĩa sau đó số chữ số có nghĩa tối đa.

Đầu ra của bạn cho thấy các chuỗi của bạn có các địa chỉ đối tượng khác nhau, các giá trị số giống hệt nhau (tức là phần 2), các chữ số có nghĩa giống nhau (số đầu tiên trong phần 3), nhưng số khác nhau.

Đối với câu hỏi của bạn, sử dụng RSpec 2 và so sánh các dấu băm BigDecimal, bạn sẽ giải quyết vấn đề của mình bằng cách sử dụng trình kết hợp rspec be_within.

Lưu ý rằng Ruby BigDecimal số và Float số đều số dấu chấm động:

  • Một BigDecimal là một số điểm độc đoán chính xác thập phân nổi.

  • A Float là số dấu phẩy động nhị phân có độ chính xác kép của kiến ​​trúc gốc.

Bạn có thể thấy các đại diện dấu chấm động BigDecimal thập phân bằng cách làm này:

require 'bigdecimal' 
x=BigDecimal.new(100) 
=> #<BigDecimal:7f8e62038570,'0.1E3',9(27)> 

Các significand phần là '0.1' và phần mũ là 'E3'.

Lưu ý rằng đây là máy ảo Ruby MRI/KRI điển hình.Việc triển khai có thể khác nhau trên các máy ảo khác của Ruby, chẳng hạn như JRuby, bởi vì Java có mã bignum của riêng nó.

Khi bạn so sánh hai loại số dấu phẩy động khác nhau, như BigDecimal và Float, bạn có thể nhận được kết quả có vẻ phản trực giác vì các loại sử dụng các căn cứ khác nhau (thập phân so với nhị phân), các điểm khác nhau và khác nhau Lớp học Ruby.

Ví dụ:

BigDecimal.new("1.111111111111111") === 1.111111111111111 
=> true 
BigDecimal.new("1.1111111111111111") === 1.1111111111111111 
=> false 
+0

Đối với hồ sơ: không đúng sự thật. Toàn bộ quan điểm của BigDecimal là nó * không * cư xử như một phao; bạn có nghĩa vụ phải lấy số bạn đã nhập. –

+0

@Andy Tôi đã thêm chi tiết hơn để giải quyết nhận xét của bạn. – joelparkerhenderson

+0

tuyệt vời, nhưng điểm của nhận xét của tôi là bạn không nên * cần * để sử dụng 'be_within' để phù hợp với một BegDecimal. Nó không giống như một chiếc phao; bạn không cần tính đến lỗi làm tròn vì cách lưu trữ số. –

2

Với RSpec 3.x bạn có thể sử dụng cho BigDecimal các eq khớp như bạn có thể sử dụng nó cho phao.

RSpec.describe "an integer" do 
    it "is equal to a float of the same value" do 
    expect(5).to eq(5.0) 
    end 
end 

Để biết thêm thông tin xem tài liệu RSpec: https://www.relishapp.com/rspec/rspec-expectations/v/3-4/docs/built-in-matchers/equality-matchers

+0

IMHO này tốt hơn giải pháp được chấp nhận – damoiser

+1

@damoiser Câu hỏi được hỏi khi RSpec là phiên bản 2, không phải phiên bản 3. Tôi sẽ cập nhật câu trả lời ngay bây giờ để hiển thị cả hai vì tôi đồng ý với bạn. – joelparkerhenderson

Các vấn đề liên quan