Проблема в добавлении больших чисел в C# с типом данных int - PullRequest
1 голос
/ 20 февраля 2020

Я пытаюсь добавить пять больших чисел в C# с int dataType. Но результат оказался неверным. почему .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);
        }
}

Ответы [ 4 ]

2 голосов
/ 20 февраля 2020

За некоторыми исключениями, разрешение типа в C# не заботится о типе, который вы назначаете для . Все, что компилятор рассматривает в вашем случае, это

i2 + i3 + i4 + i5

Поскольку каждый из операндов имеет тип int, результат будет также типа int (или, точнее, , он использует оператор сложения, который принимает два int s в качестве аргументов и возвращает int), хотя впоследствии вы присваиваете его long local.

Путем приведения одного из операндов к long, оператор int, int -> int больше не подходит, и выбран long, long -> long. Например, то же самое относится и к float - как только один из операндов равен float, результат равен float - в противном случае a / b дает целочисленное деление (оператор int, int -> int).

В общем, вам нужно убедиться, что тип данных, с которыми вы работаете, достаточно большой, чтобы в нем содержались и любые промежуточные значения. Если вы ожидаете результат, который не вписывается в int, не используйте int. По умолчанию C# не проверяет переполнение - вы можете переопределить его следующим образом:

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

Таким образом, вместо тихого перехода к неправильному значению int, вы получите исключение.

2 голосов
/ 20 февраля 2020

Из-за производительности C# (не делайте tnet) и ЛЮБОГО другого известного мне языка, используйте ЛУЧШИЙ общий знаменатель для выполнения операций. Это ОБЩЕЕ, между ними. не результат, о котором следовало бы догадываться.

ТАК, добавление 2 чисел int - это операция int, которая может переполниться. Добавление int к long - это долгая операция. Добавление двух long - это длинная операция.

Просто так. Если вы знаете, что переполнитесь, то объявите один из типов длиннее.

Теперь вы МОЖЕТЕ разыграть заклинание - вы МОЖЕТЕ также просто объявить их как длинные, вы знаете.

C# Литеральный формат short / long / int?

показывает все, что вам нужно.

  • 1111 - это int
  • 1111UL - это длинный без знака.

Таким образом, нет необходимости приводить, если вы сообщаете компилятору правильный тип данных для использования в литерале.

1 голос
/ 20 февраля 2020

Вы можете использовать checked ключевое слово , чтобы увидеть, что long result1=i2+i3+i4+i5; генерирует System.OverflowException: 'Arithmetic operation resulted in an overflow.', как говорят другие ответы. Допустимый результат вашей операции - 2 744 467 344, но максимальное значение типа int (которое является просто Int 32) составляет 2 147 483 647. Длинный тип (псевдоним для 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();
    }
}
0 голосов
/ 20 февраля 2020

int имеет максимальное значение 2 147 483 647 . Если вы попытаетесь сделать int больше этого (например, добавив два меньших ints), оно превратится в очень большое отрицательное число. Это то, что происходит в result1.

long намного больше и имеет максимальное значение 9,223,372,036,854,775,807. Это достаточно большой размер для хранения значений, которые вы пытаетесь представить.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...