使用 int 数据类型在 C# 中添加大数字时出现问题

Issue in Adding large numbers in C# with int datatype

我正在尝试使用 int 数据类型在 C# 中添加五个大数。但结果并不正确。为什么 .net 迫使我转换为 long 并执行添加以获得正确的结果。

using System;       
public class Program
{
    public static void Main()
    {
        int i1= 256741038,i2=  623958417,i3=  467905213 ,i4= 714532089,i5=938071625;
        long l1= 256741038,l2=  623958417,l3=  467905213 ,l4= 714532089,l5=938071625; 
        long result1=i2+i3+i4+i5;
        long result2=l2+l3+l4+l5;
        long result3=(long)l2+(long)l3+(long)l4+(long)l5;
        Console.WriteLine(result1);
        Console.WriteLine(result2);
        Console.WriteLine(result3);
        }
}

int 有一个 maximum value of 2,147,483,647。如果您尝试创建一个大于此的 int(例如,通过添加两个更小的 ints),它将环绕成一个非常大的负数。这就是 result1.

中发生的事情

long 更大,最大值为 9,223,372,036,854,775,807。这足以容纳您要表示的值。

由于性能 C#(不是 dotnet)和我知道的任何其他语言都使用最大的公分母来执行操作。这在他们之间很常见。不是结果,这是必须猜测的。

所以,添加2个int数是一个可能溢出的int操作。将 int 添加到 long 是一个很长的操作。添加两个long是一个long操作。

就这么简单。如果您知道会溢出,则将其中一种类型声明为更长。

现在,您可以施放 - 您也可以将它们声明为 long,你知道的。

C# short/long/int literal format?

向您展示了所有足够的内容。

  • 1111 是一个整数
  • 1111UL 是一个无符号长整数。

因此,如果您告诉编译器要在文字中使用正确的数据类型,则无需强制转换。

您可以使用 checked keyword 查看 long result1=i2+i3+i4+i5; 正在生成 System.OverflowException: 'Arithmetic operation resulted in an overflow.',正如其他答案所说。您的操作的有效结果是 2,744,467,344,但 int 的最大值(即 Int32)是 2,147,483,647。 Long 类型(Int64 的别名)最多可以包含 9,223,372,036,854,775,807,这足以添加您的数字而不会溢出。

public static void Main()
{
    checked
    {
        int i1 = 256741038, i2 = 623958417, i3 = 467905213, i4 = 714532089, i5 = 938071625;
        long l1 = 256741038, l2 = 623958417, l3 = 467905213, l4 = 714532089, l5 = 938071625;
        long result1 = i2 + i3 + i4 + i5;
        long result2 = l2 + l3 + l4 + l5;
        long result3 = (long)l2 + (long)l3 + (long)l4 + (long)l5;
        Console.WriteLine(result1);
        Console.WriteLine(result2);
        Console.WriteLine(result3);
        Console.Read();
    }
}

除了少数例外,C# 中的类型解析并不关心您分配给 的类型。在您的情况下,编译器正在考虑的所有内容是

i2 + i3 + i4 + i5

因为每个操作数都是 int 类型,结果是 also 类型 int (或者,更准确地说,它使用加法以两个 int 作为参数和 returns int) 的运算符,即使您稍后将其分配给 long local.

通过将其中一个操作数转换为 longint, int -> int 运算符不再适用,因此选择了 long, long -> longfloat 也是如此,例如 - 只要其中一个操作数是 float,结果就是 float - 否则,a / b 会给出整数除法(运算符int, int -> int).

一般来说,您需要确保您使用的数据类型足够大以容纳结果任何中间值。如果您期望的结果不适合 int,请不要使用 int。默认情况下,C# 不检查溢出 - 您可以像这样覆盖它:

var result = checked(i2 + i3 + i4 + i5);

这样,您将得到一个异常,而不是默默地回绕到错误的 int 值。