私が持っているとしましょうfloat
。有効桁数に四捨五入したいと思います。
私の場合n=6
。
つまり、フロートはf=1.23456999;
round(f,6)
与えるだろう1.23457
f=123456.0001
与えるだろう123456
誰もがそのようなルーチンを知っていますか?
ここでそれはウェブサイトで動作します:http://ostermiller.org/calc/significant_figures.html
私が持っているとしましょうfloat
。有効桁数に四捨五入したいと思います。
私の場合n=6
。
つまり、フロートは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
しかし、@ 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("%s\n", 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
これは機能するはずです(浮動小数点の精度によって与えられるノイズを除く):
#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;
}
有効数字 16 桁まで出力します。
double x = -1932970.8299999994;
char buff[100];
snprintf(buff, sizeof(buff), "%.16g", x);
std::string buffAsStdStr = buff;
std::cout << std::endl << buffAsStdStr ;