我有三组数字,一个测量(在0-1范围内)两个错误(正面和负面。这些数字应该与有效数字的数量一致地显示,向上舍入,这对应于任何一个数字中的第一个非零输入。
如果测量值为1,则跳过该测量要求(即仅需要考虑误差中的数字)。例如:
0.95637 (+0.00123, -0.02935) --> 0.96 +0.00 -0.03
1.00000 (+0.0, -0.0979) --> 1.0 +0.0 -0.1 (note had to truncate due to -ve error rounding up at first significant digit)
现在,通过记录log10(num)来获得第一个非零数字是很容易的,但是我正试图以干净的方式进行剥离和舍入工作。
所有数据类型都是双倍的,选择的语言是C ++。欢迎所有和任何想法!
答案 0 :(得分:2)
使用
cout.setf(ios::fixed, ios::floatfield);
cout.precision(2);
在输出数字之前,应该按照您的要求进行操作。
编辑:作为示例
double a = 0.95637;
double b = 0.00123;
double c = -0.02935;
cout.setf(ios::fixed, ios::floatfield);
cout.precision(2);
cout << a << endl;
cout << b << endl;
cout << c << endl;
将输出:
0.96
0.00
-0.03
进一步编辑:你显然必须调整精确度以匹配你的重要数字。
答案 1 :(得分:2)
我的C ++生锈了,但下面不会这样做:
std::string FormatNum(double measurement, double poserror, double negerror)
{
int precision = 1; // Precision to use if all numbers are zero
if (poserror > 0)
precision = ceil(-1 * log10(poserror));
if (negerror < 0)
precision = min(precision, ceil(-1 * log10(abs(negerror))));
// If you meant the first non-zero in any of the 3 numbers, uncomment this:
//if( measurement < 1 )
// precision = min(precision, ceil(-1 * log10(measurement)));
stringstream ss;
ss.setf(ios::fixed, ios::floatfield);
ss.precision( precision );
ss << measurement << " +" << poserror << " " << negerror ;
return ss.str();
}
答案 2 :(得分:1)
可能是这样的:
std::string FormatNum(double num)
{
int numToDisplay ((int)((num + 0.005) * 100.0));
stringstream ss;
int digitsToDisplay(abs(numToDisplay) % 100);
ss << ((num > 0) ? '+' : '-') << (abs(numToDisplay) / 100) << '.' << (digitsToDisplay / 10) << (digitsToDisplay % 10);
return ss.str();
}
stringstream ss;
ss << FormatNum(0.95637) << ' ' << FormatNum(+0.00123) << ' ' << FormatNum(-0.02935);
答案 3 :(得分:0)
我不太确定你是如何使用log10来帮助你获得第一个非零数字,但假设它(因此你知道你要舍入到的小数位),以下函数将正确舍入:
double round(double num, int decimalPlaces)
{
//given your example of .95637 being rounded to two decimal places
double decimalMultiplier = pow(10, decimalPlaces); // = 100
double roundedShiftedNum = num * decimalMultiplier + 0.5; // = 96.137
double insignificantDigits = (roundedShiftedNum - (int)roundedShiftedNum; // = 0.137
return (roundedShiftedNum - insignificantDigits) / decimalMultiplier; // = (96.137 - 0.137)/100 = 0.96
}
这可能不是最优雅的解决方案,但我相信它有效(虽然没试过)
答案 4 :(得分:0)
以下是Shane Powell提供的版本的变体。
std::string FormatNum(double num, int decimals)
{
stringstream ss;
if (num >= 0.0)
ss << '+';
ss << setiosflags(ios::fixed) << setprecision(decimals) << num;
return ss.str();
}