Bạn đã có câu trả lời thông minh: số học không dấu là số học modulo và do đó kết quả sẽ giữ nguyên, bạn có thể chứng minh điều đó bằng toán học ...
Tuy nhiên, một điều thú vị về máy tính là máy tính rất nhanh. Thật vậy, chúng nhanh đến mức có thể liệt kê tất cả các kết hợp hợp lệ của 32 bit trong một khoảng thời gian hợp lý (đừng thử với 64 bit).
Vì vậy, trong trường hợp của bạn, cá nhân tôi chỉ muốn ném nó vào máy tính; Tôi mất ít thời gian hơn để thuyết phục bản thân rằng chương trình là đúng hơn là tự thuyết phục bản thân hơn là bằng chứng toán học là đúng và tôi đã không giám sát một chi tiết trong đặc điểm kỹ thuật 1 :
#include <iostream>
#include <limits>
int main() {
std::uint64_t const MAX = std::uint64_t(1) << 32;
for (std::uint64_t i = 0; i < MAX; ++i) {
for (std::uint64_t j = 0; j < MAX; ++j) {
std::uint32_t const a = static_cast<std::uint32_t>(i);
std::uint32_t const b = static_cast<std::uint32_t>(j);
auto const champion = (a + (b & 255)) & 255;
auto const challenger = (a + b) & 255;
if (champion == challenger) { continue; }
std::cout << "a: " << a << ", b: " << b << ", champion: " << champion << ", challenger: " << challenger << "\n";
return 1;
}
}
std::cout << "Equality holds\n";
return 0;
}
Điều này liệt kê thông qua tất cả các giá trị có thể có của a
và b
trong không gian 32-bit và kiểm tra xem sự bình đẳng có giữ hay không. Nếu không, nó sẽ in ra trường hợp không hoạt động, bạn có thể sử dụng cái này để kiểm tra sự tỉnh táo.
Và, theo Clang : Bình đẳng được giữ vững .
Hơn nữa, do các quy tắc số học là bất khả tri về độ rộng bit (ở trên int
độ rộng bit), sự bình đẳng này sẽ giữ cho bất kỳ kiểu số nguyên không dấu nào từ 32 bit trở lên, bao gồm cả 64 bit và 128 bit.
Lưu ý: Làm thế nào một trình biên dịch có thể liệt kê tất cả các mẫu 64 bit trong một khung thời gian hợp lý? Nó không thể. Các vòng lặp đã được tối ưu hóa. Nếu không, tất cả chúng ta đã chết trước khi cuộc hành quyết chấm dứt.
Ban đầu tôi chỉ chứng minh điều đó cho các số nguyên không dấu 16 bit; Thật không may, C ++ là một ngôn ngữ điên rồ nơi các số nguyên nhỏ (bitwidths nhỏ hơn int
) được chuyển đổi đầu tiên int
.
#include <iostream>
int main() {
unsigned const MAX = 65536;
for (unsigned i = 0; i < MAX; ++i) {
for (unsigned j = 0; j < MAX; ++j) {
std::uint16_t const a = static_cast<std::uint16_t>(i);
std::uint16_t const b = static_cast<std::uint16_t>(j);
auto const champion = (a + (b & 255)) & 255;
auto const challenger = (a + b) & 255;
if (champion == challenger) { continue; }
std::cout << "a: " << a << ", b: " << b << ", champion: "
<< champion << ", challenger: " << challenger << "\n";
return 1;
}
}
std::cout << "Equality holds\n";
return 0;
}
Và một lần nữa, theo Clang : Bình đẳng được giữ vững .
Vâng, bạn đi rồi :)
1 Tất nhiên, nếu một chương trình nào đó vô tình kích hoạt Hành vi không xác định, thì điều đó sẽ không chứng minh được nhiều điều.
Math.random()
trả về một số nguyên hoặc một số kép trên [0,1) không? Tôi không nghĩ rằng kịch bản của bạn (tốt nhất mà tôi có thể nói) phản ánh vấn đề mà bạn đặt ra.