围绕c#给出错误的答案

Ben*_*Non 9 .net c# math floating-point double

我正在为一个学校项目(自行车工厂)编制一个股票/生产计划,我必须围绕一些数字,例如必须生产的自行车(由于后果是双打).

如果我使用以下代码:

double test = Math.Ceiling(100 * 1.09);

label75.Text = Convert.ToString(test);
Run Code Online (Sandbox Code Playgroud)

我得到答案110,但那不对,它应该是109(100%的9%).虽然它似乎适用于低于9%的值.

我究竟做错了什么?

p.s*_*w.g 28

doubles和floats是二进制浮点类型.这意味着它们不能精确地表示许多十进制数字(如1.09).这导致一些微妙的舍入错误.在你的情况下,100*1.09实际上导致一个非常大于109的数字,所以Ceiling函数正确地将它舍入到最接近的整数110.

将其更改为a decimal,您将获得预期的结果:

decimal test = Math.Ceiling(100 * 1.09m); // 109
Run Code Online (Sandbox Code Playgroud)

请注意,min 1.09m将其标识为decimal文字.这是有效的,因为该decimal类型专门设计用于表示十进制数(而不仅仅是它们的二进制近似,as double和floatdo).

  • @JeroenVannevel和pswg:只是为了澄清:`decimal`,`double`和`float`都是**浮点类型**.`decimal`有29个十进制数字的精度; 它们中有多少在小数点之前或之后到达,这使得它成为**浮点**类型.这就是"浮动"在这种情况下的含义.`decimal`和`double`之间的区别在于小数表示分母中幂为10的分数,而其他两种类型表示分母中幂为2的分数. (11认同)
  • @Alireza:double也是浮点类型.float也可以命名为单个(< - > double).他们都有如上所述的问题. (2认同)

Sam*_*ica 7

浮点运算不在基数10中,它在基数2中.该double类型没有精确的基数-2等价1.09

为了说明,如果您在以下程序的末尾加上一个断点

public static void Main()
{

    double test = 100 * 1.09;
}
Run Code Online (Sandbox Code Playgroud)

比test出现的那样109.00000000000001