如何删除C++中浮点数的最后一个有效数字/尾数位
How to remove last significant digits/mantissa bits for floating numbers in C++
我想以有效的方式删除浮点数的最后 2 或 3 位有效数字C++。为了更准确地表述这个问题 - 我想丢弃浮点数表示中的最后几个尾数位。
一些背景:我可以使用不同的方式到达相同的浮点数。例如,如果我在矩形上使用双线性插值,其角值相等,则由于机器精度限制,矩形不同点的最后几位数字的结果将有所不同。这些偏差的绝对顺序取决于插值的顺序。例如,如果 p[i]~1e10(i == 1..4,矩形角处的值(,则由机器精度引起的插值误差为 ~1e-4(对于 8 字节浮点数(。如果 p[i]~1e-10,则误差为 ~1e-24。由于插值用于计算一阶或二阶导数,我需要"消除"这些差异。一个想法是从最终结果中删除最后几位数字。以下是我对它的看法:
#include <iostream> // std::cout
#include <limits> // std::numeric_limits
#include <math.h> // fabs
template<typename real>
real remove_digits(const real& value, const int num_digits)
{
//return value;
if (value == 0.) return 0;
const real corrector_power =
(std::numeric_limits<real>::digits10 - num_digits)
- round(log10(fabs(value)));
//the value is too close to the limits of the double minimum value
//to be corrected -- return 0 instead.
if (corrector_power > std::numeric_limits<real>::max_exponent10 -
num_digits - 1)
{
return 0.;
}
const real corrector = pow(10, corrector_power);
const real result =
(value > 0) ? floor(value * corrector + 0.5) / corrector :
ceil(value * corrector - 0.5) / corrector;
return result;
}//remove_digits
int main() {
// g++ (Debian 4.7.2-5) 4.7.2 --- Debian GNU/Linux 7.8 (wheezy) 64-bit
std::cout << remove_digits<float>(12345.1234, 1) << std::endl; // 12345.1
std::cout << remove_digits<float>(12345.1234, 2) << std::endl; // 12345
std::cout << remove_digits<float>(12345.1234, 3) << std::endl; // 12350
std::cout << std::numeric_limits<float>::digits10 << std::endl; // 6
}
它可以工作,但使用 2 个昂贵的操作 - log10 和 pow。有没有更聪明的方法可以做到这一点?如上所述,为了实现我的目标,我不需要删除实际的十进制数字,而只需将浮点数表示的尾数表示中的 3-4 位设置为 0。
"一些背景:我可以使用不同的方式到达相同的浮点数。
这不是问题。x附近的"局部"分辨率约为x-std::next_after(x,0.0)
在很宽的范围内x
是线性的。p[i]
变化 20 个数量级的问题无关紧要,因为相对误差随p[i]
线性变化,这意味着它也会随第一个表达式线性变化。
更一般地说,如果要比较a
和b
是否足够相似,只需测试a/b
是否近似1.00000000
即可。(当b
正好为零时,你就会遇到更大的问题——没有有意义的方法可以说 1E-10 是否"几乎等于"0(
相关文章:
- 我必须更改我的数字最后一个数字和第一个数字,但不要使用仅带有整数或循环的函数.例如从 12345 到 52341
- 将一个数字拆分为多个数字,每个数字只有一个有效位
- 带有文件结束函数的 while 循环重复输出文件中的最后一个数字两次
- 递归推动POP POSTFIX计算器无法正确执行操作,只需将最后一个数字作为结果
- 代码问题.使用矢量删除相同的数字,除了它的最后一个入口
- C++:对数组进行排序,最后一个数字重复两次
- C++ - 查找数组中第一个和最后一个负数之间的数字
- 我不想要最后一个数字/值后面的逗号,如何删除它(c ++,循环)
- 如何删除C++中浮点数的最后一个有效数字/尾数位
- 有效地从 std::list 中删除最后一个元素
- 逐行计算文件:EOF 重复最后一个数字(不能使用中断)
- 如何确定浮点数中的最后一个非零十进制数字
- 为什么我可以索引到数字超出范围的三维数组中,但仍然可以访问数组中的最后一个数字
- 无法显示 for 循环后的最后一个数字
- 不能算出这个按数字顺序打印数字的c++小程序的最后一个
- 查找升序列表中降序的第一个和最后一个数字
- 冒泡排序不排序最后一个数字与此算法
- 排序程序仅显示第一个和最后一个数字
- 如何在读取文本文件时跳到每行最后一个数字之后的下一行
- 为什么 C++ 中的编译器不增加循环中最后一个数字的值?