473,839 Members | 1,538 Online

# how to convert float to unsigned int

1 New Member
when you convert 1.7 to unsigned int, it becomes 1 or 2?
Jan 15 '13 #1
9 64101
weaknessforcats
9,208 Recognized Expert Moderator Expert
You can't convert a float to an int. An int has no decimal portion so part of your float value gets lost.

You can however convert an int to a float with a zero decimal portion. But you can't convert it back.

And typecasting a float to an int just chops off the decimal portion and any bad things that happen later will be the fault of this cast and not the fault of the compiler.
Jan 15 '13 #2
gorav sharma
2 New Member
typecasting is not possible from float to unsigned int
Jan 15 '13 #3
weaknessforcats
9,208 Recognized Expert Moderator Expert
Try this:

Expand|Select|Wrap|Line Numbers
1. int main()
2. {
3.    float x = -1.0;
4.   unsigned int y;
5.   y = (unsigned int) x;
6.
7. }
The whole point of a cast is to tell the compiler to not follow the rules and to just do what you say, however incorrect.

In the above code, y becomes 4294967295 but what can I say. The cast absolves the compiler from doing things correctly.
Jan 15 '13 #4
185 New Member
@Mr. Digits: Casting 1.7 to unsigned int becomes 1. However, you may round or ceil by including <math.h>

@WeaknessforCat s: It's totally dependent on the underlying binary representation of the number being cast. For example, casting -1 to unsigned gets 4294967295.

However, If we understand the binary representation of the number, you won't get surprised with this result. Negative numbers are represented in the two's complement form which makes it logical to get 4294967295 for -1 when dealing with it as unsigned.

For the floating point, it's another story where the binary representation has some specific bits for the sign, exponent and mantissa.
Jan 15 '13 #5
weaknessforcats
9,208 Recognized Expert Moderator Expert
All you are telling me is that when you cast the results of the cast are indeterminate. That is, the type safety of your program has been lost. It doesn't matter what is the result of the cast.

Cast errors in C are one of the biggest reasons C++ was created.
Jan 15 '13 #6
donbock
2,426 Recognized Expert Top Contributor
(I'm on the road so I can't test this on a real compiler. Let me know if I'm wrong.)

An implicit conversion is associated with the assignment operator (ref C99 Standard 6.5.16). The C99 Standard goes on to say:
6.3.1.4 Real floating and integer
1 When a finite value of real floating type is converted to an integer type other than _Bool, the fractional part is discarded (i.e., the value is truncated toward zero). If the value of the integral part cannot be represented by the integer type, the behavior is undefined.
If the destination is an unsigned int then the behavior is defined as long as the integral part of the floating value is nonnegative and can fit in an unsigned int.

Thus, the following code snippet ought to compile without errors and yield this output: "1 + 3".
Expand|Select|Wrap|Line Numbers
1. void sub(void) {
2.   float f = 1.5f;
3.   double d = 3.14159265358;
4.   unsigned int i, j;
5.   i = f;
6.   j = d;
7.   printf("%u + %u\n", i, j);
8.   }
That's not the end of the story. C99 introduced new header <fenv.h>. This header provides the fesetround() function which allows you to change the floating point rounding behavior. Options may include:
• FE_DOWNWARD (same as the floor function)
• FE_UPWARD (same as the ceil function)
• FE_TONEAREST (same as the round function)
• FE_TOWARDZERO (same as the trunc function, and 6.3.1.4)
Much of the <fenv.h> capabilities are implementation-dependent. Macros for unsupported rounding behavior are not defined. Be very careful how you try to use this capability.

I wouldn't use <fenv.h> -- it isn't portable. Portable methods to achieve these rounding behaviors are:
Expand|Select|Wrap|Line Numbers
1. #include <math.h>
2.    float f;
3.    unsigned int u;
4.    u = floor(f);   // FE_DOWNWARD
5.    u = ceil(f);    // FE_UPWARD
6.    u = round(f);   // FE_TONEAREST
7.    u = trunc(f);   // FE_TOWARDZERO
8.    u = f;          // FE_TOWARDZERO
Jan 15 '13 #7
weaknessforcats
9,208 Recognized Expert Moderator Expert
All true but I was speaking strictly of a typecast.
Jan 16 '13 #8
donbock
2,426 Recognized Expert Top Contributor
An explicit conversion (cast) should work the same as an implicit conversion (no cast).
Expand|Select|Wrap|Line Numbers
1. unsigned int i, j;
2. i = (unsigned int) 1.5f;
3. j = 3.14159265358;
4. printf("%u + %u\n", i, j);   // output: "1 + 3"
Your earlier example illustrates undefined behavior due to assigning a value outside the range of the destination type. The following assignments trigger undefined behavior because we're trying to assign a negative value to an unsigned type, not from converting floating point to integer.
Expand|Select|Wrap|Line Numbers
1. unsigned int a, b, c;
2. a = (unsigned int) -1.5f;
3. b = (unsigned int) -1.8;
4. c = (unsigned int) -1;
The asserts in the following snippet ought to prevent any undefined behavior from occurring.
Expand|Select|Wrap|Line Numbers
1. #include <limits.h>
2. #include <math.h>
3. unsigned int convertFloatingPoint(double v) {
4.    double d;
5.    assert(isfinite(v));
6.    d = trunc(v);
7.    assert((d>=0.0) && (d<=(double)UINT_MAX));
8.    return (unsigned int)d;
9.    }
Jan 16 '13 #9
weaknessforcats
9,208 Recognized Expert Moderator Expert
The point I am trying to make is that with a cast you cannot guarantee correct results using the rules of the language.

True an unsigned int has no sign bit but the cast tells the compiler that I don't really care. I know more about this program than you do and I personally guarantee only unsigned int values in that float. So forget language rules and just do what I tell you.

A correctly designed program does not have these indeterminate results kinds of behavior.

By the time you get to C++, a cast means a)I am using C code with void* or b) my design is screwed up.
Jan 16 '13 #10