C# 将整数与分数相乘,并在C中舍入为整数#

C# 将整数与分数相乘,并在C中舍入为整数#,c#,C#,我需要得到三分之二,四舍五入到整数 标准四舍五入: .6轮对1轮 .5轮对1轮 .4轮对0轮 从零开始,我认为这是正确的选择。但是我认为我的乘法是不对的,因为我的结果是0 int totalPoints= 71625; int twoThirds = (int)Math.Round((double)totalPoints * (2 / 3), 0, MidpointRounding.AwayFromZero); 答案应该是47750。(2/3)首先计算,因为它在括号中。结果是0,因为这是一

我需要得到三分之二,四舍五入到整数

标准四舍五入:

  • .6轮对1轮
  • .5轮对1轮
  • .4轮对0轮
从零开始,我认为这是正确的选择。但是我认为我的乘法是不对的,因为我的结果是0

int totalPoints= 71625;
int twoThirds = (int)Math.Round((double)totalPoints * (2 / 3), 0, MidpointRounding.AwayFromZero);

答案应该是47750。

(2/3)首先计算,因为它在括号中。结果是0,因为这是一个整数除法。

因为
2/3
是一个
int
计算,所以它将返回
0
,然后
0*总计点
等于
0

我会使用
2/3m
让计算结果为十进制。然后你可以得到你期望的结果

int totalPoints = 71625;
int twoThirds = (int)Math.Round(totalPoints * (2/3m), 0, MidpointRounding.AwayFromZero);

虽然@D-Shih的答案在这里是正确的,但这并不是你能得到的最好答案。即使对于十进制,三分之二也不能精确表示,2/3m也不能精确表示三分之二,因此会出现舍入误差。当你乘以这个数字时,你也会乘以误差。最好是最后一次分开。让我来说明区别:

int totalPoints = 71625;
decimal result1 = totalPoints * (2 / 3m); //47750.000000000000000000000002M
decimal result2 = (decimal)totalPoints * 2 / 3; //47750 (exactly)
double result3 = (double)totalPoints * 2 / 3; //47750 (exactly)
这没什么大不了的,因为结果是一样的。但是如果我们稍微改变一下这个例子

double totalPointsDouble = 71626.5d;

decimal result1 = (decimal)totalPointsDouble * (1 / 3m); //23875.499999999999999999999998M
decimal result2 = (decimal)totalPointsDouble * 1 / 3m; //23875.5M
double result3 = totalPointsDouble * 1 / 3; //23875.5

int oneThird1 = (int)Math.Round((decimal)totalPointsDouble * (1 / 3m), 0, MidpointRounding.AwayFromZero);
//23875
int oneThird3 = (int)Math.Round(totalPointsDouble * 1 / 3, 0, MidpointRounding.AwayFromZero);
//23876

舍入误差会传播到结果,结果会有所不同。根据数学,23876是正确的。

为什么要在对数字进行四舍五入时使用十进制?因为
十进制
具有更高的精度,虽然存储值需要更多的内存。如果要舍弃所有整数精度,为什么还要支付十进制的额外成本呢?这里唯一值得注意的是,如果输入值大于
int.MaxValue/2
,则可能需要担心溢出错误。从变量名-
totalPoints
-的外观来看,我猜在这种情况下,它可能永远不会那么大。@Chris说得好。你应该一直注意范围,这就是为什么totalPoints在相乘之前被转换为双倍的原因。没错,我忘了计算是双倍的,所以不会在这里溢出!