how to convert float to unsigned int

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • 012345676543210
    New Member
    • Jan 2013
    • 1

    how to convert float to unsigned int

    when you convert 1.7 to unsigned int, it becomes 1 or 2?
  • weaknessforcats
    Recognized Expert Expert
    • Mar 2007
    • 9214

    #2
    You can't convert a float to an int. An int has no decimal portion so part of your float value gets lost.

    Your compiler will warn you about this. If you ignore the warning then any bad things that happen later will not be the compiler's fault.

    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.

    Comment

    • gorav sharma
      New Member
      • Jan 2013
      • 2

      #3
      typecasting is not possible from float to unsigned int

      Comment

      • weaknessforcats
        Recognized Expert Expert
        • Mar 2007
        • 9214

        #4
        Try this:

        Code:
        int main()
        {
           float x = -1.0;
          unsigned int y;
          y = (unsigned int) x;
        
        }
        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.

        Comment

        • Anas Mosaad
          New Member
          • Jan 2013
          • 185

          #5
          @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.

          Comment

          • weaknessforcats
            Recognized Expert Expert
            • Mar 2007
            • 9214

            #6
            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.

            Comment

            • donbock
              Recognized Expert Top Contributor
              • Mar 2008
              • 2427

              #7
              (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".
              Code:
              void sub(void) {
                float f = 1.5f;
                double d = 3.14159265358;
                unsigned int i, j;
                i = f;
                j = d;
                printf("%u + %u\n", i, j);
                }
              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:
              Code:
              #include <math.h>
                 float f;
                 unsigned int u;
                 u = floor(f);   // FE_DOWNWARD
                 u = ceil(f);    // FE_UPWARD
                 u = round(f);   // FE_TONEAREST
                 u = trunc(f);   // FE_TOWARDZERO
                 u = f;          // FE_TOWARDZERO
              Last edited by donbock; Jan 16 '13, 12:02 AM. Reason: Added sentence about unsigned int and changed the snippet accordingly.

              Comment

              • weaknessforcats
                Recognized Expert Expert
                • Mar 2007
                • 9214

                #8
                All true but I was speaking strictly of a typecast.

                Comment

                • donbock
                  Recognized Expert Top Contributor
                  • Mar 2008
                  • 2427

                  #9
                  An explicit conversion (cast) should work the same as an implicit conversion (no cast).
                  Code:
                  unsigned int i, j; 
                  i = (unsigned int) 1.5f; 
                  j = 3.14159265358; 
                  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.
                  Code:
                  unsigned int a, b, c;
                  a = (unsigned int) -1.5f;
                  b = (unsigned int) -1.8;
                  c = (unsigned int) -1;
                  The asserts in the following snippet ought to prevent any undefined behavior from occurring.
                  Code:
                  #include <limits.h>
                  #include <math.h>
                  unsigned int convertFloatingPoint(double v) {
                     double d;
                     assert(isfinite(v));
                     d = trunc(v);
                     assert((d>=0.0) && (d<=(double)UINT_MAX));
                     return (unsigned int)d;
                     }

                  Comment

                  • weaknessforcats
                    Recognized Expert Expert
                    • Mar 2007
                    • 9214

                    #10
                    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.

                    Comment

                    Working...