我有3个非常大的有符号整数.

long x = long.MaxValue;
long y = long.MaxValue - 1;
long z = long.MaxValue - 2;

我想计算他们的截尾平均值.预期均值为long.MaxValue - 1,即9223372036854775806.

不可能计算为:

long avg = (x + y + z) / 3; // 3074457345618258600

注意:我读了所有关于2个数字的平均数的问题,但我不明白如何将这种技术应用于3个数字的平均数.

使用BigInteger会很容易,但是让我们假设我不会使用它.

BigInteger bx = new BigInteger(x);
BigInteger by = new BigInteger(y);
BigInteger bz = new BigInteger(z);
BigInteger bavg = (bx + by + bz) / 3; // 9223372036854775806

如果我转换成double,那么,当然,我会失go 精度:

double dx = x;
double dy = y;
double dz = z;
double davg = (dx + dy + dz) / 3; // 9223372036854780000

如果我转换成decimal,它是有效的,但我们假设我不能使用它.

decimal mx = x;
decimal my = y;
decimal mz = z;
decimal mavg = (mx + my + mz) / 3; // 9223372036854775806

Question:有没有一种方法可以只使用long类型来计算3个非常大的整数的截断平均值?不要把这个问题看成是C语言特定的,只是我更容易在C语言中提供样本.

推荐答案

这段代码可以用,但不是很漂亮吗.

它首先将所有三个值相除(对这些值求底,因此您会"丢失"余数),然后再将余数相除:

long n = x / 3
         + y / 3
         + z / 3
         + ( x % 3
             + y % 3
             + z % 3
           ) / 3

请注意,当有一个或多个负值时,上述示例并不总是正常工作.

正如与Ulugbek讨论的那样,由于下面的 comments 数量呈爆炸式增长,以下是当前针对正值和负值的最佳解决方案.

感谢Ulugbek UmirovJames SKevinZMarc van Leeuwengnasher729的回答和 comments ,这就是当前的解决方案:

static long CalculateAverage(long x, long y, long z)
{
    return (x % 3 + y % 3 + z % 3 + 6) / 3 - 2
            + x / 3 + y / 3 + z / 3;
}

static long CalculateAverage(params long[] arr)
{
    int count = arr.Length;
    return (arr.Sum(n => n % count) + count * (count - 1)) / count - (count - 1)
           + arr.Sum(n => n / count);
}

.net相关问答推荐

.NET restore/build在使用组织包的Github Action工作流中调用时获得401

为什么DotNet新的webapi;命令会为我生成不同的文件夹

向从 .NET 序列化的对象添加 Xml 属性

如何在 .net MAUI 中删除不需要编译的平台?

使用 SSH.NET 查找具有特定文件名的最新 SFTP 文件

无法使用 int.Parse 从字符串转换值

每当属性值发生变化时引发事件?

Gacutil.exe 成功添加程序集,但在资源管理器中无法查看程序集.为什么?

如何使用 C# 关键字作为属性名称?

Int32.ToString() 是特定于文化的吗?

简单委托(委托)与多播委托

Select 文件夹对话框 WPF

Microsoft.Practices.ServiceLocation 来自哪里?

日期时间是什么意思?在 C# 中是什么意思?

C# 测试字符串是否为整数?

log4net的正确使用方法(记录器命名)

string.Empty vs null.你用哪一个?

判断 .NET 中的目录和文件写入权限

如何将 Excel 序列日期编号转换为 .NET DateTime?

任何人都知道缺少枚举通用约束的好方法吗?