คุณมีคำตอบที่ชาญฉลาดอยู่แล้ว: เลขคณิตที่ไม่ได้ลงชื่อเป็นเลขคณิตแบบโมดูโลดังนั้นผลลัพธ์จะถือคุณสามารถพิสูจน์ได้ทางคณิตศาสตร์ ...
สิ่งที่ยอดเยี่ยมอย่างหนึ่งเกี่ยวกับคอมพิวเตอร์คือคอมพิวเตอร์ทำงานเร็ว อันที่จริงมันเร็วมากจนการแจกแจงชุดค่าผสม 32 บิตที่ถูกต้องทั้งหมดเป็นไปได้ในระยะเวลาที่เหมาะสม (อย่าลองด้วย 64 บิต)
ดังนั้นในกรณีของคุณโดยส่วนตัวแล้วฉันชอบโยนมันใส่คอมพิวเตอร์ ฉันใช้เวลาน้อยกว่าในการโน้มน้าวตัวเองว่าโปรแกรมนั้นถูกต้องกว่าที่จะโน้มน้าวตัวเองได้ดีกว่าการพิสูจน์ทางคณิตศาสตร์นั้นถูกต้องและฉันไม่ได้ดูแลรายละเอียดในข้อกำหนด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;
}
สิ่งนี้จะแจกแจงค่าที่เป็นไปได้ทั้งหมดของa
และb
ในช่องว่าง 32 บิตและตรวจสอบว่ามีความเท่าเทียมกันหรือไม่ หากไม่เป็นเช่นนั้นระบบจะพิมพ์เคสที่ใช้ไม่ได้ผลซึ่งคุณสามารถใช้เป็นการตรวจสอบความสมบูรณ์ได้
และตามเสียงดังกราว : ความเท่าเทียมกันถือ
นอกจากนี้เนื่องจากกฎเลขคณิตเป็นแบบไม่เชื่อเรื่องพระเจ้าแบบความกว้างบิต (สูงกว่าint
ความกว้างบิต) ความเท่าเทียมกันนี้จะเก็บไว้สำหรับประเภทจำนวนเต็ม 32 บิตหรือมากกว่าที่ไม่ได้ลงนามรวมถึง 64 บิตและ 128 บิต
หมายเหตุ: คอมไพลเลอร์จะระบุรูปแบบ 64 บิตทั้งหมดในกรอบเวลาที่เหมาะสมได้อย่างไร มันไม่สามารถ ลูปถูกปรับให้เหมาะสม มิฉะนั้นเราทุกคนจะเสียชีวิตก่อนที่การประหารชีวิตจะสิ้นสุดลง
ตอนแรกฉันพิสูจน์แล้วสำหรับจำนวนเต็ม 16 บิตที่ไม่ได้ลงชื่อ น่าเสียดายที่ C ++ เป็นภาษาที่บ้าจำนวนเต็มขนาดเล็ก (bitwidths ขนาดเล็กกว่าint
) 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;
}
และอีกครั้งตามเสียงดังกราว : ความเท่าเทียมกันถือ
เอาล่ะ :)
1 แน่นอนว่าหากโปรแกรมมีการกระตุ้นพฤติกรรมที่ไม่ได้กำหนดโดยไม่ได้ตั้งใจก็จะไม่สามารถพิสูจน์ได้มากนัก
Math.random()
กลับจำนวนเต็มหรือในคู่ [0,1)? ฉันไม่คิดว่าบทของคุณ (ดีที่สุดเท่าที่ฉันจะบอกได้) สะท้อนปัญหาที่คุณวาง