C例程将浮子绕到n个重要数字

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

本文关键字:数字 例程      更新时间:2023-10-16

假设我有一个float。我想将其舍入一定数量的大数字。

在我的情况下n=6

所以说float是 f=1.23456999;

round(f,6)将提供1.23457

f=123456.0001将提供123456

有人知道这样的例行程序吗?

在这里它在网站上工作:http://ostermiller.org/calc/significant_figures.html

将数字乘以合适的缩放系数,以将所有有意义的数字移动到小数点的左侧。然后圆,最后逆转操作:

#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;   
}

测试:http://ideone.com/fh5ebt

buts @pascalcuoq指出:圆形值可能无法完全表示为浮点值。

#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("%sn", r);
    free(r);
}

输出是:

1.23457

类似的东西应该有效:

double round_to_n_digits(double x, int n)
{ 
    double scale = pow(10.0, ceil(log10(fabs(x))) + n);
    return round(x * scale) / scale;
}

另外,您可以只使用sprintf/atof转换为字符串,然后再次返回:

double round_to_n_digits(double x, int n)
{ 
    char buff[32];
    sprintf(buff, "%.*g", n, x);
    return atof(buff);
}

上述两个功能的测试代码:http://ideone.com/omzqzz


请注意,在某些情况下可能会观察到不正确的舍入,例如正如@clearscreen在下面的评论中指出的那样,13127.15舍入至13127.1而不是13127.2。

这应该有效(除了浮点精度给出的噪声外):

#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.12fn",dround(a,6));
  printf("%12.12fn",dround(b,6));
  return 0;
}

如果要将浮子打印到字符串,请使用简单的sprintf()。为了将其输出到控制台,您可以使用printf()

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

这将用6个小数位置输出您的浮标。

打印到16个重要数字。

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