【问题标题】:Int64 resulting a false result, why?Int64 导致错误结果,为什么?
【发布时间】:2020-02-18 18:05:49
【问题描述】:

我似乎在使用Int64 var 的算术运算中找不到准确的结果。我需要对两个 Int64 值进行平均

static void Main(string[] args)
{
    Int64 avg
    int testCase = 0;
    testCase = int.Parse(Console.ReadLine());

    for (int i = 0; i < testCase; i++)
    {
        string[] str = Console.ReadLine().Split();

        avg = ( ( Int64.Parse( str[0] ) + Int64.Parse( str[1] ) ) / 2 );

        Console.WriteLine(avg);
    }
}

输入:str[0] == 9082296538332151448str[1] == 5601337573664003844

输出:-1881554980856698162

为什么它会导致负数。试图找到平均值

【问题讨论】:

  • 9082296538332151448 + 5601337573664003844 &gt; Int64.MaxValue,你有整数溢出。
  • 你能具体说明你提供的输入吗?如果我只提供这两个数字之一,它会抛出 OverflowException,因为 9082296538332151448 无法放入 int。此外,代码不会编译,因为您在Int64 avg 之后缺少分号,这让我担心问题中的代码不是您的真实代码。你能发布一个不依赖用户输入而是硬编码输入的minimal reproducible example 吗?
  • 注意(9082296538332151448m + 5601337573664003844m) / 2 == 7341817055998077646; Decimal 对此有足够的精度。但是请注意,即使Decimal 的精度也不是无限的——更多您可以切换到BigInteger
  • 分号丢失必须在发帖时将其删除。对不起这个错误。除此之外,除非使用 Int64 ,否则您在 Int 中尝试的数字将不适合。

标签: c# int


【解决方案1】:

你有整数溢出

9082296538332151448 + 5601337573664003844 > Int64.MaxValue

14683634111996155292 > 9223372036854775807

在这种情况下,您可以使用checked 关键字抛出异常 (ArithmeticException)(并且知道出现问题出错):

avg = checked( ( Int64.Parse( str[0] ) + Int64.Parse( str[1] ) ) / 2 );

如果str[0]str[1]都保证等于或低于Int64.MaxValue,你可以把它写成

Int64 arg1 = Int64.Parse(str[0]);
Int64 arg2 = Int64.Parse(str[1]); 

arg = checked(arg1 / 2 + arg2 / 2 + (arg1 % 2 + arg2 % 2) / 2);

一般情况可以是这样的:

Int64[] data = ... 

Int64 average = 0;
Int64 rem = 0;

foreach (var item in data) {
  rem     += item % data.Length;
  average += item / data.Length + rem / data.Lenth;
  rem     %= data.Lenth; 
}   

if (rem > data.Length % 2L)
  average += 1;
else if (-rem > data.Length % 2L)
  average -= 1;  

最后,另一种(较慢但普遍)的可能性是使用BigIntegers 而不是Int64

using System.Numerics;

...

avg = (Int64)( ( BigInteger.Parse( str[0] ) + BigInteger.Parse( str[1] ) ) / 2 );

【讨论】:

  • 在这种情况下如何在两个 long.MaxValue 中使用算术运算?
  • @iamin_hridoy:两个long.MaxValue的平均值是( long.MaxValue / 2 + long.MaxValue / 2 + (long.MaxValue % 2 + long.MaxValue % 2) / 2)
猜你喜欢
  • 1970-01-01
  • 2021-07-24
  • 2022-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多