C#中的Double与Decimal Rounding [英] Double vs Decimal Rounding in C#

查看:157
本文介绍了C#中的Double与Decimal Rounding的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么:

double dividend = 1.0;
double divisor = 3.0;
Console.WriteLine(dividend / divisor * divisor);

输出1.0,

但是: / p>

but:

decimal dividend = 1;
decimal divisor = 3;
Console.WriteLine(dividend / divisor * divisor);

输出0.99999999999999999999999999

outputs 0.9999999999999999999999999999

我明白1/3不能精确计算,所以必须有一些舍入。
但是为什么Double将答案提交到1.0,但是Decimal不是?

I understand that 1/3 can't be computed exactly, so there must be some rounding. But why does Double round the answer to 1.0, but Decimal does not?

另外,为什么双重计算1.0 / 3.0为0.33333333333333331?
如果使用四舍五入,那么最后3个不会舍入为0,为什么1?

Also, why does double compute 1.0/3.0 to be 0.33333333333333331? If rounding is used, then wouldn't the last 3 get rounded to 0, why 1?

推荐答案

强>为什么1/3是双倍的是0.33333333333333331

Why 1/3 as a double is 0.33333333333333331

以二进制代表1/3的最接近的方式是这样的:
0.0101010101。 ..
与系列相同1/4 +(1/4)^ 2 +(1/4)^ 3 +(1/4)^ 4 ...

The closest way to represent 1/3 in binary is like this: 0.0101010101... That's the same as the series 1/4 + (1/4)^2 + (1/4)^3 + (1/4)^4...

当然,这受限于可以存储在一个double中的位数。一个double是64位,但其中之一是符号位,另一个11表示指数(认为它像科学符号,但是是二进制)。所以其余的,被称为尾数或有效位数是52位。假设1开始,然后为每个后续的1/4的功率使用两位。这意味着你可以存储:
1/4 + 1/4 ^ 2 + ... + 1/4 ^ 27
这是0.33333333333333331

Of course, this is limited by the number of bits you can store in a double. A double is 64 bits, but one of those is the sign bit and another 11 represent the exponent (think of it like scientific notation, but in binary). So the rest, which is called the mantissa or significand is 52 bits. Assume a 1 to start and then use two bits for each subsequent power of 1/4. That means you can store: 1/4 + 1/4^2 + ... + 1/4 ^ 27 which is 0.33333333333333331

为什么乘以3回合1

因此,以二进制表示的1/3以双倍的大小限制:
0.010101010101010101010101010101010101010101010101010101
我不是说这是它的存储方式。像我说的那样,你存储从1开始的位,你使用指针和符号的单独的位。但是,我认为考虑如何在基础2中实际写入它是有用的。

So 1/3 represented in binary and limited by the size of a double is: 0.010101010101010101010101010101010101010101010101010101 I'm not saying that's how it's stored. Like I said, you store the bits starting after the 1, and you use separate bits for the exponent and the sign. But I think it's useful to consider how you'd actually write it in base 2.

让我们坚持使用这个数学家的二进制表示法,忽略一个双重的大小限制。你不必这样做,但我觉得很方便。如果我们要将这个近似值乘以1/3,乘以3,那么与位移到乘以2的相同,然后添加你开始的位置。这给了我们1/3 * 3 = 0.11111111111111111111111111111111111111111111111111111111

Let's stick with this "mathematician's binary" representation and ignore the size limits of a double. You don't have to do it this way, but I find it convenient. If we want to take this approximation for 1/3 and multiply by 3, that's the same as bit shifting to multiply by 2 and then adding what you started with. This gives us 1/3 * 3 = 0.111111111111111111111111111111111111111111111111111111

但可以双重存储吗?不,请记住,在前1之后,您只能拥有52位尾数,该数字有54位。所以我们知道它将是四舍五入的,在这种情况下向上舍入到1。

But can a double store that? No, remember, you can only have 52 bits of mantissa after the first 1, and that number has 54 ones. So we know that it'll be rounded, in this case rounded up to exactly 1.

为什么小数点你得到0.99999999999999999999999999

使用十进制,您可以得到96位来表示一个整数,其他位表示最多28个幂的指数。因此即使最终将它们全部存储为二进制,重新使用10的权力,所以考虑到10号的数字是有意义的.96位让我们表达高达79,228,162,514,264,337,593,543,950,335,但是代表1/3,我们将全部去3,最多28个我们可以转到小数点右边:0.33333333333333333333333333。

With decimal, you get 96 bits to represent an integer, with additional bits representing the exponent up to 28 powers of 10. So even though ultimately it's all stored as binary, here we're working with powers of 10 so it makes sense to think of the number in base 10. 96 bits lets us express up to 79,228,162,514,264,337,593,543,950,335, but to represent 1/3 we're going to go with all 3's, up to the 28 of them that we can shift to the right of the decimal point: 0.3333333333333333333333333333.

将这个近似乘以1/3乘以我们可以准确表示的数字。只有28 9,全部转移到小数点右边:0.99999999999999999999999999。所以与双倍不一样,在这一点上还没有第二轮四舍五入。

Multiplying this approximation for 1/3 by 3 gives us a number we can represent exactly. It's just 28 9's, all shifted to the right of the decimal point: 0.9999999999999999999999999999. So unlike with double's there's not a second round of rounding at this point.

这篇关于C#中的Double与Decimal Rounding的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆