四舍五入c#给出错误答案
我正在为一个学校项目(自行车工厂)编制一个库存/生产计划,我必须对一些数字进行四舍五入,例如必须生产的自行车(由于放射性尘埃,它是双倍的) 如果我使用以下代码:四舍五入c#给出错误答案,c#,.net,math,floating-point,double,C#,.net,Math,Floating Point,Double,我正在为一个学校项目(自行车工厂)编制一个库存/生产计划,我必须对一些数字进行四舍五入,例如必须生产的自行车(由于放射性尘埃,它是双倍的) 如果我使用以下代码: double test = Math.Ceiling(100 * 1.09); label75.Text = Convert.ToString(test); 我得到的答案是110,但这不对,应该是109(100的9%)。虽然它似乎适用于低于9%的值 我做错了什么?doubles和floats是二进制浮点类型。这意味着它们不能精确地表
double test = Math.Ceiling(100 * 1.09);
label75.Text = Convert.ToString(test);
我得到的答案是110,但这不对,应该是109(100的9%)。虽然它似乎适用于低于9%的值
我做错了什么?
double
s和float
s是二进制浮点类型。这意味着它们不能精确地表示许多十进制数字(如1.09
)。这会导致一些微妙的舍入错误。在您的例子中,100*1.09实际上会导致一个比109稍大的数字,因此天花
函数会正确地将其向上舍入到最接近的整数110
将其更改为十进制,您将得到预期的结果:
decimal test = Math.Ceiling(100 * 1.09m); // 109
注意
1.09m
中的m
将其标识为decimal
文字。这是因为decimal
类型专门设计用于表示十进制数(而不仅仅是它们的二进制近似值,如double
和float
do) 浮点运算不在基数10中,而是在基数2中。double
类型没有与1.09
举例来说,如果您在以下程序的末尾放置一个断点
public static void Main()
{
double test = 100 * 1.09;
}
而
test
将显示为109.00000000000001
不相关:label75
。请告诉我这不是一个真正的变量名。这个问题在这个网站上可能已经被问过几百次了。也许几千。请同时阅读:@mikeTheLiar:让这家伙休息一下。这是一个学校项目,不是代码审查。@David早期养成的坏习惯很难改掉。此外,必须维护一个代码库,其中strSqlStatement44
是一个实际的变量名,这会让您一触即发(不,我不是在编造)。1.09没有一个基2等价物。。。。。。可以用有限数量的digits@Sam,true,但不使用标准二进制文件notation@SamIam您可以用“无限”表示有理数(注意这是有理数)通过不计算除法,而是将数字表示为一个分子和一个分母,每个分子和分母的精度都是有限的decimal
是一种浮点类型。为什么将1.09更改为Double(1.09d)不起作用,但将1.09更改为decimal会起作用?@Alireza:Double也是一种浮点类型。浮点也可以命名为单(双)浮点。它们都有如上所述的问题。@Alireza因为decimal设计用于十进制系统,就像大多数货币一样。@Alireza实际上,decimal
占用16个字节。您可以使用sizeof(decimal)
@jeroenvanevel和p.s.w.g.来验证这一点:decimal
,double
和float
都是浮点类型decimal
有29位小数精度;其中有多少在小数点之前或之后取决于您,这使其成为浮点类型。这就是“浮动”在这里的意思。decimal
和double
之间的区别在于,小数表示分母中具有十次幂的分数,而其他两种类型表示分母中具有二次幂的分数。