C++ 中的 while 循环中的浮点错误
Floating point error in while loop in C++
int main()
{
float x = k ; // k is some fixed positive value
while(x>0)
x-- ;
return 0 ;
}
上面的程序可以无限循环吗?
是的,这是可能的。以最大浮点数为例。
如以下代码所示,对于最大的浮点数m
,m
等于m - 1
:
#include <iostream>
#include <limits>
int main() {
auto m = std::numeric_limits<float>::max();
auto l = m;
l--;
std::cerr << (m == l) << "n";
}
演示:http://ideone.com/Wr9zdN
因此,使用此起始值,循环将是无限的。
为什么?
float
(与其他所有内置类型一样)具有有限的精度。要使x - 1
可以用x
以外的数字表示,小于x
的最大数之间的差必须小于2。
现在让我们计算m
,最大浮点数和x
之间的差值,最大浮点数,严格小于m
:
#include <iostream>
#include <cmath>
#include <limits>
int main() {
auto m = std::numeric_limits<float>::max();
std::cout << "float max: " << m << "n";
auto x = std::nextafter(m, 0.0f);
std::cout << "biggest value less than max: " << x << "n";
auto d = m - x;
std::cout << "the difference: " << d << "n";
}
演示:http://ideone.com/VyNgtE
事实证明,这两个数字之间存在巨大的2.02824e+31
差距。远远大于 1。1 实在是太小了,无法发挥作用。
是的,可以。例如,如果k
FLT_MAX
。没有足够的精度来处理如此大的数字之间的如此小的距离。
#include <float.h>
#include <stdio.h>
int main()
{
float a = FLT_MAX;
float b = a - 1;
printf("%.10fn", a - b);
return 0;
}
输出:
0.0000000000
我认为实际上
可以。如果k
足够大,四舍五入将吞噬您的递减。
相关文章:
- 删除映射和分割错误中的一个过去结束元素
- C++类错误中的模板专用化
- 模板元编程,简历资格错误中的冲突
- Cpp 错误中的<<运算符
- 功能错误中的表达语法帮助!C/C
- Cython将扩展模块传递到to_py_call_code错误中的python reults
- 在测试网上部署智能合约时合约错误中的未知操作 hi
- C 错误中的pronic号码
- 循环和运行时错误中的C 变量声明
- C++ 分段错误中的命令行参数
- 映射引发错误中的 C++ 自定义对象
- MSVC11 错误中的 x64 位 asm
- C++错误中的复合 [没有匹配调用 'push_back'的成员函数]
- 包括Code::Blocks错误中的多个标头
- c++编译器错误中的简单类继承
- 获取Openssl证书错误中的错误字符串
- <Mat> 函数逻辑错误中的向量传递
- 分配错误中的非 Ivalue
- 链接器错误中的"Symbol from plugin"
- 赋值错误中的非左值