9

如何在 C++ 中进行涉及有效数字的数学运算?我希望它能够正确处理来自化学和物理实验的测量数据。一个例子:65 / 5 = 10。我需要去掉不需要的小数位并用 0 替换一些数字。

谢谢!

4

7 回答 7

9

这应该可以满足您的需求:

std::cout.precision(x); // x would be the number of significant figures to output
于 2011-01-05T18:01:46.737 回答
4

这可能不是最有效的方法,但您可以创建自定义 sig fig 数据类型。

class SigFigFloat
{
  SigFigFloat(vector<short> digits, int decimalIndex, bool negative);
  SigFigFloat operator+(const SigFigFloat &value);
  SigFigFloat operator-(const SigFigFloat &value);
  //etc...


}

这可能需要做很多工作,但如果你正确实施,它可以是一种非常灵活的方式来表示和使用 sig figs 进行计算。

于 2011-01-05T18:03:50.413 回答
1

这很难,因为有效数字是十进制概念,而计算机说二进制。您可以使用十进制数类(我不知道有任何类),或使用boost::interval,这与您当然想要实现的目标最接近。

于 2011-01-05T18:03:27.973 回答
1

这取决于您如何显示它们。如果您使用的是 printf 系列,则设置精度 ( sprintf(buffer, "%.2f", myfloat))。如果您使用 ostreams,则调用精度函数来设置小数位数。如果您正在寻找更科学的 sig figs 方法,则必须编写一个自定义函数,该函数根据浮点数的当前值确定精度。

于 2011-01-05T18:06:26.870 回答
1

你也可以:

#define SIGNIFICANT_DIGITS 3
const float SIGNIFICANT_DIGITS_PWR = powf(10.0f, SIGNIFICANT_DIGITS);

float f;
std::cin >> f;

int int_digits = (int)log10f(f) + 1;
if (int_digits > 1) {
    float prod = SIGNIFICANT_DIGITS_PWR / powf(10.0f, int_digits);
    f = (float)(int)(f * prod) / prod;
} else {
    f = (float)((int)(f * SIGNIFICANT_DIGITS_PWR)) / SIGNIFICANT_DIGITS_PWR;
};

std::cout << f << '\n';

输出:

0.1234
> 0.123
12.34
> 12.3
1234
> 1230
于 2020-06-14T11:17:03.893 回答
0

这是一个对我有用的快速 C++11 解决方案:

int sig_figs = 3;
double number = 1562.654478;

std::cout << "original number:" << number << std::endl;

number = ([number](int number_of_sig_figs)->double{
    std::stringstream lStream;
    lStream << std::setprecision(number_of_sig_figs) << number;
    return std::stod(lStream.str());
})(sig_figs);

std::cout << "rounded number:" << number << std::endl;
于 2014-09-09T21:33:26.133 回答
-2

那么 math.h 中有很好的数学库

还将您的数字存储在浮点数、双精度数或长双精度数中将允许更精确的操作。

浮点数提供 7 个有效数字,而双精度数提供 16 个有效数字。

资源

此外,当打印出来时,人们通常使用 _snprintf 或 printf 并且您可以格式化这些双精度,浮动到您想要的精度,例如:

浮动精度

printf("值 %8.2f", floatVariable);

这表示您需要总共 8 个字符的字段,在 8 个字符中,最后 2 个字符将保留小数部分。

_snprintf(缓冲区,sizeof(缓冲区),“值 %.2f”,floatVariable);

上面的例子要求最小字段宽度,最后两个字符是小数部分。

于 2011-01-05T18:03:32.403 回答