C++に慣れるために素数判定の関数を書き、Pythonでは時間のかかったメルセンヌ素数の判定を試そうとしたのですが、2^n - 1
を表現するところで理解のできない挙動に直面しました。
1)``unsigned long long n = 1;を用意してfor文内で2乗を繰り返す、2)あるいはfor文内で
n = pow(2, i);を用意してから
--n;をすると、
2^n - 1が正しく表現されます。 ですが、3)for文内で
n = pow(2, i) - 1;とすると、
2^53 - 1までは正しく計算されるのですが、
2^54 - 1以降は、
2^n - 1ではなく
2^n`になってしまいます。
C++ - C++のpow関数でおかしくなってるのか?|teratailという質問を読んで、double
の表現範囲の限界として52-53桁あたりで問題が起きうるというのは何となく理解したのですが、(2)と(3)のやり方で差が出る理由が分かりません。
よろしくお願いします。
C++
1#include <iostream> 2#include <string> 3using namespace std; 4 5int main() { 6 // works fine 7 unsigned long long n = 1; 8 for (int i = 1; i <= 64; ++i) { 9 n *= 2; 10 cout << "2^"s << i << "-1: "s << n - 1 << endl; 11 } 12}
C++
1#include <iostream> 2#include <string> 3#include <cmath> 4using namespace std; 5 6int main() { 7 // works fine 8 for (int i = 1; i <= 64; ++i) { 9 unsigned long long n = pow(2, i); 10 cout << "2^"s << i << "-1: "s << n - 1 << endl; 11 } 12}
C++
1#include <iostream> 2#include <string> 3#include <cmath> 4using namespace std; 5 6int main() { 7 /* 8 * incorrect from 2^54 - 1 9 * 2^53-1: 9007199254740991 10 * 2^54-1: 18014398509481984 (should be 18014398509481983) 11 */ 12 for (int i = 1; i <= 64; ++i) { 13 unsigned long long n = pow(2, i) - 1; 14 cout << "2^"s << i << "-1: "s << n << endl; 15 } 16}
回答3件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。