2015-01-07 11 views
5

Thử tính số học dấu phẩy động trong Groovy. Không biết tại sao/làm thế nào/những gì groovy đang làm đằng sau hậu trường để gây ra những loại hành vi khác nhau?Tại sao Groovy thực hiện số học dấu chấm động theo cách này?

double point2 = 0.2 
double point1 = 0.1 
double point3 = 0.3 

assert point2 + point1 == point3 // false, as expected 
    |  | |  | | 
    0.2 | 0.1 | 0.3 
      |  false 
      0.30000000000000004  

float point2 = 0.2 
float point1 = 0.1 
float point3 = 0.3 

assert point2 + point1 == point3 // false, as expected 
    |  | |  | | 
    0.2 | 0.1 | 0.3 
      |  false 
      0.30000000447034836 

def point2 = 0.2 
def point1 = 0.1 
def point3 = 0.3 

assert point2 + point1 == point3 // this returns true 
assert 0.2 + 0.1 == 0.3 // this returns true 

Tôi nghĩ rằng nó phải làm với BigDecimal nhưng sau đó tôi đã thử điều này.

BigDecimal point2 = 0.2 
BigDecimal point1 = 0.1 
BigDecimal point3 = 0.3 

float point4 = 0.4 

assert point1 + point3 == point4 
    |  | |  | | 
    0.1 | 0.3 | 0.4 
      0.4  false 

Điều gì gây ra hành vi này?

+0

có thể trùng lặp của [Toán tử dấu chấm động bị hỏng?] (Http://stackoverflow.com/questions/588004/is-floating-point-math-broken) – tmyklebu

+2

@tmyklebu không có điều này không trùng lặp với câu hỏi này; trong khi nửa đầu sẽ chỉ ra rằng, khi các xác nhận được viết sai, câu hỏi ở đây là về các loại (ẩn) của groovy cho các số "floaty". – cfrick

+0

@cfrick: Tôi hiểu rồi. Bạn đúng; đây là về loại chữ nổi dấu phẩy rõ ràng. Hãy tha thứ cho ngón tay kích thích ngứa của tôi; Tôi thấy '0.1' và '0.2' và' 0.3' và nói "Ôi Chúa ơi, không phải lần nữa." – tmyklebu

Trả lời

5

bạn def: s có BigDecimals

groovy:000> p1 = 0.1 
===> 0.1 
groovy:000> p1.getClass() 
===> class java.math.BigDecimal 

equals không cho comparsion giữa BigDecimal và phao mẹ đẻ/đôi

groovy:000> p1.equals(0.1f) 
===> false 
groovy:000> p1.equals(0.1) 
===> true 
groovy:000> p1==0.1f 
===> false 
groovy:000> p1==0.1 
===> true 

Không chắc chưa, tại sao == công trình cho [Dd] Gấp đôi .

groovy:000> p1.equals(0.1d) 
===> false 
groovy:000> p1==0.1d 
===> true 

Tôi đoán là, nó được chôn trong DefaultTypeTransformation.compareToWithEqualityCheck. Vì cả hai bên đều là Số: s.

+0

Tôi đã tìm ra điều đó và thêm vào câu hỏi. – kschmit90

+0

Được rồi, nhưng tại sao bằng không để so sánh giữa BigDecimal và float/double bản địa? Vì vậy, tôi có thể so sánh một đôi với một BigDecimal nhưng không phải là một phao? – kschmit90

+3

thực sự tôi nghĩ rằng bạn đã tìm thấy một lỗi. Giả định của tôi sẽ là BigDecimal được chuyển đổi sai thành một đôi để so sánh. Tôi đã mở http://jira.codehaus.org/browse/GROOVY-7238 để theo dõi điều này – blackdrag

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