How to convert efficiently double to int

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Efoe A
    New Member
    • Oct 2011
    • 1

    How to convert efficiently double to int

    Hello all.

    I have a function with paremeter double *col_zero that contains integger values. like 0, 1, 2. I am 100% sure of that.

    I cant change the inputs and I have to use these values in a for loop for a count.

    For now I am just printing my values in a file to be sure the output are as I want.

    fp is a FILE pointer.
    If I make :
    fprintf(fp, " %d or %i \n ", row_zero[k],(int)row_zero[k] );

    the output for the value 0 is
    0 or 1074266112
    0 or 1072693248

    Could somebody explain me where the second value come from? Is my cast wrong?
    If, so what is the most efficient way to deal with that??

    Thank you
  • weaknessforcats
    Recognized Expert Expert
    • Mar 2007
    • 9214

    #2
    A double is a floating point type. It has a decimal portion. An integer does not have a decimal portion. Therefore, there is no way toconvert a double to an int. If you try you will be warned by the compiler about potential loss of data as the decimal portion is tossed away. All the cast does it tell the compiler to shut up.

    You might try the ceil() function using your double rather than a cast.

    Comment

    • Banfa
      Recognized Expert Expert
      • Feb 2006
      • 9067

      #3
      In your fprinf format string you are using %d and %i. Both of these are for printing integers when you are trying to output the double you need to use %f

      read this

      Comment

      • donbock
        Recognized Expert Top Contributor
        • Mar 2008
        • 2427

        #4
        What type is row_zero?
        I'll assume it is double* (like col_zero).

        The compiler will automatically convert function arguments to the types specified by the in-scope function prototype or function definition before passing the arguments to that function. When argument type information is not available (no function declaration, old-style function declaration/definition, variable number of arguments), the compiler performs the so-called usual conversions on arguments before passing them to that function. I listed my recollection of the usual conversions below. This may not be precisely correct, but it will give you the idea.
        • float or double arguments are converted to double;
        • char, unsigned char, short, unsigned short, and int are converted to int;
        • unsigned int is converted to unsigned int;
        • long is converted to long;
        • unsigned long is converted to unsigned long.


        The function prototype for fprintf is
        Code:
        int fprintf(FILE *fp, const char *fmt, ...);
        The first two arguments are converted to the prototyped types, but the last two arguments are subject to the usual conversions. The third argument is converted to double, the last is converted to int. The format string tells fprintf to interpret the third argument as an integer, but it is actually a double so you have undefined behavior -- anything can happen. The format string tells fprintf to interpret the last argument as an int, and it is an int so that one is handled properly.

        Comment

        • Banfa
          Recognized Expert Expert
          • Feb 2006
          • 9067

          #5
          The format string tells fprintf to interpret the third argument as an integer, but it is actually a double so you have undefined behavior -- anything can happen. The format string tells fprintf to interpret the last argument as an int, and it is an int so that one is handled properly.
          Not quite Don :D

          The compiler puts all variables passed to fprintf on the stack after the conversions you provide above. A double is normally 8 bytes and an int 4 so the compiler puts 12 bytes in total on the stack.

          fprintf (and family) have no knowledge of the actual number of parameters passed, they just have a chunk of data (an array of bytes effectively) on the stack that they interpret according to the format string. The first format string parameter tells fprintf to display an int so it takes enough data from its chunk of data for an int and displays it as an int, this is 4 bytes which would be the first 1/2 of the double parameter. The second format string parameter, again, tells fprintf to display an int so it takes enough data from what's left of its chunk of data for an int and displays it as an int, this is 4 bytes which would be the second 1/2 of the double parameter. The last 4 bytes of the chunk of data is ignored.

          So the program actually outputs the data contained in the double interpreted as 2 integers and ignores completely the actual integer passed.

          Comment

          • donbock
            Recognized Expert Top Contributor
            • Mar 2008
            • 2427

            #6
            The moral here is that expert or not, undefined behavior may be worse than you can imagine.

            Comment

            Working...