2020年08月03日(月) [長年日記]
■ [math] 巨大自然数Aが自然数Bの倍数かどうかを調べる
long型では表現できない大きな数AがBの倍数かどうかを調べるにはどうするか。
倍数かどうかを知るにはAをBで割った余りが0かどうかを調べればよい。Aが大きな数でもその余りはBより大きくならないので、余りさえ計算できればうまくいく。
例えば、Aを「11111111111111111111111111111111111111111111111111」のように1が連続した整数とする。このような数は1から始めて「10倍して1を加える」という操作を繰り返すことで生成できるので、剰余演算の等価性から得られる
(10a + 1) % b = (10a % b + 1 % b) % b = (((10 % b)(a % b)) % b + 1 % b) % b
という変換を繰り返すことで余りを求めることができる(「a % b」はaをbで割った余りを表すものとする)。
1が連続する整数のことをレピュニット数と言うようだが、120桁のレピュニット数は5964848081の倍数らしい。それを次のコードで確認できる。
#include <iostream> int main() { const long b = 5964848081L; long rem = 1; for (int n = 2; n <= 120; ++n) { rem = ((10 * rem) % b + 1) % b; } std::cout << rem << std::endl; }
0