steviekm3
steviekm3

Reputation: 1053

A C routine to round a float to n significant digits?

Suppose I have a float. I would like to round it to a certain number of significant digits.

In my case n=6.

So say float was f=1.23456999;

round(f,6) would give 1.23457

f=123456.0001 would give 123456

Anybody know such a routine ?

Here it works on website: http://ostermiller.org/calc/significant_figures.html

Upvotes: 13

Views: 19251

Answers (6)

Paul R
Paul R

Reputation: 213049

Something like this should work:

double round_to_n_digits(double x, int n)
{ 
    double scale = pow(10.0, ceil(log10(fabs(x))) + n);

    return round(x * scale) / scale;
}

Alternatively you could just use sprintf/atof to convert to a string and back again:

double round_to_n_digits(double x, int n)
{ 
    char buff[32];

    sprintf(buff, "%.*g", n, x);

    return atof(buff);
}

Test code for both of the above functions: http://ideone.com/oMzQZZ


Note that in some cases incorrect rounding may be observed, e.g. as pointed out by @clearScreen in the comments below, 13127.15 is rounded to 13127.1 instead of 13127.2.

Upvotes: 3

Mitendra
Mitendra

Reputation: 1554

Print to 16 significant digit.

double x = -1932970.8299999994;
char buff[100];
snprintf(buff, sizeof(buff), "%.16g", x);
std::string buffAsStdStr = buff;

std::cout << std::endl << buffAsStdStr ;

Upvotes: -3

Daniel Gehriger
Daniel Gehriger

Reputation: 7468

Multiply the number by a suitable scaling factor to move all significant digits to the left of the decimal point. Then round and finally reverse the operation:

#include <math.h>

double round_to_digits(double value, int digits)
{
    if (value == 0.0) // otherwise it will return 'nan' due to the log10() of zero
        return 0.0;

    double factor = pow(10.0, digits - ceil(log10(fabs(value))));
    return round(value * factor) / factor;   
}

Tested: http://ideone.com/fH5ebt

Buts as @PascalCuoq pointed out: the rounded value may not exactly representable as a floating point value.

Upvotes: 10

Massimiliano
Massimiliano

Reputation: 8032

This should work (except the noise given by floating point precision):

#include <stdio.h>
#include <math.h>

double dround(double a, int ndigits);

double dround(double a, int ndigits) {

  int    exp_base10 = round(log10(a));
  double man_base10 = a*pow(10.0,-exp_base10);
  double factor     = pow(10.0,-ndigits+1);  
  double truncated_man_base10 = man_base10 - fmod(man_base10,factor);
  double rounded_remainder    = fmod(man_base10,factor)/factor;

  rounded_remainder = rounded_remainder > 0.5 ? 1.0*factor : 0.0;

  return (truncated_man_base10 + rounded_remainder)*pow(10.0,exp_base10) ;
}

int main() {

  double a = 1.23456999;
  double b = 123456.0001;

  printf("%12.12f\n",dround(a,6));
  printf("%12.12f\n",dround(b,6));

  return 0;
}

Upvotes: 3

David Schwartz
David Schwartz

Reputation: 182819

#include <stdio.h> 
#include <string.h>
#include <stdlib.h>

char *Round(float f, int d)
{
    char buf[16];
    sprintf(buf, "%.*g", d, f);
    return strdup(buf);
}

int main(void)
{
    char *r = Round(1.23456999, 6);
    printf("%s\n", r);
    free(r);
}

Output is:

1.23457

Upvotes: 5

rekire
rekire

Reputation: 47965

If you want to print a float to a string use simple sprintf(). For outputting it just to the console you can use printf():

printf("My float is %.6f", myfloat);

This will output your float with 6 decimal places.

Upvotes: 1

Related Questions