2012-06-10 32 views
13
#include <stdio.h> 
#include <float.h> 

int main() 
{ 
    printf("%f\n", FLT_MAX); 
} 

Output từ GNU:in ấn rất lớn số dấu chấm động

340282346638528859811704183484516925440.000000 

Output từ Visual Studio:

340282346638528860000000000000000000000.000000 

Đừng tiêu chuẩn C và C++ cho phép cả hai kết quả? Hay họ ủy thác một kết quả cụ thể?

Lưu ý rằng FLT_MAX = 2^128-2^104 = 340282346638528859811704183484516925440.

+3

Các tiêu chuẩn C và C++ thậm chí không chỉ định một biểu diễn dấu phẩy động cụ thể. Vì vậy, tôi bị cám dỗ để nghĩ rằng họ không thể ủy thác một kết quả cụ thể. – Mysticial

+0

@Trung bình Vâng, họ có thể vẫn thường ủy quyền rằng "giá trị chính xác được đại diện phải được in ra" hoặc một cái gì đó đến mức độ đó. – fredoverflow

+3

Và Unix pwns Windows. Một lần nữa. –

Trả lời

6

Tôi nghĩ rằng một phần liên quan của tiêu chuẩn C99 là "Đề xuất thực tế" từ 7.19.6.1 p.13:

Đối e, E, f, F, g, và G chuyển đổi, nếu số chữ số thập phân có ý nghĩa tối đa là DECIMAL_DIG, sau đó kết quả phải được làm tròn chính xác. Nếu số lượng chữ số thập phân có ý nghĩa lớn hơn DECIMAL_DIG nhưng giá trị nguồn chính xác là có thể đại diện với số DECIMAL_DIG, thì kết quả phải là đại diện chính xác với số không dấu. Nếu không, giá trị nguồn bị ràng buộc bởi hai các chuỗi thập phân liền kề L < U, cả hai có số có nghĩa là DECIMAL_DIG; giá trị của chuỗi số thập phân kết quả D nên đáp ứng L < = D < = U, với quy định bổ sung mà lỗi nên có một dấu hiệu chính xác cho sự chỉ đạo làm tròn hiện hành.

Hiển thị của tôi là điều này cho phép mất nhiều thời gian trong những gì có thể được in trong trường hợp này; vì vậy kết luận của tôi là cả VS và GCC đều tuân thủ ở đây.

+0

Erm ... Vậy GNU hay Visual Studio có đúng không? :) – fredoverflow

+2

Cả hai đều chính xác, chỉ một có độ chính xác cao hơn. –

+5

@ColeJohnson: không có độ chính xác cao hơn. GNU lừa bạn nghĩ rằng nó có, nhưng kết quả của nó thậm chí còn tồi tệ hơn MSVC. Điểm nổi đại diện cho * khoảng *, không phải số. Vì vậy, 340282346638528859811704183484516925440, 340282346638528859811704183484516925450 và 340282346638528860000000000000000000000 là tất cả cùng một giá trị dấu phẩy động (đối với ieee 64 bit). [Một định dạng điểm nổi tốt hơn rountine thực sự là một trong đó cung cấp cho bạn các đại diện ngắn nhất có thể] (http://florian.loitsch.com/publications/dtoa-pldi2010.pdf). – ybungalobill

1

Cả hai đều được phép theo tiêu chuẩn C (C++ chỉ inports tiêu chuẩn C)

Từ một draft version trong phần 5.2.4.2.2 phần 10

Các giá trị được đưa ra trong danh sách sau đây sẽ thay thế bằng biểu thức thường xuyên với fi định nghĩa giá trị thực-de mà là lớn hơn hoặc bằng với những hiển thị:
- tối đa biểu diễn fi nite fl số thả nổi-điểm, (1 - b -p) b Emax

FLT_MAX 1E+37 

và Visual C++ 2012 có

#define FLT_MAX   3.402823466e+38F  /* max value */ 
+0

Trong thực tế, giá trị của 'FLT_MAX' sẽ giống nhau trên bất kỳ nền tảng nào sử dụng điểm nổi IEEE-754. Vì vậy, đó không phải là vấn đề ở đây. –

+0

@OliCharlesworth: Được rồi, có thể "thiếu sót" quá mạnh. Nó gọi các kết quả không xác định. – wallyk

0

Mã bản thân là thiếu sót mà nó sử dụng %f cho một giá trị lớn hơn tầm quan trọng được tổ chức tại một float hoặc double. Bằng cách làm như vậy, bạn đang yêu cầu xem "đằng sau bức màn" như các bit bảo vệ vô nghĩa hoặc tiếng ồn điểm động khác được tạo ra trong chuyển đổi sang thập phân.

Rõ ràng bạn không nên mong đợi bất kỳ sự nhất quán nào trong các hồ sơ kim loại được tạo ra sau khi chế tạo động cơ tại Honda so với Toyota. Nevermind bất kỳ kỳ vọng hợp lý của sự nhất quán như vậy.

Cách thích hợp để hiển thị số đó là sử dụng một trong các định dạng "khoa học" như %g độ chính xác được cung cấp không được chỉ định quá mức. Khi triển khai IEEE-754, 7 số thập phân có ý nghĩa đối với float, 15-16 cho double, khoảng 19 cho long double và 34 cho __float128. Vì vậy, đối với ví dụ bạn đã đưa ra, %.15g sẽ phù hợp, giả sử nó đang được thực hiện IEEE-754.

+1

Sử dụng '% f' không phải là" thiếu sót ". Câu hỏi đặt ra là hỏi cái gì tiêu chuẩn cho phép "đằng sau tấm màn". –

+0

@OliCharlesworth: Được rồi, có thể "thiếu sót" quá mạnh. Nó gọi các kết quả không xác định. – wallyk