'Convert Long to Float Changing the number c#
I have long vairable long x = 231021578;
and when I convert it to float like float y = x;
the value of y will be 231021584
I want to know why this happen. Float is stored in 4 bytes and its range is from ±1.5x10^−45 to ±3.4x10^38 and this value is between this range.
I want to know the concept behind this change I searched alot but I didn't reach anything.
Solution 1:[1]
A 4-byte object can encode, at most, 232 different values.
Do not expect a float, with its typically 24 bit precision, to encode exactly every integer value from 0 to ±3.4x1038.
231021578 (0xDC5 1C0A), with its 27 leading significant bits*1, is not one of those float. The closest float is 231021584 (0xDC5 1C10). That has 24 or less significant bits*2.
*1
Hex: 0xDC5 1C0A
Bin: 1101 1100 0101 0001 1100 0000 1010
^-------------------------------^ 27 significant leading bits.
*2
Hex: 0xDC5 1C10
Bin: 1101 1100 0101 0001 1100 0001 0000
^---------------------------^ 24 significant leading bits.
Solution 2:[2]
Floats are an approximation and cannot easily represent ALL rational values with only 4 bytes, long is 8 bytes, so you expect to lose some information when you convert the value to a type with less precision, but on top of that float is stored differently, using base-2 notation, where as integral types like long are stored using base-10.
You will get better results with double or decimal
As a general rule I use
decimalfor discrete values that you need to maintain their exact value to a specific number of decimal places 100% of the time, for instance for monetary values on invoices and transactions. Many other measurements are acceptable to be stored and processed usingdouble.
The key take-away is that double is better for un unspecified number of decimal places, where as decimal is suited for implementations that have a fixed number of decimal places. Both of these concepts can lead to rounding errors at different points in your logic, decimal forces you to deliberately deal with rounding up front, double allows you to defer management of rounding until you need to display the value.
long x = 231021578;
float y = x;
double z = x;
decimal m = x;
Console.WriteLine("long: {0}", x);
Console.WriteLine("float: {0}", y);
Console.WriteLine("double: {0}", z);
Console.WriteLine("decimal: {0}", m);
Results:
long: 231021578
float: 2.310216E+08
double: 231021578
decimal: 231021578
- DotNetPerls - C# float Numbers
- Greg Low - SQL: Newbie Mistake #1: Using float instead of decimal
- C# Decimal
- Floating-point numeric types (C# reference)
Its out of scope for this post, but there was a healthy discussion related to this 10 years ago: Why is the data stored in a Float datatype considered to be an approximate value?
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 |
