Is there a function to round a float in C or do I need to write my own?

后端 未结 7 1305
旧时难觅i
旧时难觅i 2020-11-27 07:02

Is there a function to round a float in C or do I need to write my own?

float conver = 45.592346543;

I would

相关标签:
7条回答
  • 2020-11-27 07:18

    To print a rounded value, @Matt J well answers the question.

    float x = 45.592346543;
    printf("%0.1f\n", x);  // 45.6
    

    As most floating point (FP) is binary based, exact rounding to one decimal place is not possible when the mathematically correct answer is x.1, x.2, ....

    To convert the FP number to the nearest 0.1 is another matter.

    Overflow: Approaches that first scale by 10 (or 100, 1000, etc) may overflow for large x.

    float round_tenth1(float x) {
      x = x * 10.0f;
      ...
    }
    

    Double rounding: Adding 0.5f and then using floorf(x*10.0f + 0.5f)/10.0 returns the wrong result when the intermediate sum x*10.0f + 0.5f rounds up to a new integer.

    // Fails to round 838860.4375 correctly, comes up with 838860.5 
    // 0.4499999880790710449 fails as it rounds to 0.5
    float round_tenth2(float x) {
      if (x < 0.0) {
        return ceilf(x*10.0f + 0.5f)/10.0f;
      }
      return floorf(x*10.0f + 0.5f)/10.0f;
    }
    

    Casting to int has the obvious problem when float x is much greater than INT_MAX.


    Using roundf() and family, available in <math.h> is the best approach.

    float round_tenthA(float x) {
      double x10 = 10.0 * x;
      return (float) (round(x10)/10.0);
    }
    

    To avoid using double, simply test if the number needs rounding.

    float round_tenthB(float x) {
      const float limit = 1.0/FLT_EPSILON;
      if (fabsf(x) < limit) {
        return roundf(x*10.0f)/10.0f;
      }
      return x;
    }
    
    0 讨论(0)
  • 2020-11-27 07:20

    As Rob mentioned, you probably just want to print the float to 1 decimal place. In this case, you can do something like the following:

    #include <stdio.h>
    #include <stdlib.h>
    
    int main()
    {
      float conver = 45.592346543;
      printf("conver is %0.1f\n",conver);
      return 0;
    }
    

    If you want to actually round the stored value, that's a little more complicated. For one, your one-decimal-place representation will rarely have an exact analog in floating-point. If you just want to get as close as possible, something like this might do the trick:

    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    
    int main()
    {
      float conver = 45.592346543;
      printf("conver is %0.1f\n",conver);
    
      conver = conver*10.0f;
      conver = (conver > (floor(conver)+0.5f)) ? ceil(conver) : floor(conver);
      conver = conver/10.0f;
    
      //If you're using C99 or better, rather than ANSI C/C89/C90, the following will also work.
      //conver = roundf(conver*10.0f)/10.0f;
    
      printf("conver is now %f\n",conver);
      return 0;
    }
    

    I doubt this second example is what you're looking for, but I included it for completeness. If you do require representing your numbers in this way internally, and not just on output, consider using a fixed-point representation instead.

    0 讨论(0)
  • 2020-11-27 07:27
    #include <math.h>
    
    double round(double x);
    float roundf(float x);
    

    Don't forget to link with -lm. See also ceil(), floor() and trunc().

    0 讨论(0)
  • 2020-11-27 07:29

    Just to generalize Rob's answer a little, if you're not doing it on output, you can still use the same interface with sprintf().

    I think there is another way to do it, though. You can try ceil() and floor() to round up and down. A nice trick is to add 0.5, so anything over 0.5 rounds up but anything under it rounds down. ceil() and floor() only work on doubles though.

    EDIT: Also, for floats, you can use truncf() to truncate floats. The same +0.5 trick should work to do accurate rounding.

    0 讨论(0)
  • 2020-11-27 07:32

    you can use #define round(a) (int) (a+0.5) as macro so whenever you write round(1.6) it returns 2 and whenever you write round(1.3) it return 1.

    0 讨论(0)
  • 2020-11-27 07:36

    Sure, you can use roundf(). If you want to round to one decimal, then you could do something like: roundf(10 * x) / 10

    0 讨论(0)
提交回复
热议问题