2016-08-22 23 views
6

Có sự khác biệt chính xác giữa các giá trị sau (giả sử giá trị của a và b có thể biểu diễn mà không mất độ chính xác trong phao).Float vs double Math Java

Với nổi:

float a; 
float b; 
double result = 1 + a*b; 

Với đôi:

double a; 
double b; 
double result = 1 + a*b; 
+0

Có theo định nghĩa; một 'float' là một điểm nổi bật 32 bit, cơ bản 2 IEEE 754 trong khi một' double' là 64bit. Sự kiện duy nhất mà điều này không đúng là _all ba_ của các yếu tố đầu vào và kết quả có thể phù hợp với một 'float'. – fge

+0

Tôi về cơ bản muốn biết nếu Java đã chuyển đổi một * b thành đôi sau hậu trường. Từ câu trả lời, tôi có thể thấy rõ ràng không phải vậy. – Quirion

Trả lời

6

ví dụ đơn giản:

float a = 16777217; // Largest int exactly representable in a float. 
float b = 16777217; 
System.out.println((double)(1 + a*b)); 

double c = 16777217; 
double d = 16777217; 
System.out.println(1 + c*d); 

Output (Ideone):

2.81474976710656E14 
2.8147501026509E14 

Vì vậy, có, có một mất độ chính xác sử dụng float.

+0

Để bổ sung cho câu trả lời của bạn, bạn có thể thêm ghi chú Peter Lawrey đã đề cập, rằng a * b là một phao khi a và b là phao. – Quirion

0

Có thể có một sự mất mát của sự khác biệt chính xác trong một phần * b khi bạn đánh giá nó như là phao nổi và đôi. Vì vậy, có, với một số giá trị, thứ hai sẽ chính xác hơn.

3

Có một mất độ chính xác trong

float a; 
float b; 
double result = 1 + a*b; 
  • các float đại diện.
  • sản phẩm của ab cũng sẽ là float. Lưu ý: a * b là một số float
  • việc thêm vào ngày 1 có thể dẫn đến mất độ chính xác.

Để nên rằng a * b thể mất chính xác hơn

for (int i = 1; i < 100; i += 2) { 
    float a = i; 
    float b = 1.0f/i; 
    if ((double) a * b != a * b && a * b != 1) 
     System.out.println(i + " " + (double) a * b + " " + a * b); 
} 

in

41 0.999999962747097 0.99999994 
47 0.9999999683350325 0.99999994 
55 0.9999999683350325 0.99999994 
61 0.9999999441206455 0.99999994 
83 0.999999962747097 0.99999994 
97 0.999999969266355 0.99999994 

lưu ý: nó cũng có thể xảy ra hồi chính xác mất và nhận được câu trả lời ngay sau khi b đã mất độ chính xác

for (int i = 1; i < 20; i += 2) { 
    float a = i; 
    float b = 1.0f/i; 
    if (b != 1.0/i && a * b == 1) 
     System.out.println(i + " " + (double) a * b + " " + a * b); 
} 

in

3 1.0000000298023224 1.0 
5 1.0000000149011612 1.0 
7 1.0000000447034836 1.0 
9 1.0000000074505806 1.0 
11 1.0000000298023224 1.0 
13 1.000000037252903 1.0 
15 1.0000000521540642 1.0 
17 1.0000000037252903 1.0 
19 1.0000000074505806 1.0 
+0

Là 'float b = -1.0f/i;' đại diện mà không mất độ chính xác? – Quirion

+0

@Quirion chỉ khi 'i' là một sức mạnh của 2. Nếu không có một số mất độ chính xác mà có thể tồi tệ hơn hoặc biến mất khi nhân với 'i' –

+0

Vì vậy, câu trả lời của bạn không hợp lệ như vậy, bởi vì bạn đang mất độ chính xác thời điểm bạn gán float b = -1.0f/i; , nhưng câu hỏi nói rằng a và b có thể được biểu diễn mà không bị mất độ chính xác. Tôi đã quan tâm đến sự hiểu biết nếu phép nhân gây mất độ chính xác và nó làm vì một * b được xử lý như một phao, như bạn đã đề cập. – Quirion

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