views:

140

answers:

5
warning C4244: '=' : conversion from 'unsigned int' to 'float', possible loss of data  

Shouldn't a float be able to handle any value from an int?

unsigned int: 0 to 4,294,967,295  
float 3.4E +/- 38 (7 digits) 

Wiki:

The advantage of floating-point representation over fixed-point (and

integer) representation is that it can support a much wider range of values.

Any insight would be helpful, thanks.

http://msdn.microsoft.com/en-us/library/s3f49ktz%28VS.80%29.aspx

+3  A: 

As you note in your question, the float only takes 7 digits, as opposed to the 10 digits in INT_MAX. I believe this would be the reason to give a C4244 warning at this conversion.

You
@You: Yes I did see that, however, based on where the decimal is, shouldn't we be able to represent larger numbers, even thought there are less digits?
Tommy
@Tommy: You may want to read http://en.wikipedia.org/wiki/Floating_point to learn more about how floating point values are represented, in particular the way the bits are divvied up between mantissa and exponent.
JaredReisinger
@Tommy - float can handle the range, but will lose precision (ie., you'll lose some of the least significant digits). That's a loss of data, so the warning is appropriate.
Michael Burr
e.g., try storing both 4_000_000_000 and 4_000_000_001 in your floats, and see what value they have.
sarnold
Ok, I get it now, thank you.
Tommy
+3  A: 

While float supports a wider range of values than unsigned int, it does so with less accuracy. Floats have a 23-bit mantissa which, as you posted, is only about 7 decimal digits. unsigned ints support over 9 decimal digits.

Suggestion: use double, not float.

Edit: Actually, I retract that suggestion; floating-point and integer data types are fundamentally different and are not directly convertible. What integer value do you expect to get for Single.MaxValue? For Single.NegativeInfinity? Explaining why you want to convert from float to int would be helpful.

Dour High Arch
@Dour... I tihnk he's converting the other way; from int to float. Still, knowing *why* would certainly help.
JaredReisinger
+3  A: 

'unisigned int' and 'float' both use 32 bits to store values. Since a float has a larger range, it necessarily sacrifices some precision. This means that there are some unsigned int values that cannot be accurately represented in a float. MSDN provides some more details.

JaredReisinger
+2  A: 

From wikipedia:

Single precision, called "float" in the C language family, and "real" or "real*4" in ? Fortran. This is a binary format that occupies 32 bits (4 bytes) and its significand has a precision of 24 bits (about 7 decimal digits).

With an int having 32 bits (generally) and a float having 32 bits (with part reserved for the exponent), there are a lot of int values that can't be exactly represented by the floating point type.

sje397
+1  A: 

try this to understand the situation

float f = 0.0f;
while (f < (INT_MAX-1))
   f++;

and you'll see that this is really an infinite loop on systems where int is 32 bits or less.

What will be interesting is to break into the infinite loop and see what the value is for f such that f == f + 1

franji1
The limit is exp(2, 24), because float only has 24 significant bits. `printf("%f\n", float(1<<24)+1)` prints an even number which is obviously wrong.
FredOverflow