Đây là một vấn đề nhỏ thực sự khó chịu trong đó có ba (!) Nguyên nhân.
Thứ nhất có vấn đề là số học dấu chấm động là gần đúng. Nếu trình biên dịch chọn một hàm pow
trả về float hoặc double, thì 4 ** 31 lớn đến mức 5 nhỏ hơn 1ULP (đơn vị ít chính xác nhất), vì vậy việc thêm nó sẽ không làm gì (nói cách khác, 4.0 ** 31 + 5 == 4.0 ** 31). Nhân với -2 có thể được thực hiện mà không bị mất, và kết quả có thể được lưu trữ trong một long long
mà không bị mất như là câu trả lời sai: -9.223.372.036.854.775.808.
Thứ hai, tiêu đề chuẩn có thể bao gồm các tiêu đề chuẩn khác, nhưng không bắt buộc. Rõ ràng, phiên bản của Visual Studio là <iostream>
bao gồm <math.h>
(tuyên bố pow
trong không gian tên chung), nhưng phiên bản Code :: Blocks thì không.
Thứ ba, chức năng của OP pow
không được chọn vì anh đi lập luận 4
, và 31
, mà đều là kiểu int
, và các chức năng công bố có các tham số kiểu unsigned
. Kể từ C++ 11, có rất nhiều tình trạng quá tải (hoặc một mẫu chức năng) của std::pow
. Tất cả đều trả lại float
hoặc double
(trừ khi một trong các đối số thuộc loại long double
- không áp dụng ở đây).
Do đó, tình trạng quá tải của std::pow
sẽ là kết hợp tốt hơn ... với giá trị trả về kép và chúng tôi nhận được làm tròn điểm nổi.
Đạo đức của câu chuyện: Không viết chức năng có cùng tên với chức năng thư viện chuẩn, trừ khi bạn thực sự biết bạn đang làm gì!
Nguồn
2016-12-08 17:10:07
Nhận xét không dành cho thảo luận mở rộng; cuộc hội thoại này đã được [chuyển sang trò chuyện] (http://chat.stackoverflow.com/rooms/130291/discussion-on-question-by-peter-long-long-value-in-visual-studio). –