CS801~2000

C# コンパイルエラー CS1021について解説 – 整数定数が大きすぎる原因と対策

CS1021は、C#のコンパイラが整数リテラルの値が許容範囲を超えた場合に発生するエラーです。

例えば、整数型の変数への代入や、BigIntegerの初期化時に指定した数値がUInt64.MaxValueを上回ると、このエラーが表示されます。

適切な数値やデータ型を選択するよう確認してください。

エラー CS1021の原因

整数リテラルが大きすぎる理由

整数リテラルが大きすぎる理由は、C#で利用される各数値型に決められた範囲が存在するためです。

整数リテラルを記述する際に、その値が型の範囲を超えると、コンパイルエラー CS1021 が発生します。

ここでは、数値型の範囲とその制約、そして特にUInt64.MaxValueを超えた場合の問題について説明します。

数値型の範囲と制約

C#では、各整数型(たとえばintuintlongulong)ごとに取り扱える値の範囲が決まっています。

例えば、int型は231から2311までの値しか扱えません。

数値リテラルがこれらの範囲から外れるとエラーが発生するため、リテラル値が選択された型に適合していることが重要です。

実例として、以下のコードはint型に対して非常に大きな値を割り当てようとしてエラーが発生します。

using System;
class Program
{
    static void Main(string[] args)
    {
        // 以下の行はコンパイルエラー CS1021 を引き起こす可能性があります。
        // int number = 18_446_744_073_709_552_000;
        Console.WriteLine("整数リテラルの大きさの確認");
    }
}
整数リテラルの大きさの確認

UInt64.MaxValue超過の問題

UInt64型の最大値は2641であり、整数リテラルがこの上限を超えるとエラーとなります。

特に、リテラルにアンダースコアで区切られた桁数が多い場合、視覚的には読みやすいものの、型の制約を超えた値を記述してしまうリスクがあります。

実際に、以下のケースではUInt64.MaxValueを超えた値を記述しているため、エラーが発生します。

using System;
class Program
{
    static void Main(string[] args)
    {
        // コンパイル時にUInt64.MaxValueを超えるためエラーとなります。
        // ulong largeNumber = 18_446_744_073_709_552_000;
        Console.WriteLine("UInt64の上限を超える例");
    }
}
UInt64の上限を超える例

BigInteger利用時の留意点

BigInteger型は非常に大きな整数を扱うための型ですが、インスタンス化の際にも適切な初期化方法が求められます。

特に、リテラルとして記述された数値が直接渡された場合、同様のエラーが発生する可能性があります。

インスタンス化時の制限事項

BigIntegerのインスタンス化においても、リテラルによっては内部的に扱えない大きな数値として認識される場合があります。

そのため、インスタンス化の際は、文字列や配列を用いるなど、別のアプローチが必要となることがあります。

以下のサンプルコードは、BigIntegerのインスタンス化における注意点を示しています。

using System;
using System.Numerics;
class Program
{
    static void Main(string[] args)
    {
        // 直接リテラルを使用するとエラーが発生する場合があるため注意が必要です。
        // var bigNum = new BigInteger(18_446_744_073_709_552_000);
        // 正しいインスタンス化方法の例:文字列からBigIntegerに変換
        BigInteger bigNumFromString = BigInteger.Parse("18446744073709552000");
        Console.WriteLine("BigIntegerの値: " + bigNumFromString);
    }
}
BigIntegerの値: 18446744073709552000

エラーが発生する状況

int型の利用例

int型に対して非常に大きなリテラル値を割り当てるケースは、エラーが発生する代表的な例です。

整数リテラルがint型の範囲(231から2311)を超えると、コンパイル時にエラーが発生します。

コード例と発生パターン

以下のコード例は、int型に対して大きな値を割り当てようとすることで、エラーが発生するパターンを示しています。

実際にコンパイルする際は、エラーとなる行はコメントアウトしてあります。

using System;
class Program
{
    static void Main(string[] args)
    {
        // 以下の行は整数リテラルがint型の範囲を超えているため、コンパイルエラー CS1021 となります。
        // int tooLarge = 18_446_744_073_709_552_000;
        Console.WriteLine("int型に大きな値を割り当てる例");
    }
}
int型に大きな値を割り当てる例

BigIntegerの利用例

BigIntegerは通常、非常に大きな整数を扱う時に利用されますが、誤ったリテラルの指定でエラーが発生するケースがあります。

特にリテラル値を直接渡す場合、コンパイラがその値を内部で適切な型に変換できないことがあります。

エラーに至る具体的な記述

次のコード例は、直接リテラルを使用してBigIntegerのインスタンスを作成しようとした場合のエラーケースを示しています。

コンパイルエラーを避けるため、エラー箇所はコメントアウトしてあります。

using System;
using System.Numerics;
class Program
{
    static void Main(string[] args)
    {
        // 次の行はリテラルが大きすぎるためエラーとなります。
        // var bigNumberError = new BigInteger(18_446_744_073_709_552_000);
        // 正しくは以下のように文字列で初期化する方法を用います。
        BigInteger bigNumber = BigInteger.Parse("18446744073709552000");
        Console.WriteLine("BigIntegerで正しい値の取り扱い例");
    }
}
BigIntegerで正しい値の取り扱い例

エラー解消の対策

適切なデータ型の選択

エラーを防ぐためには、扱おうとする数値に対して最適なデータ型を選択することが大切です。

数値が型の範囲に収まるように調整するか、またはBigIntegerなどの大きな数値を扱える型を利用します。

型ごとの特徴と選定方法

  • int型: 231から2311までの整数を扱う。一般的な用途に適しています。
  • long型: 263から2631までの整数を扱う。より大きな整数を必要とする場合に利用できます。
  • ulong型: 0から2641までの整数を扱う。正の整数のみを対象にする場合に適しています。
  • BigInteger型: ほぼ制限なく整数を扱うことができますが、インスタンス化の際の初期化方法に注意が必要です。

適切な型を選ぶことで、リテラルの値が型の範囲内に収まり、エラーを防止することができます。

数値リテラルの調整方法

数値リテラルが直接型の範囲を超える場合、リテラルに型指定子を付加して明示的に型を指定するか、または数値を調整して範囲内に収める必要があります。

たとえば、ulong型のリテラルの場合は末尾にULを付けることが推奨されます。

using System;
class Program
{
    static void Main(string[] args)
    {
        // ulong型のリテラルでは、ULサフィックスを利用して型を明示します。
        ulong adjustedNumber = 18_446_744_073_709_551_615UL;
        Console.WriteLine("調整後のulongリテラル: " + adjustedNumber);
    }
}
調整後のulongリテラル: 18446744073709551615

定数表記の見直し

定数やリテラルの記述方法を工夫することで、視認性の向上とエラー回避につながります。

ここでは、アンダースコアの利用方法や、数値の範囲内に収めるための工夫について説明します。

アンダースコアの利用による視認性向上

C#では、数値リテラルにアンダースコアを挿入することで、桁区切りを行い視認性を向上させることができます。

ただし、アンダースコアは数値の意味を変えるものではなく、あくまで読みやすさを向上するための記法です。

記述ミスがないように注意してください。

using System;
class Program
{
    static void Main(string[] args)
    {
        // アンダースコアを用いて桁区切りを行い、リテラルの視認性を向上しています。
        ulong numberWithUnderscores = 18_446_744_073_709_551_615UL;
        Console.WriteLine("アンダースコア利用例: " + numberWithUnderscores);
    }
}
アンダースコア利用例: 18446744073709551615

範囲内に収めるための工夫

リテラル値が大きすぎる場合、数値そのものや型指定子を調整する必要があります。

場合によっては、リテラルを分割して計算する方法や、文字列を利用した初期化が有効です。

特にBigIntegerでは、直接大きなリテラルを渡すのではなく、文字列から変換する方法が推奨されます。

using System;
using System.Numerics;
class Program
{
    static void Main(string[] args)
    {
        // 大きな数値を扱う場合は、文字列を用いてBigIntegerに変換する手法が安全です。
        BigInteger safeBigNumber = BigInteger.Parse("18446744073709552000");
        Console.WriteLine("安全に初期化したBigInteger: " + safeBigNumber);
    }
}
安全に初期化したBigInteger: 18446744073709552000

まとめ

この記事では、整数リテラルが大きすぎるために発生するコンパイルエラー CS1021 の原因と、実際に起こる状況について解説しています。

具体的には、各数値型の取り扱い範囲、UInt64.MaxValue の超過、BigInteger利用時の注意点、そしてエラー解消のためのデータ型選択とリテラル表記の工夫について説明しています。

関連記事

Back to top button
目次へ