C言語で学ぶ超完全数(スーパーパーフェクト数)の判定方法
超完全数とは?
「超完全数(スーパーパーフェクト数)」とは、完全数の概念を一般化した数論上の概念です。1969年に数学者のD・スリヤナラヤナ(D Suryanarayana)によって発見されました。超完全数は、次の式を満たす自然数として定義されます。
sig(sig(n)) = 2n
ここで sig(n) は、ある整数の約数の総和を求める関数で、「約数和関数」と呼ばれます。つまり、約数の総和を2段階で計算した結果が元の数の2倍になるとき、その数を超完全数と呼びます。
具体例1:16は超完全数
N = 16 が超完全数かどうかを、約数の総和を使って確認してみましょう。
sig(16) = 1 + 2 + 4 + 8 + 16 = 31(16の約数は 1, 2, 4, 8, 16) sig(31) = 1 + 31 = 32(31は素数のため約数は2つだけ) 2 × 16 = 32 = sig(sig(16))
この計算結果から、sig(sig(16)) が 2×16 と一致しているため、16は超完全数であることがわかります。
具体例2:6は超完全数ではない
次に、超完全数ではない例として n = 6 の場合を見てみます。
sig(6) = 1 + 2 + 3 + 6 = 12 sig(12) = 1 + 2 + 3 + 4 + 6 + 12 = 28 6 × 2 = 12 ≠ 28
sig(sig(6)) = 28 は 2×6 = 12 と一致しないため、6は超完全数ではありません。
C言語による実装例
以下は、与えられた数が超完全数かどうかを判定するC言語のサンプルプログラムです。約数の総和を効率よく求めるため、√n までループを回して約数をペアごとに加算する手法を採用しています。
#include<stdio.h>
// 数の約数の総和を求める関数
int divisorsum(int n){
int sum = 0; // 総和を初期化
for (int i = 1; i * i <= n; ++i){
if (n % i == 0) { // 約数を見つけたら総和に加算
if (i == (n / i))
sum += i;
else
sum += (i + n / i);
}
}
return sum;
}
int main() {
int n = 16;
int n1 = divisorsum(n);
if (2 * n == divisorsum(n1)){
printf("数 %d は超完全数です\n", n);
} else {
printf("数 %d は超完全数ではありません\n", n);
}
return 0;
}
実行結果
数 16 は超完全数です
補足:既知の超完全数の性質
超完全数としては 2, 4, 16, 64, 4096, 65536 … などが知られており、これらはすべてメルセンヌ素数に関連する2の累乗という興味深い性質を持っています。本記事のプログラムを応用すれば、任意の範囲から超完全数を探索することも可能です。
-
C#でのソケットプログラミング入門:TcpListenerとSocketクラスの使い方
System.Net.Sockets名前空間とはC#の「System.Net.Sockets」名前空間には、Windowsソケットインターフェースのマネージド実装が用意されています。これにより、.NETアプリケーションからTCP/IPなどのネットワーク通信を簡単かつ安全に扱うことができます。同期モードと非同期モードこの名前空間のソケットプログラミングには、大きく分けて2つの基本モードが存在します。同期(Synchronous):処理が完了するまで待機する方式。実装がシンプルで理解しやすく、小規模なツールに向いています。非同期(Asynchronous):処理の完了を待たずに次の処理へ進める方式
-
Linuxシェルスクリプトで学ぶ数学処理 – 第4回:四則演算から素数判定まで
今回は、数学と数値計算の視点からシェルスクリプトを学んでいきます。前回の記事ではやや複雑なスクリプト(簡易電卓)を紹介しましたが、読者にとっては少し理解しづらかったかもしれません。そこで今回は、内容を小さな単位に分割し、シェルスクリプトのもうひとつの実用的な側面を段階的に習得できるよう構成しました。 これまでの連載記事 この記事までに公開されているシェルスクリプト入門シリーズは以下の3本です。まだお読みでない方は、先に目を通しておくと理解がより深まります。 Linuxシェルと基本のシェルスクリプトを理解する – 第1回 シェルプログラミングが学べる5つのシェルスクリプト – 第2回 Linu