为什么 numeric_limits<float>::min() 实际上没有给出尽可能小的浮点数?
Why does numeric_limits<float>::min() not actually give the smallest possible float?
似乎我们可以简单地推导出小于numeric_limits<float>::min()
的浮点数。为什么。如果numeric_limits<float>::min()
不应该是最小的正浮点数,那么它应该是什么?
#include <iostream>
#include <limits>
using namespace std;
int main(){
float mind = numeric_limits<float>::min();
float smaller_than_mind = numeric_limits<float>::min()/2;
cout<< ( mind > smaller_than_mind && smaller_than_mind > 0 ) <<endl;
}
在此处运行它:https://onlinegdb.com/ry3AcxjXz
>min()
返回具有格式的全部表达能力的最小正值 - 其有效位数的所有位都可供使用。
较小的正值称为次正值。尽管它们是可表示的,但有效数的高位必然为零。
IEEE-754 64 位二进制浮点格式表示一个带符号的数字(+ 或 -,编码为 0 或 1)、一个指数(-1022 到 +1023,编码为 1 到 2046,加上 0 和 2047 作为特殊情况)和一个 53 位有效数(用 52 位加上指数字段中的线索编码)。
对于正常值,指数字段为 1 到 2046(表示 -1022 到 +1023 的指数),有效数(二进制)为 1.xxx...xxx,其中xxx...xxx 表示另外 52 位。在所有这些值中,有效位数的最低位的值是最高有效位(其中的前 1 位)值的2-52倍。
对于次正规值,指数字段为 0。这仍然表示 -1022 的指数,但这意味着有效位数的高位为 0。意义现在 0.xxx...xxx. 由于在此范围内使用越来越低的值,有效数的更多前导位变为零。现在,有效位数的最低位的值大于最高有效位值的2-52倍。在此区间内,您不能像在正常区间中那样精细地调整数字,因为并非有效位数的所有位都可用于任意值 - 某些前导位固定为 0 以设置刻度。
因此,处理此范围内的数字时发生的相对误差往往大于正常范围内的相对误差。浮点格式具有此次正态范围,因为如果没有,数字将恰好在最小正态值处切断,并且该正态值与零之间的差距将是一个巨大的相对跳跃 - 单步完成值的 100%。通过包括次正规数,相对误差会逐渐增加,并且绝对误差从这一点开始保持不变,直到达到零。
重要的是要知道正常范围的底部在哪里。min()
告诉你这一点。denorm_min()
告诉您最终的最小正值。
根据 en.cppreference.com:
对于具有非规范化的浮点类型,min 返回最小值 正归一化值。请注意,此行为可能是意外的, 特别是与积分类型的最小值行为相比时。
float
是一种具有非规范化的类型,即有关规范化浮点数的信息。
因为numeric_limits::min
返回"对于具有次正规数的浮点类型,返回最小正规范化值"。 您可以将其除以 2,并在某些系统上获得一个次正态(在某些平台上也称为非正态)数字。 这些数字不存储float
类型的完整精度,但允许存储否则将变为 0.0 的值。
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 如何修复此错误:未定义对"距离(浮点数,浮点数,浮点数,浮点数,浮点数)"的引用
- C++浮点数据类型和字符串数据类型无法子到模板函数中
- 使用提升将数据从 PyObject 复制到浮点数 *
- 使用浮点数和双精度数的非常小数字的数学
- 使用英特尔内联函数将打包的 8 位整数乘以浮点数向量
- 如何在 c++ 中将小数点后两位数的浮点数分配给另一个浮点数
- 返回浮点数的小数位数
- txt 文件中浮点数的最大和最小值
- 为什么 std::cout 打印浮点数、双精度和长双精度到相同的小数精度?
- 将浮点数转换为无符号字符数组并打印出来
- 如何将时间字符串 (M:SS) 转换为浮点数
- 如何将浮点数(*)[6]转换为浮点**类型?
- C++将浮点数乘以分数
- 如何将浮点数转换为uint8_t?
- 将字符串转换为浮点数或整数,而无需使用内置函数(如 atoi 或 atof)
- 如何在C++(Arduino)中将浮点数组转换为字节数组
- 在数学上将浮点数四舍五入到 N 位小数
- Cython通过浮点数的最快方式,用于高频控制回路
- 为什么 numeric_limits<float>::min() 实际上没有给出尽可能小的浮点数?