More fun with floating points



  • By coincidence this is on a similar topic to today's CodeSOD. I present to you this rounding algorithm copy-pasted 100s of times through our codebase.

        roundIt = 1;
        sprintf_s(rndx, "%50.12f", givenDoubleValue);

        if (rndx[strlen(rndx) - 12] == '0')
          if (rndx[strlen(rndx) - 11] == '0')
            roundIt = 0;

        if (roundIt)
        {
          rndx[strlen(rndx) - 12] = '0';
          rndx[strlen(rndx) - 11] = '0';
        }

        memset (x, '\0', sizeof x);

        strncpy_s(x, rndx, (strlen(rndx) - 10));

        givenDoubleValue = atof(x);
        if (roundIt)
          givenDoubleValue += 1.00;



  • By about the 3rd line of this code, I'd be thinking -- there must be a better way of doing this. Converting a numeric value into a string for further processing is almost always a code smell.



  • @Mithious said:

    ... copy-pasted 100s of times through our codebase.

    D:



  • So 1.01 rounds to 2?  It is similar to truncating to two decimal places and then running through ceil().

    Fun things happen to negative numbers.  -0.99 rounds to 1!

    And hopefully you never have large numbers (like 1e50) or it will abort your program.



  • Discourse touched me in a no-no place

    @jnz said:

    And hopefully you never have large numbers (like 1e50) or it will abort your program.
    %f would (should) never return exponential formatted numbers - you need %g for that:

    [pjh@pjh tmp]$ cat ./format.c
    #include <stdio.h>
    int main(void){
            double d =1e100;
            printf("%.12f\n", d);
            printf("%.12g\n", d);
            return 0;
    }
    [pjh@pjh tmp]$ make format
    cc     format.c   -o format
    [pjh@pjh tmp]$ ./format
    10000000000000000159028911097599180468360808563945281389781327557747838772170381060813469985856815104.000000000000
    1e+100
    [pjh@pjh tmp]$


  • @jnz said:

    Fun things happen to negative numbers.  -0.99 rounds to 1!

    I was wondering if anyone would notice that one. :)

     



  • I thought you were supposed to always round down and then deposit the extra into your own bank account - after beating the crap out of your copier, of course.

    Or am I 'jumping to conclusions'?


  • Discourse touched me in a no-no place

    @DrPepper said:

    By about the 3rd line of this code, I'd be thinking -- there must be a better way of doing this. Converting a numeric value into a string for further processing is almost always a code smell stench.
    FTFY


  • Discourse touched me in a no-no place

    @jnz said:

    So 1.01 rounds to 2?  It is similar to truncating to two decimal places and then running through ceil().

    Actually, it's just like running through ceil(). And then adding 1 if the original number was negative, just for giggles.
    @jnz said:
    And hopefully you never have large numbers (like 1e50) or it will abort your program.

    You can't tell that for sure; it depends on the buffer sizes and we were never told them. (Most likely true though.)


Log in to reply
 

Looks like your connection to What the Daily WTF? was lost, please wait while we try to reconnect.