为何在C++中能创建小于float最小值的float变量?
为什么能创建小于
std::numeric_limits<float>().min()的float变量? 先看你写的这段C++代码:
#include <iostream> #include <limits> int main() { float x = std::numeric_limits<float>().min(); // x = 1.17549e-38 float y = 1.17549e-39f; // 这个值比float的min()还小,怎么做到的? if(x < y) std::cout << "x < y" << std::endl; else if (x == y) std::cout << "x == y" << std::endl; else std::cout << "y < x" << std::endl; std::cout << x << std::endl; // 输出1.17549e-38 std::cout << y << std::endl; // 输出1.17549e-39,无报错无警告 return 0; }
你遇到的情况是:1.17549e-39f比std::numeric_limits<float>().min()还小,但能正常赋值;而1.17549e-46f却会被截断为0并触发警告。原因其实出在对min()的理解上:
关键:std::numeric_limits<float>::min()的真实含义
std::numeric_limits<float>().min()返回的是float类型能表示的最小正规格化浮点数,不是能表示的最小正浮点数。
IEEE 754单精度float的存储分为两种模式:
- 规格化浮点数:指数位不全为0,这类数的范围是从
min()(约1.17549e-38)到max()(约3.40282e+38)。 - 非规格化浮点数:指数位全为0,这类数用来填补0到最小规格化数之间的空白,数值范围是从0到
min()之间的更小正数。你的1.17549e-39f就属于这类,float可以正常存储它,所以编译不会报错。
为什么1.17549e-46f会被截断为0?
IEEE 754单精度float能表示的最小非规格化正数约为1.4013e-45。1.17549e-46f比这个值还要小,已经超出了float能表示的最小非零正数范围,编译器只能把它截断为0,同时给出“floating constant truncated to zero”的警告。
内容的提问来源于stack exchange,提问作者Vadim Kiselev
相关产品推荐
相关产品推荐

