关于c:CC如何只保留4位有效数字

42次阅读

共计 2011 个字符,预计需要花费 6 分钟才能阅读完成。

文章原文:https://tlanyan.pp.ua/c-cpp-keep-significant-figures/

问题

敌人要用数值算例验证舍入误差对算法稳定性的影响,实际中遇到的第一个问题是:C/C++ 如何只保留 4 位有效数字(significant figures)?

如果接触过 Java/JS 等语言,保留小数点后几位 是非常容易的,调用 setScaletoFixed 等函数就能够,还能指定舍入模式。然而对于 C /C++,如何保留指定有效位数呢?

C/C++ 保留指定有效数字

在 C /C++ 语言中,精度的概念只在输入 (流) 中呈现,因而实现的一个思路是:依照指定精度输入字符串,再转换成数字。

C 语言指定有效数字位数

先看 C 语言的解决方案。

C 语言的 printf 系列函数能够指定输入格局,打印成字符串后可用 atof 转换成数字。于是指定有效数字的 C 语言实现版本如下:

include <stdio.h>

include <stdlib.h>

double convert1(int precision, double val) {

char buffer\[128\];
sprintf(buffer, "%.*g", precision, val);

return atof(buffer);

}

应用代码验证:

int main(int argc, char* argv[]) {

double f1 = 1235.46698;
printf("origin: %.12f, converted: %.12f\\n", f1, convert1(4, f1));

double f2 = 1.23546698;
printf("origin: %.12f, converted: %.12f\\n", f2, convert1(4, f2));

double f3 = 0.00123546698;
printf("origin: %.12f, converted: %.12f\\n", f3, convert1(4, f3));

double f4 = 0.0000123546698;
printf("origin: %.12f, converted: %.12f\\n", f4, convert1(4, f4));

return 0;

}

输入后果如下:

origin: 1235.466980000000, converted: 1235.000000000000
origin: 1.235466980000, converted: 1.235000000000
origin: 0.001235466980, converted: 0.001235000000
origin: 0.000012354670, converted: 0.000012350000

均保留了 4 位 有效数字,与预期相符。

C++ 语言指定有效数字位数

C++ 应用 范型 (Generics) 对规范库进行了大重构,在语法方面绝对于 C 可读性晋升不少。

以下是 C ++ 应用 stringstream 转换数字的代码:

include <sstream>

template<int PRECISION>
double convert2(double input) {

std::stringstream is;
double res;
is.precision(PRECISION);
is << input;
is >> res;
return res;

}

应用代码验证:

int main(int argc, char* argv[]) {

std::cout.precision(12);
std::cout.setf(std::ios::fixed, std:: ios::floatfield);

double f1 = 1235.46698;
std::cout << "origin:" << f1 << ", converted:" << convert2<4>(f1) << std::endl;

double f2 = 1.23546698;
std::cout << "origin:" << f2 << ", converted:" << convert2<4>(f2) << std::endl;

double f3 = 0.00123546698;
std::cout << "origin:" << f3 << ", converted:" << convert2<4>(f3) << std::endl;

double f4 = 0.0000123546698;
std::cout << "origin:" << f4 << ", converted:" << convert2<4>(f4) << std::endl;

return 0;

}

其输入后果与 C 语言版本统一。

总结

C/C++ 中,整数、浮点数等根本类型没有原生的格式化反对,须要借助输入输出的格式化函数能力达到保留指定有效数字的目标。

与有效数字相似的问题还有:

  1. C/C++ 中如何保留 小数点后指定位数
  2. C/C++ 中如何实现 FLOOR/CEILING、UP/DOWN、HALF\_UP/HALF\_DOWN 等 舍入模式(Rounding Mode)?

参考

  1. C++ 模板编程

正文完
 0