Zaten akıllı cevaba sahipsiniz: işaretsiz aritmetik, modülo aritmetiktir ve bu nedenle sonuçlar geçerli olacaktır, bunu matematiksel olarak kanıtlayabilirsiniz ...
Bilgisayarlarla ilgili harika bir şey, bilgisayarların hızlı olmasıdır. Aslında, o kadar hızlıdırlar ki, 32 bitlik tüm geçerli kombinasyonları makul bir süre içinde saymak mümkündür (64 bit ile denemeyin).
Bu yüzden, sizin durumunuzda, ben şahsen onu bir bilgisayara atmayı seviyorum; o program matematiksel kanıtı doğru olandan kendimi ikna için gereken daha doğru olduğunu kendimi ikna etmeye bana daha az zaman alır ve ben şartnamede bir ayrıntıyı nezaret etmediğini 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;
}
Bu, tüm olası değerleri ile numaralandırır a
veb
eşitlik tutan veya değil 32-bit uzayda ve çekler olsun. Çalışmazsa, mantık kontrolü olarak kullanabileceğiniz, çalışmayan vakayı yazdırır.
Ve Clang'a göre : Eşitlik geçerlidir .
Ayrıca, aritmetik kuralların bit genişliği agnostik olduğu göz önüne alındığında (yukarıda int
bit genişliğinin ) , bu eşitlik, 64 bit ve 128 bit dahil olmak üzere 32 bit veya daha fazla işaretsiz tamsayı türü için geçerli olacaktır.
Not: Bir derleyici, tüm 64 bitlik kalıpları makul bir zaman diliminde nasıl sıralayabilir? Olamaz. Döngüler optimize edildi. Aksi takdirde idam sona ermeden hepimiz ölmüş olurduk.
Başlangıçta bunu yalnızca 16 bitlik işaretsiz tamsayılar için kanıtladım; ne yazık ki C ++, küçük tam sayıların (bundan daha küçük bit genişlikleri int
) ilk önce dönüştürüldüğü çılgın bir dildir 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;
}
Ve bir kez daha, Clang'a göre : Eşitlik geçerlidir .
İyi gidiyorsun :)
1 Elbette, bir program yanlışlıkla Tanımlanmamış Davranışı tetiklerse, pek bir şey kanıtlamaz.
Math.random()
[0,1) üzerinde bir tamsayı mı yoksa bir çift mi döndürür? Senaryonuzun (söyleyebileceğim en iyisi) oluşturduğunuz sorunu yansıttığını sanmıyorum.