Nếu tôi viết:
int x = /* any non-zero integer value */;
float y = x;
float z = y / y;
Có zđược đảm bảo là chính xác 1.f không?
Nếu tôi viết:
int x = /* any non-zero integer value */;
float y = x;
float z = y / y;
Có zđược đảm bảo là chính xác 1.f không?
x, static_cast<int>(y) != x(nếu cả hai đều là 32-bit), nhưng zvẫn sẽ bằng 1.0ftrừ khi x == 0cả mẫu số và mẫu số đều có cùng một lỗi làm tròn.
xvà yđủ lớn, và đủ gần nhau (không bằng nhau), thì x/ycó thể sẽ 1.fquá, do lỗi chuyển đổi. Hãy thử gõ này trong giao diện điều khiển của trình duyệt của bạn (mà có lẽ còn sử dụng IEEE754) và nhấn ENTER: 9223372036854775700/9223372036854775800.
Câu trả lời:
Nếu triển khai C ++ của bạn sử dụng IEEE754 thì có, điều này được đảm bảo. (Toán tử phép chia được yêu cầu để trả về giá trị dấu phẩy động tốt nhất có thể).
Các chỉ ngoại lệ cho y / y, nói chung, không phải là 1.flà những trường hợp khi yđược NaN, +Inf, -Inf, 0.f, và -0.f, hoặc nếu bạn đang ở trên một nền tảng nơi intrất rộng mà trường hợp nhất định nó không thể được đại diện trong một floatmà không có floatđược thiết lập để +Infhoặc -Inf1 . Bỏ qua điểm cuối cùng đó, trong trường hợp của bạn, điều đó có nghĩa là điều đó int x = 0;sẽ tạo ra ngoại lệ duy nhất.
IEEE754 rất phổ biến. Nhưng để kiểm tra chắc chắn, hãy kiểm tra giá trị của
std::numeric_limits<float>::is_iec559;
1 Ví dụ, một nền tảng với 128 bit intvà IEEE754 32 bit floatsẽ thể hiện hành vi này cho các giá trị nhất định của x.
ycó thể trở thành NaN.
NaN, một số mẫu có bộ bit dấu. Nhưng NaN != NaNđối với bất kỳ bitpattern nào của NaN, việc tranh luận xem "+ NaN == -NaN" là vô nghĩa.
ygiá trị đó vừa nằm trong một thanh ghi vừa trong bộ nhớ, và trình biên dịch đã chọn tải mẫu số từ bộ nhớ. Vì vậy, bạn kết thúc với y_from_register / y_from_memory. Nếu thanh ghi có độ chính xác cao hơn bộ nhớ, điều gì đảm bảo rằng 1 là kết quả chia tốt nhất?
floatkhông thể chứa xgiá trị của.
Không, không phải trong mọi trường hợp, ngay cả đối với IEEE754.
Ví dụ: với int x = 0;, bạn sẽ nhận được NaN. ( Trực tiếp )
infhay 0fhoặc dấu hiệu biến thể của những người thì kết quả cũng không phải là1f
std::numeric_limits<int>::max()có thể lớn hơnstd::numeric_limits<float>::max().