Is Double Multiplication Broken in .Net

Is double Multiplication Broken in .NET?

Because you've misunderstood floating point arithmetic and how data is stored.

In fact, your code isn't actually performing any arithmetic at execution time in this particular case - the compiler will have done it, then saved a constant in the generated executable. However, it can't store an exact value of 6.9, because that value cannot be precisely represented in floating point point format, just like 1/3 can't be precisely stored in a finite decimal representation.

See if this article helps you.

Double multiplication in c#

Most likely, in case you are using DirectX (the only reason I can find behind your problematic), this problem seems related to the fact that every time a Device is created and/or handled, it forces the FPU to single precision mode, thus losing accuracy and causing double, long, decimal variables to get truncated. If I try a IEEE-754 floating point converter and input your data, I get this result, which is precisely your case: your data, at some point, was read as a double-precision number, but then it got truncated into a single.precision floating point number as you can see:

Sample Image

This problem can be solved by explicitly building the Device object under the flag FpuPreserve.

I also had this very problem, and in the beginning though about incorrect casting or so, until after a long trace found out the values got truncated after I built a DirectX Device object.

C# precision calculations multiplying int and double

Floating-point types (and calculations) are imprecise in nature. They work in binary, not in decimal, and hence calculations yield “unexpected” decimal values.

Compare it with this:

Console.WriteLine((197688 * 0.1m) == 19768.800000000003m); // False
Console.WriteLine((197688 * 0.1m) == 19768.8m); // True

The result is as you'd expect, because decimal is used. As the name suggests, it's suited for decimal calculations because of its internal representation.

Side note: The rule of thumb is never use floating-point types for monetary calculations. Exactly becuase of precision issues with decical values.

How to use double datatype while multiplying with the Integer value?

In .NET the decimal datatype represents fixed precision numbers. The double datatype represents floating-point numbers, which are an approximation and should not be used when absolute precision is required.

Is Vb.Net Math Broken?

This is just how floating numbers work. They work with some level of precision, when you write 1.66 it might actually be stored as 1.66000000000000000001 or 1.65999999999999999 in memory. So when you start adding these numbers together that small error adds up.

If you want to avoid this, you could use System.Decimal data type which will solve this issue most scenarios (it uses a different model to store the value in memory that preserves the exact value).

For example, try

?1.66D + 0.83D

D suffix means that the value is of type Decimal

WRONG SUM OF DOUBLES IN VB .NET

A double value can only represent certain numbers exactly. Most values can only be approximated. See Wikipedia for some more detailed explanation.
You basically have a fixed number of decimal digits, depending on the size of the floating point number (compare Single and Double) and an exponent that represents the number. Due to this even simple calculations may produce some rounding errors.

To avoid this you can use a datatype like Decimal that is represented exactly and is often used for financial calculation for example to avoid these errors.

Understanding the given calculation (cast + multiplication)

That is exactly the case. It's just that 10.9 is slightly less than 10.9 due to the way floating point numbers are represented (10.9 cannot be represented exactly, so you get an approximation, which in this case is something like 10.89999999...). The cast then truncates any digits following the decimal point. So you get 108.

Exact values are as follows here (obtained with Jon Skeet's DoubleConverter class):

10.9         -> 10.9000000000000003552713678800500929355621337890625
(float) 10.9 -> 10.8999996185302734375

Multiplying that float by 10 and then cutting off all decimal places will obviously result in 108.



Related Topics



Leave a reply



Submit