Double vs Decimal Rounding in C #

Why:

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

output 1.0,

a

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

outputs 0.999999999999999999999999999999

?

I understand that 1/3 cannot be calculated accurately, so there must be some kind of rounding. But why a double round of answer at 1.0, but Decimal not?

Also, why should double compute 1.0 / 3.0 be 0.3333333333333333331? If rounding is used, will the last 3 not be rounded to 0, why 1?

+6
source share
2 answers

Why 1/3 as double - 0.33333333333333331

The closest way to represent 1/3 in binary format is: 0.010101010101 ... Same as the series 1/4 + (1/4) ^ 2 + (1/4) ^ 3 + (1/4) ^ 4...

Of course, this is limited by the number of bits that you can save in double. A double bit is 64 bits, but one of them is a sign bit, and the other 11 is an exponent (consider it as a scientific designation, but in binary form). So the rest, which is called the mantissa or value, is 52 bits. Suppose you need to run 1, and then use two bits for each subsequent power 1/4. This means that you can store: 1/4 + 1/4 ^ 2 + ... + 1/4 ^ 27 which is 0.33333333333333333331

Why multiply by 3 rounds by 1

So 1/3, represented in binary format and limited by the size of the binary file: 0.01010101010101010101010101010101010101010101010101010101010101 I do not say that it is stored. As I said, you store bits starting at 1, and you use separate bits for the exponent and sign. But I think it’s useful to consider how you actually write it in base 2.

Let adheres to this "mathematical binary" representation and ignore the limits of the size of the double. You do not have to do this, but I find it convenient. If we want to take this approximation for 1/3 and multiply by 3, it will be the same as the bit offset to multiply by 2, and then add what you started with. This gives us 1/3 * 3 = 0.111111111111111111111111111111111111111111111111111111111

But can a double store? No, remember, you can only have 52 bits of the mantissa after the first 1, and this number has 54 units. Therefore, we know that it will be rounded, in this case rounded to 1.

Why for decimal you get 0.999999999999999999999999999999

In decimal form, you get 96 bits to represent an integer, with the extra bits representing an exponent of up to 28 degrees 10. So, although in the end it is all stored as binary, here we work with powers of 10, so it makes sense to think of a number in base 10. 96 bits allow us to express up to 79 228 162 543 494 333, but for representation 1/3 we are going to go with all 3, up to 28 of them, which we can shift to the right of the decimal point: 0.33333333333333333333333333333.

Multiplying this approximation by 1/3 by 3, we get a number that we can accurately represent. This is only 28 9, all shifted to the right of the decimal point: 0.999999999999999999999999999999. Thus, unlike the double, there is no second round of rounding at this point.

+14
source

This is a decimal type design optimized for precision, as opposed to a double type, which is optimized for low precision but better performance.

The decimal value type represents decimal numbers from positive 79,228,162,514,264,337,593,543,950,335 to negative 79,228,162,514,264,337,593,543,950,335.

The type of decimal value is suitable for financial calculations requiring a large number of significant integer and fractional digits and rounding errors . The Decimal type does not eliminate the need for rounding. Rather, it minimizes errors due to rounding. Thus, your code produces the result 0.99999999999999999999999999999999, not 1.

One of the reasons infinite decimal places are a necessary extension of finite decimal places is the representation of fractions. Using long division, a simple division of integers such as 1/9 becomes a repeating decimal, 0,111 ... in which the numbers are repeated endlessly. This decimal gives a quick proof for 0.999 ... = 1. Multiplying 9 times 1 produces 9 in each digit, so 9 Γ— 0.111 ... is 0.999 ... and 9 Γ— 1/9 is 1, so 0.999 ... = 1:

-2
source

All Articles