C#のmodとは?余りを求める%演算子の使い方と割り算・負数の注意点
はじめに
C#で割り算の「余り」を求めたいときに使うのが、%演算子です。検索や会話では「C#のmod」「mod演算子」「剰余」「余り」と呼ばれることがありますが、C#では基本的にmodというキーワードや演算子ではなく、%を使って余りを計算します。
例えば、10を3で割ると商は3、余りは1です。この余りを求めるコードは次のように書きます。
C#int result = 10 % 3;
Console.WriteLine(result); // 1
%演算子は、偶数・奇数の判定、倍数チェック、ループ内で一定回数ごとに処理を実行する場面、配列のインデックスを循環させる処理など、実務でもよく使われます。
ただし、C#の%演算子には、負数を扱うときの結果や、小数で使う場合の誤差、0で割ったときの例外など、注意すべきポイントもあります。この記事では、C#のmodに相当する%演算子の基本から、割り算との違い、負数や小数の注意点、実用的なサンプルコードまでわかりやすく解説します。
1. C#のmodとは?%演算子で「余り」を求める処理
C#で「mod」と言われる処理は、一般的には割り算をしたときの余りを求める処理を指します。数学や他のプログラミング言語では「mod」「Modulo」「剰余演算」と呼ばれることがありますが、C#では主に%演算子を使います。
1-1. C#にmod関数はある?基本は%演算子を使う
C#には、標準でmodという名前の演算子はありません。
例えば、次のような書き方はC#ではできません。
C#int result = mod(10, 3); // C#標準ではこのようなmod関数はない
C#で余りを求める場合は、次のように%演算子を使います。
C#int result = 10 % 3;
Console.WriteLine(result); // 1
つまり、C#で「modを使いたい」と思った場合は、まず%演算子を使うと覚えておけば問題ありません。
1-2. %演算子でできること:割り算の余りを取得する
%演算子は、左側の値を右側の値で割ったときの余りを返します。
C#int remainder = 10 % 3;
この場合、10 ÷ 3は商が3で余りが1です。そのため、remainderには1が入ります。
他にも、次のような結果になります。
C#Console.WriteLine(8 % 2); // 0
Console.WriteLine(9 % 2); // 1
Console.WriteLine(15 % 4); // 3
Console.WriteLine(20 % 6); // 2
割り切れる場合は余りがないため、結果は0になります。
1-3. 「mod」「剰余」「余り」「%演算子」の違い
「mod」「剰余」「余り」「%演算子」は似た意味で使われますが、少しずつニュアンスが異なります。
「余り」は、割り算をしたときに残る数のことです。小学校の算数で出てくる「10 ÷ 3 = 3 余り 1」の「1」が余りです。
「剰余」は、余りをより数学的・プログラミング的に表した言葉です。
「mod」は、moduloの略で、剰余演算を表す言葉です。他の言語ではmodという演算子や関数が用意されている場合もあります。
「%演算子」は、C#で余りを求めるために実際に使う演算子です。
C#では、一般的なmod処理を%演算子で実現すると考えるとわかりやすいです。
2. C#の%演算子の基本的な使い方
C#の%演算子は、基本的には次の形で使います。
C#左の値 % 右の値
左の値を右の値で割ったときの余りが結果になります。
2-1. 整数同士で余りを求める基本構文
整数同士で余りを求める基本構文は次のとおりです。
C#int result = dividend % divisor;
dividendは割られる数、divisorは割る数です。
例えば、13を5で割った余りを求める場合は、次のように書きます。
C#int dividend = 13;
int divisor = 5;
int remainder = dividend % divisor;
Console.WriteLine(remainder); // 3
13 ÷ 5は商が2で余りが3なので、結果は3になります。
2-2. 具体例:10 % 3 の結果は1
10 % 3の結果は1です。
C#int result = 10 % 3;
Console.WriteLine(result); // 1
理由は、10を3で割ると次のようになるからです。
10 ÷ 3 = 3 余り 1
C#の%演算子は、この「余り」の部分を返します。
2-3. 割り切れる場合の結果は0
割り切れる場合、%演算子の結果は0になります。
C#Console.WriteLine(10 % 2); // 0
Console.WriteLine(12 % 3); // 0
Console.WriteLine(15 % 5); // 0
この性質は、倍数判定でよく使われます。
C#int number = 20;
if (number % 5 == 0)
{
Console.WriteLine("5の倍数です");
}
number % 5が0であれば、numberは5で割り切れるため、5の倍数と判定できます。
2-4. int・longなど整数型での使用例
%演算子は、intだけでなく、longなどの整数型でも使えます。
C#int intResult = 10 % 3;
Console.WriteLine(intResult); // 1
long longResult = 10000000000L % 3L;
Console.WriteLine(longResult); // 1
大きな整数を扱う場合は、intではなくlongを使うことがあります。intの範囲を超える可能性がある値では、型の範囲にも注意しましょう。
C#long totalCount = 1234567890123L;
long groupSize = 1000L;
long remainder = totalCount % groupSize;
Console.WriteLine(remainder);
整数型で%を使う場合は、結果も整数になります。小数部分が出るわけではなく、あくまで余りだけが返されます。
3. 割り算とmodの違いを理解する
C#では、/演算子と%演算子はどちらも割り算に関係しますが、返す結果が違います。
/演算子は商を求めます。一方、%演算子は余りを求めます。
3-1. /演算子は商を求める
/演算子は、割り算の結果を求める演算子です。
整数同士の割り算では、小数部分は切り捨てられます。
C#int result = 10 / 3;
Console.WriteLine(result); // 3
10 ÷ 3は本来3.333...ですが、int同士の割り算では小数部分が切り捨てられ、結果は3になります。
小数として計算したい場合は、doubleなどを使います。
C#double result = 10.0 / 3.0;
Console.WriteLine(result); // 3.3333333333333335
3-2. %演算子は余りを求める
%演算子は、割り算の商ではなく、余りを求めます。
C#int result = 10 % 3;
Console.WriteLine(result); // 1
10 ÷ 3は商が3、余りが1です。/演算子では商の3が得られ、%演算子では余りの1が得られます。
C#Console.WriteLine(10 / 3); // 3
Console.WriteLine(10 % 3); // 1
この2つは混同しやすいので、役割の違いをしっかり押さえておきましょう。
3-3. 商と余りを同時に考える例
商と余りは、セットで考えると理解しやすくなります。
C#int dividend = 17;
int divisor = 5;
int quotient = dividend / divisor;
int remainder = dividend % divisor;
Console.WriteLine($"商: {quotient}");
Console.WriteLine($"余り: {remainder}");
実行結果は次のようになります。
商: 3
余り: 2
17 ÷ 5は、5 × 3 = 15で、残りが2です。
つまり、次の関係が成り立ちます。
C#dividend == divisor * quotient + remainder
具体的には、次のようになります。
17 = 5 × 3 + 2
この関係を理解しておくと、/と%の違いがより明確になります。
3-4. Math.DivRemで商と余りを同時に取得する方法
C#では、Math.DivRemを使うと、商と余りを同時に取得できます。
C#int dividend = 17;
int divisor = 5;
int quotient = Math.DivRem(dividend, divisor, out int remainder);
Console.WriteLine($"商: {quotient}");
Console.WriteLine($"余り: {remainder}");
実行結果は次のとおりです。
商: 3
余り: 2
Math.DivRemは、戻り値として商を返し、out引数で余りを返します。
通常は/と%を別々に使っても問題ありませんが、商と余りの両方が必要な処理では、Math.DivRemを使うと意図がわかりやすくなります。
C#int totalItems = 23;
int itemsPerPage = 10;
int pages = Math.DivRem(totalItems, itemsPerPage, out int remainingItems);
Console.WriteLine($"満杯のページ数: {pages}");
Console.WriteLine($"残りの件数: {remainingItems}");
このように、ページング処理やグループ分けの処理でも、商と余りを同時に扱う場面があります。
4. 小数・浮動小数点数で%演算子を使う場合
C#の%演算子は、整数だけでなく、doubleやfloatなどの浮動小数点数にも使えます。
ただし、小数の計算では誤差が発生することがあるため、整数の剰余よりも注意が必要です。
4-1. doubleやfloatでも%演算子は使える
double型でも、次のように%演算子を使えます。
C#double result = 10.5 % 3.0;
Console.WriteLine(result); // 1.5
10.5から3.0を3回引くと1.5が残るため、結果は1.5になります。
floatでも同様に使えます。
C#float result = 10.5f % 3.0f;
Console.WriteLine(result); // 1.5
4-2. 小数の余りを求めるサンプルコード
小数の余りを求める例を見てみましょう。
C#double value = 7.5;
double step = 2.0;
double remainder = value % step;
Console.WriteLine(remainder); // 1.5
7.5を2.0で割ると、2.0 × 3 = 6.0で、残りは1.5です。
別の例です。
C#double value = 5.75;
double unit = 0.5;
double remainder = value % unit;
Console.WriteLine(remainder);
このように、一定の単位で区切ったときの残りを求めたい場合に、小数の%演算子を使うことがあります。
4-3. 小数計算で誤差に注意すべき理由
小数で%演算子を使う場合、浮動小数点数の誤差に注意が必要です。
例えば、次のようなコードでは、期待どおりに見える結果にならない場合があります。
C#double result = 0.3 % 0.1;
Console.WriteLine(result);
数学的には0.3は0.1で割り切れるため、余りは0になりそうです。しかし、doubleでは多くの小数を2進数で正確に表現できないため、ごく小さな誤差が出ることがあります。
そのため、小数の剰余結果をそのまま== 0で判定するのは避けたほうが安全です。
C#double result = 0.3 % 0.1;
double epsilon = 0.0000001;
if (Math.Abs(result) < epsilon)
{
Console.WriteLine("ほぼ0です");
}
小数では、完全一致ではなく、許容誤差を使って判定するのが一般的です。
4-4. 小数の剰余が必要なケースと注意点
小数の剰余は、一定の間隔で値を区切る処理や、周期的な値を扱う処理で使われることがあります。
例えば、角度を360度以内に収める処理では、次のように書けます。
C#double angle = 725.5;
double normalized = angle % 360.0;
Console.WriteLine(normalized); // 5.5
ただし、負の角度や誤差を考慮する場合は、単純な%だけでは不十分なことがあります。
C#double angle = -10.0;
double normalized = angle % 360.0;
Console.WriteLine(normalized); // -10
常に0以上の角度にしたい場合は、正のmod結果を得るための処理を追加します。
C#double angle = -10.0;
double normalized = ((angle % 360.0) + 360.0) % 360.0;
Console.WriteLine(normalized); // 350
小数の%演算子を使う場合は、誤差と負数の扱いに注意しましょう。
5. 負数で%演算子を使うときの注意点
C#の%演算子で特に注意したいのが、負数を扱う場合です。
数学でイメージするmodと、C#の%演算子の結果が異なることがあります。
5-1. C#の%演算子は数学的なmodと結果が異なる場合がある
C#の整数の%演算子では、余りの符号は左側の値、つまり割られる数の符号に従います。
C#Console.WriteLine(10 % 3); // 1
Console.WriteLine(-10 % 3); // -1
Console.WriteLine(10 % -3); // 1
Console.WriteLine(-10 % -3); // -1
数学的なmodでは、-10 mod 3を2と考えることがあります。しかし、C#の-10 % 3は-1になります。
この違いを知らないと、配列の循環処理や曜日計算などでバグが発生することがあります。
5-2. 負の数を割られる数にした場合の結果
左側の値が負数の場合、C#の%演算子の結果も負になることがあります。
C#Console.WriteLine(-10 % 3); // -1
Console.WriteLine(-8 % 3); // -2
Console.WriteLine(-7 % 3); // -1
これは、C#の整数除算が0に近づく方向へ切り捨てられることと関係しています。
C#Console.WriteLine(-10 / 3); // -3
Console.WriteLine(-10 % 3); // -1
次の関係で考えると理解しやすいです。
-10 = 3 × (-3) + (-1)
そのため、-10 % 3の結果は-1になります。
5-3. 負の数を割る数にした場合の結果
右側の値、つまり割る数が負数の場合も確認しておきましょう。
C#Console.WriteLine(10 % -3); // 1
Console.WriteLine(-10 % -3); // -1
C#では、余りの符号は右側の値ではなく、左側の値に従います。
そのため、10 % -3の結果は1です。右側が負数でも、左側が正数であれば、結果は正になります。
10 = (-3) × (-3) + 1
一方、-10 % -3は次のように考えられます。
-10 = (-3) × 3 + (-1)
そのため、結果は-1です。
5-4. 常に正のmod結果を得る書き方
配列のインデックスや曜日計算などでは、負の余りではなく、常に0以上の結果が欲しいことがあります。
その場合は、次のように書きます。
C#int mod = ((value % m) + m) % m;
関数にすると、次のようになります。
C#static int PositiveMod(int value, int m)
{
return ((value % m) + m) % m;
}
使用例です。
C#Console.WriteLine(PositiveMod(10, 3)); // 1
Console.WriteLine(PositiveMod(-10, 3)); // 2
Console.WriteLine(PositiveMod(7, 3)); // 1
Console.WriteLine(PositiveMod(-1, 3)); // 2
value % mが負になった場合でも、いったんmを足してから再度% mを行うことで、0以上m - 1以下の結果にできます。
ただし、この書き方は基本的にmが正数である前提です。mが0の場合はエラーになるため、必要に応じてチェックを入れましょう。
C#static int PositiveMod(int value, int m)
{
if (m <= 0)
{
throw new ArgumentException("mは正の整数である必要があります。", nameof(m));
}
return ((value % m) + m) % m;
}
5-5. 他の言語と結果が違うことがある点に注意
負数のmodは、プログラミング言語によって結果が異なることがあります。
例えば、ある言語では-10 % 3が2になる場合がありますが、C#では-1になります。
C#で負数を扱う場合は、「%の結果は左側の値の符号に従う」と覚えておくと安全です。
特に、他の言語からC#へコードを移植するときや、アルゴリズムの記事を参考に実装するときは注意しましょう。数学的なmod結果が必要な場合は、先ほどのPositiveModのような関数を使うのがおすすめです。
6. C#でmodを使う代表的な実用例
C#の%演算子は、単に余りを計算するだけでなく、さまざまな実用的な処理に使われます。
ここでは、よく使われる代表例を紹介します。
6-1. 偶数・奇数を判定する
偶数・奇数の判定では、2で割った余りを使います。
C#int number = 7;
if (number % 2 == 0)
{
Console.WriteLine("偶数です");
}
else
{
Console.WriteLine("奇数です");
}
2で割った余りが0なら偶数、0でなければ奇数です。
C#Console.WriteLine(4 % 2); // 0
Console.WriteLine(5 % 2); // 1
リスト内の数値を偶数と奇数に分ける場合にも使えます。
C#int[] numbers = { 1, 2, 3, 4, 5, 6 };
foreach (int number in numbers)
{
if (number % 2 == 0)
{
Console.WriteLine($"{number}は偶数です");
}
else
{
Console.WriteLine($"{number}は奇数です");
}
}
6-2. 倍数かどうかを判定する
ある数が特定の数の倍数かどうかを判定する場合も、%演算子を使います。
C#int number = 30;
if (number % 3 == 0)
{
Console.WriteLine("3の倍数です");
}
number % 3が0であれば、numberは3で割り切れるため、3の倍数です。
複数の条件を組み合わせることもできます。
C#int number = 15;
if (number % 3 == 0 && number % 5 == 0)
{
Console.WriteLine("3と5の両方の倍数です");
}
FizzBuzzのような定番問題でも、%演算子が使われます。
C#for (int i = 1; i <= 30; i++)
{
if (i % 15 == 0)
{
Console.WriteLine("FizzBuzz");
}
else if (i % 3 == 0)
{
Console.WriteLine("Fizz");
}
else if (i % 5 == 0)
{
Console.WriteLine("Buzz");
}
else
{
Console.WriteLine(i);
}
}
6-3. 配列やリストのインデックスを循環させる
%演算子は、配列やリストのインデックスを循環させる処理にも便利です。
例えば、次のような曜日の配列があるとします。
C#string[] days =
{
"日曜日",
"月曜日",
"火曜日",
"水曜日",
"木曜日",
"金曜日",
"土曜日"
};
インデックスを0から順に増やしていき、配列の長さを超えたら最初に戻したい場合、%を使えます。
C#for (int i = 0; i < 10; i++)
{
string day = days[i % days.Length];
Console.WriteLine(day);
}
days.Lengthは7なので、i % 7の結果は0から6の範囲に収まります。
0 % 7 = 0
1 % 7 = 1
2 % 7 = 2
...
6 % 7 = 6
7 % 7 = 0
8 % 7 = 1
このように、配列のインデックスを安全に循環させる処理に%演算子はよく使われます。
6-4. 一定回数ごとに処理を実行する
ループ処理の中で、一定回数ごとに特別な処理を実行したい場合にも%演算子が役立ちます。
例えば、5回ごとにメッセージを表示する場合は次のように書けます。
C#for (int i = 1; i <= 20; i++)
{
Console.WriteLine($"{i}回目の処理");
if (i % 5 == 0)
{
Console.WriteLine("5回ごとの処理を実行します");
}
}
i % 5 == 0になるのは、iが5、10、15、20のときです。
ログ出力、進捗表示、定期的な保存処理などでも、同じ考え方が使えます。
C#for (int i = 1; i <= 1000; i++)
{
// 何らかの処理
if (i % 100 == 0)
{
Console.WriteLine($"{i}件処理しました");
}
}
6-5. 時計・曜日・ローテーション処理に使う
%演算子は、周期的な値を扱う処理にも向いています。
例えば、24時間表記の時刻を扱う場合、24で割った余りを使うことで、時間を0から23の範囲に収められます。
C#int hour = 20;
int afterHours = 8;
int newHour = (hour + afterHours) % 24;
Console.WriteLine(newHour); // 4
20時の8時間後は28時ではなく、翌日の4時です。28 % 24の結果が4になるため、正しい時刻を表現できます。
担当者のローテーションにも使えます。
C#string[] members = { "佐藤", "鈴木", "田中" };
for (int i = 0; i < 10; i++)
{
string member = members[i % members.Length];
Console.WriteLine($"{i + 1}回目の担当: {member}");
}
このように、繰り返し循環する処理では、%演算子が非常に便利です。
7. C#の%演算子でよくあるエラーと対処法
%演算子はシンプルですが、使い方を誤るとエラーやバグの原因になります。
ここでは、C#のmod処理でよくある注意点を紹介します。
7-1. 0で割るとDivideByZeroExceptionが発生する
整数で%演算子を使うとき、右側の値が0だとDivideByZeroExceptionが発生します。
C#int result = 10 % 0; // DivideByZeroException
変数を使う場合は、割る数が0にならないようにチェックしましょう。
C#int dividend = 10;
int divisor = 0;
if (divisor != 0)
{
int result = dividend % divisor;
Console.WriteLine(result);
}
else
{
Console.WriteLine("0で割ることはできません");
}
特に、ユーザー入力や外部データを使う場合は、0チェックを忘れないようにしましょう。
7-2. 変数の型によって結果が変わる
/演算子では、整数同士の計算か小数を含む計算かによって結果が大きく変わります。
C#Console.WriteLine(10 / 3); // 3
Console.WriteLine(10.0 / 3.0); // 3.3333333333333335
%演算子でも、整数で計算するか小数で計算するかによって、結果の型や値が変わります。
C#Console.WriteLine(10 % 3); // 1
Console.WriteLine(10.5 % 3.0); // 1.5
整数の余りが欲しいのか、小数を含めた剰余が欲しいのかを明確にして、適切な型を使いましょう。
また、intの範囲を超える可能性がある場合は、longなどの型を検討します。
C#long value = 10000000000L;
long result = value % 3L;
Console.WriteLine(result);
7-3. 負数の結果を想定しないバグ
負数を扱う場合、C#の%演算子は負の結果を返すことがあります。
C#int index = -1;
int length = 5;
int result = index % length;
Console.WriteLine(result); // -1
この結果をそのまま配列のインデックスに使うと、エラーになります。
C#string[] items = { "A", "B", "C", "D", "E" };
// items[-1] はエラーになる
循環インデックスとして使いたい場合は、正のmodを返す関数を使いましょう。
C#static int PositiveMod(int value, int m)
{
return ((value % m) + m) % m;
}
string[] items = { "A", "B", "C", "D", "E" };
int index = -1;
int safeIndex = PositiveMod(index, items.Length);
Console.WriteLine(items[safeIndex]); // E
負数が入り得る処理では、%の結果が必ず正になると思い込まないことが重要です。
7-4. 小数の誤差による判定ミス
小数で%演算子を使う場合、浮動小数点数の誤差によって判定がずれることがあります。
C#double result = 0.3 % 0.1;
if (result == 0)
{
Console.WriteLine("割り切れます");
}
else
{
Console.WriteLine("割り切れません");
}
数学的には割り切れるように見えても、doubleの内部表現の都合で、完全な0にならない場合があります。
そのため、小数の結果を判定するときは、許容誤差を使いましょう。
C#double result = 0.3 % 0.1;
double epsilon = 0.0000001;
if (Math.Abs(result) < epsilon)
{
Console.WriteLine("ほぼ割り切れます");
}
else
{
Console.WriteLine("割り切れません");
}
金額計算のように正確な小数計算が必要な場合は、doubleではなくdecimalの使用も検討しましょう。
7-5. %を「パーセント計算」と混同しない
%という記号を見ると、パーセント計算を連想するかもしれません。しかし、C#の%演算子はパーセントを計算する演算子ではありません。
次のコードは、100の10%を求めるコードではありません。
C#int result = 100 % 10;
Console.WriteLine(result); // 0
これは、100を10で割った余りを求めています。
パーセント計算をしたい場合は、通常の掛け算や割り算を使います。
C#double price = 1000;
double rate = 10.0;
double discount = price * rate / 100.0;
Console.WriteLine(discount); // 100
C#の%は「余り」を求める演算子であり、「何パーセントか」を求める演算子ではない点に注意しましょう。
8. C#のmodを使ったサンプルコード集
ここでは、C#の%演算子を使った実用的なサンプルコードをまとめて紹介します。
8-1. 基本の余り計算
最も基本的な余り計算です。
C#int a = 10;
int b = 3;
int remainder = a % b;
Console.WriteLine(remainder); // 1
割り切れる場合は0になります。
C#int a = 12;
int b = 4;
int remainder = a % b;
Console.WriteLine(remainder); // 0
8-2. 偶数・奇数判定
2で割った余りを使って、偶数か奇数かを判定します。
C#int number = 11;
if (number % 2 == 0)
{
Console.WriteLine("偶数です");
}
else
{
Console.WriteLine("奇数です");
}
メソッドにすると、再利用しやすくなります。
C#static bool IsEven(int number)
{
return number % 2 == 0;
}
Console.WriteLine(IsEven(10)); // True
Console.WriteLine(IsEven(11)); // False
奇数判定のメソッドも作れます。
C#static bool IsOdd(int number)
{
return number % 2 != 0;
}
Console.WriteLine(IsOdd(10)); // False
Console.WriteLine(IsOdd(11)); // True
8-3. 倍数判定
指定した数の倍数かどうかを判定する例です。
C#static bool IsMultipleOf(int number, int divisor)
{
if (divisor == 0)
{
throw new ArgumentException("divisorに0は指定できません。", nameof(divisor));
}
return number % divisor == 0;
}
Console.WriteLine(IsMultipleOf(15, 3)); // True
Console.WriteLine(IsMultipleOf(16, 3)); // False
divisorが0の場合は、%演算子を使う前に例外を投げています。
実務では、ユーザー入力などで0が入る可能性があるため、こうしたチェックが大切です。
8-4. 正のmodを返す関数
C#の%演算子は負の余りを返すことがあるため、常に正の結果が欲しい場合は専用の関数を用意すると便利です。
C#static int PositiveMod(int value, int m)
{
if (m <= 0)
{
throw new ArgumentException("mは正の整数である必要があります。", nameof(m));
}
return ((value % m) + m) % m;
}
使用例です。
C#Console.WriteLine(PositiveMod(10, 3)); // 1
Console.WriteLine(PositiveMod(-10, 3)); // 2
Console.WriteLine(PositiveMod(0, 3)); // 0
Console.WriteLine(PositiveMod(-1, 5)); // 4
配列の循環インデックスに使う例です。
C#string[] items = { "A", "B", "C", "D", "E" };
int index = -1;
int safeIndex = PositiveMod(index, items.Length);
Console.WriteLine(items[safeIndex]); // E
このように、負数が入り得る循環処理では、正のmodを返す関数を使うと安全です。
8-5. ループ内で周期的に処理する例
一定回数ごとに処理を実行する例です。
C#for (int i = 1; i <= 20; i++)
{
Console.WriteLine($"{i}回目");
if (i % 5 == 0)
{
Console.WriteLine("5回ごとの処理です");
}
}
5回ごとに処理を行うため、i % 5 == 0を条件にしています。
進捗表示の例です。
C#for (int i = 1; i <= 1000; i++)
{
// データ処理を行う
if (i % 100 == 0)
{
Console.WriteLine($"{i}件処理しました");
}
}
配列の要素を順番に繰り返し使う例です。
C#string[] colors = { "Red", "Green", "Blue" };
for (int i = 0; i < 10; i++)
{
string color = colors[i % colors.Length];
Console.WriteLine(color);
}
i % colors.Lengthによって、インデックスが0、1、2、0、1、2と循環します。
9. C#のmodに関するよくある質問
C#のmodや%演算子について、よくある疑問をまとめます。
9-1. C#にmod演算子はありますか?
C#には、modという名前の演算子はありません。
C#でmodに相当する処理を行う場合は、%演算子を使います。
C#int result = 10 % 3;
Console.WriteLine(result); // 1
他の言語ではmodというキーワードや関数を使う場合がありますが、C#では基本的に%演算子を使うと覚えておきましょう。
9-2. C#の%は割り算ですか?
C#の%は、割り算そのものではなく、割り算をしたときの余りを求める演算子です。
商を求める場合は/演算子を使います。
C#Console.WriteLine(10 / 3); // 3
Console.WriteLine(10 % 3); // 1
/は商、%は余りを返します。
9-3. %演算子で商は取得できますか?
%演算子では商は取得できません。%演算子で取得できるのは余りです。
商を取得したい場合は/演算子を使います。
C#int quotient = 10 / 3;
int remainder = 10 % 3;
Console.WriteLine(quotient); // 3
Console.WriteLine(remainder); // 1
商と余りを同時に取得したい場合は、Math.DivRemも使えます。
C#int quotient = Math.DivRem(10, 3, out int remainder);
Console.WriteLine(quotient); // 3
Console.WriteLine(remainder); // 1
9-4. 負数のmod結果を正にするには?
C#の%演算子では、左側の値が負数の場合、結果も負になることがあります。
C#Console.WriteLine(-10 % 3); // -1
常に正のmod結果が欲しい場合は、次のように書きます。
C#int result = ((value % m) + m) % m;
関数にすると、次のようになります。
C#static int PositiveMod(int value, int m)
{
if (m <= 0)
{
throw new ArgumentException("mは正の整数である必要があります。", nameof(m));
}
return ((value % m) + m) % m;
}
使用例です。
C#Console.WriteLine(PositiveMod(-10, 3)); // 2
Console.WriteLine(PositiveMod(-1, 5)); // 4
配列の循環や曜日計算など、負数を正の範囲に収めたい場合に便利です。
9-5. 小数でも%演算子は使えますか?
はい。C#の%演算子は、doubleやfloatなどの小数でも使えます。
C#double result = 10.5 % 3.0;
Console.WriteLine(result); // 1.5
ただし、小数では浮動小数点数の誤差に注意が必要です。
C#double result = 0.3 % 0.1;
Console.WriteLine(result);
期待どおりに0にならない場合があるため、小数の剰余を判定に使う場合は、許容誤差を使いましょう。
C#double epsilon = 0.0000001;
if (Math.Abs(result) < epsilon)
{
Console.WriteLine("ほぼ0です");
}
正確な小数計算が必要な場面では、decimal型の利用も検討するとよいでしょう。
まとめ
C#でmodに相当する処理を行う場合は、基本的に%演算子を使います。%演算子は、割り算をしたときの余りを求める演算子です。
C#int result = 10 % 3;
Console.WriteLine(result); // 1
/演算子は商を求め、%演算子は余りを求めます。
C#Console.WriteLine(10 / 3); // 3
Console.WriteLine(10 % 3); // 1
また、%演算子は偶数・奇数判定、倍数判定、配列インデックスの循環、一定回数ごとの処理、時計や曜日のような周期的な処理でよく使われます。
一方で、注意点もあります。整数で0を右側に指定するとDivideByZeroExceptionが発生します。負数を扱う場合、C#の%演算子は数学的なmodと異なり、負の結果を返すことがあります。小数で使う場合は、浮動小数点数の誤差にも注意が必要です。
常に正のmod結果が必要な場合は、次のような関数を用意しておくと便利です。
C#static int PositiveMod(int value, int m)
{
if (m <= 0)
{
throw new ArgumentException("mは正の整数である必要があります。", nameof(m));
}
return ((value % m) + m) % m;
}
C#のmod処理は、基本を理解すればさまざまな場面で活用できます。%演算子の意味、割り算との違い、負数や小数の注意点を押さえて、安全で読みやすいコードを書きましょう。

