我有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相关问答推荐

删除数据库项目中的表

CLR如何在后台优化布尔比较操作?

IANA 到 Windows 时区映射

为什么具有可为空值的 struct 的 HashSet 非常慢?

在 ASP.NET MVC 中我可以在哪里放置自定义类?

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

C# - 获取不包括隐藏文件的文件列表

如何在任务栏顶部全屏显示 Windows 窗体?

Style 和 ControlTemplate 的区别

如何将浮点数向上舍入到 C# 中最近的 int?

静态代码块

如何将 NuGet 与 Visual C# Express 一起使用?

如何授予所有用户对我的应用程序创建的文件的完全权限?

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

关闭 Visual Studio 中所有选项卡但当前选项卡的键盘快捷键?

C# - 你如何停止计时器?

在生产环境中部署调试符号(pdb 文件)有什么风险?

POCO 是什么意思?

DataGridView 在我的两个屏幕之一上的可怕重绘性能

找不到库 hostpolicy.dll