Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 浮点/双精度数学。用C进行四舍五入#_C#_Floating Point_Double_Rounding - Fatal编程技术网

C# 浮点/双精度数学。用C进行四舍五入#

C# 浮点/双精度数学。用C进行四舍五入#,c#,floating-point,double,rounding,C#,Floating Point,Double,Rounding,frst:31.1 drst:31.2 有人能解释一下原因吗?好吧,数学。Round想要双倍的,而不是浮动的,这就是原因 float ff = (float)31.15; double dd = 31.15; var frst = Math.Round(ff, 1, MidpointRounding.AwayFromZero); var drst = Math.Round(dd, 1, MidpointRounding.AwayFromZero); 等于 Math.Round(ff, 1

frst:31.1

drst:31.2


有人能解释一下原因吗?

好吧,
数学。Round
想要
双倍的
,而不是
浮动的
,这就是原因

float ff = (float)31.15;

double dd = 31.15;

var frst = Math.Round(ff, 1, MidpointRounding.AwayFromZero);

var drst = Math.Round(dd, 1, MidpointRounding.AwayFromZero);
等于

Math.Round(ff, 1, MidpointRounding.AwayFromZero);
如果我们检查
(双)ff

Math.Round((double)ff, 1, MidpointRounding.AwayFromZero);
我们将看到行动中的汇总错误

Console.Write(((double)ff).ToString("R"));

最后,
Math.Round(31.14999618530273,1,中点舍入.AwayFromZero)==31.1
如预期的那样,在浮点中,所有数字在内部表示为分数,分母为2的幂

(这与小数实际上是分母为10的幂的分数的方式类似。因此
31.15
只是一种写分数的方式
3115/100

在浮点运算中,
31.15
必须在内部表示为二进制数。最接近的二进制分数是:
1111.10010011001100…重复

1100
递归(永远重复),因此该数字将被截断,具体取决于它是存储在double还是float中。在浮点运算中,它被截断为24位,在双精度运算中,它被截断为53位

31.149999618530273

因此,您可以看到这个数字转换成的double实际上略大于它转换成的float。因此很明显,它不一定会四舍五入到同一个数字,因为它的开头不是同一个数字。

因为
(float)31.15
不等于
(double)31.15
。浮点运算总是会产生舍入误差。在特殊舍入中,双精度舍入与浮点舍入不同。浮点值舍入错误是不可避免的。它们就像死亡和税收一样不可避免:@i486好吧,不总是这样,存在
float
是有原因的。@i486同样,这并不意味着你永远不应该使用
float
。C#gold徽章在哪里?IMHO本应在前17秒,而不是5小时后,作为dup关闭此文件!我很好奇为什么
(double)ff
就是
31.1499961853027
,而不是
31.1500000000000
@Gonzalo Lorieto:
double
是二进制的,
0.15==15/100=3/20
是二进制表示中的周期分数。@gonzalorieto@gonzalorieto@gonzalorieto你可以在这里读到->
Exact:  1111.100100110011001100110011001100110011001100110011001100110011001100...forever
Float:  1111.10010011001100110011
Double: 1111.1001001100110011001100110011001100110011001100110