首页 > 解决方案 > 为什么浮点转换不起作用?

问题描述

为什么最小正浮点数的浮点转换失败?

#include <iostream>
#include <vector>

int main(){
   std::vector<std::string> testStrings;
   float fmax = std::numeric_limits<float>::max(); // maximum value
   float fmin = std::numeric_limits<float>::min(); // maximum value
   std::cout<<fmax<<std::endl;
   std::cout<<fmin<<std::endl;
   
  float result=0;
  bool status=false;
  //below test cases must pass
  testStrings.push_back("10");
  testStrings.push_back("+10");
  testStrings.push_back(" 10 ");
  testStrings.push_back("10.253165");
  testStrings.push_back("10.253165E12");
  testStrings.push_back("11111111111111111111111");
  testStrings.push_back("2e-123546132222");
  testStrings.push_back("3.40282e+38");
  testStrings.push_back("3.40284e+38");
  testStrings.push_back("1.17549e-38"); // This test case is throwing out of range exception

for(std::string temp:testStrings)
{
std::stof(temp);
}

}

我正在使用 std::stof 方法进行转换。

标签: c++floating-point

解决方案


该程序没有使用足够的数字来表示float具有足够准确度的最小法线。

IEEE-754 binary32 中的最小正正态数为 2 -126,即 1.1754943508222875079687365372222456778186655567720875215087517062784172594547271728515625•10^ -38。但是,这不是问题中的程序传递给的数字strtod。相反,它只使用了六个有效数字,“1.17549e-38”。1.17549•10 -38小于 2 -126,并且比它小很多,以至于将其转换为float(使用 IEEE-754 binary32 格式)会产生小于 2 -126的数字。实际产生的数字是 2 −126 − 31•2 −149

因此,尝试将“1.17549e-38”从十进制转换为浮点数会strtof产生范围错误,因为它确实超出范围(超出正常范围;该值是可表示的,但 C++ 标准允许结果超出范围错误低于正常范围)。

教训:不要只使用六位数。再使用三个数字“1.17549435e-38”就足以使转换结果为 2 -126,并且不会产生范围错误。通常,使用九个有效十进制数字就足以将任何 IEEE-754 binary32 格式转换为十进制并返回将产生原始数字。(这个值,九,由 报告std::numeric_limits<float>::max_digits10。)

另请参阅std::stod 为应该是有效的字符串抛出 out_of_range 错误


推荐阅读