AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / coding / 问题 / 79481888
Accepted
Paul Grinberg
Paul Grinberg
Asked: 2025-03-04 02:48:08 +0800 CST2025-03-04 02:48:08 +0800 CST 2025-03-04 02:48:08 +0800 CST

c++ std::stof() 抛出 out_of_range 5.87747175e-39

  • 772

考虑以下代码

#include <iostream>

int main()
{
  const std::string s("5.87747175e-39");
  float f = std::stof(s);
  std::cout << s << " - " << f << std::endl;
  return 0;
}

使用 g++ 编译并执行时,会抛出。但是,正如您在此处std::out_of_range看到的,5.87747175e-39 是一个有效的浮点数。这是怎么回事?

以防万一,我使用的是 amd64 Debian 12,它使用 g++ 版本 12.2

不管怎样,Python 认为这是一个有效的浮点数

python3 -c 'print(float("5.87747175e-39"))'

此外,这个问题似乎扩展到所有非规范化浮点数。例如,“1.1754942e-38”是最大的有效IEEE-754 非规范化浮点数,但 stof() 认为它是一个错误。最小的规范化浮点数是“1.1754944e-38”,也就是报告为 FLT_MIN

c++
  • 3 3 个回答
  • 95 Views

3 个回答

  • Voted
  1. Best Answer
    gcc-6.0
    2025-03-04T03:33:06+08:002025-03-04T03:33:06+08:00

    查看GCC 的实现,std::stof如果浮点数小于,则抛出此错误FLT_MIN,否则FLT_TRUE_MIN。

    造成这种情况的原因可能是因为是在C++17FLT_TRUE_MIN中引入的,而在C++11中。std::stof

    • 3
  2. Eric Postpischil
    2025-03-04T20:10:41+08:002025-03-04T20:10:41+08:00

    float对于低于正常范围的结果,可能会报告下溢,因为此类结果可能具有比正常更大的错误。如果结果处于低于正常范围,C++ 标准允许将字符串转换为报告下溢。

    5.87747175•10 −39在 的范围内float,但它在次正常范围内(如下所述)。C++ 标准规定调用stof(strtof在 C++ 2020 草案 N4849 21.3.4 [string.conversions] 3 中),然后遵从 C 标准来定义strtof。C 标准指出strtof可能会下溢。C 2018 7.12.1 6 规定“如果数学结果的幅度太小,以至于无法在指定类型的对象中表示数学结果,而不会产生异常舍入误差,则结果会发生下溢。” “异常舍入误差”是指遇到次正常值时发生的舍入误差。(次正常值的有效有效数字位较少,因此比正常值更容易出现相对误差,所以它们的舍入误差可以说是异常的。)

    因此,C++ 标准允许 C++ 实现对次正规值进行下溢,即使这些值是可表示的。

    这个问题本质上是这个问题的重复,只是一个问题是针对的double,而这个问题是针对的float。

    正常值和低于正常值

    对于 IEEE-754 32 位二进制浮点数,正常范围是从 2 −126到 2 128 −2 104。在此范围内,每个数字都用一个有效数字(浮点表示的小数部分)表示,其前导位为 1,后跟 23 个附加位,因此将此范围内的任何实数四舍五入为最接近的可表示值时发生的误差最多为前导位位置值的2 −24倍。

    除了这个正常范围之外,还有一个从 2 −149到 2 −126 −2 −149的亚正常范围。在这个区间内,浮点格式的指数部分已经达到了最小值,并且无法再减少。为了在这个区间内表示越来越小的数字,有效数字要降低到正常最小值 1 以下。它以 0 开头,后面跟着 23 个附加位。在这个区间内,将实数四舍五入到最接近的可表示值时出现的误差可能大于前导位位置值的 2 −24倍。由于指数无法再减少,这个区间内的数字随着它们越来越小,前导 0 位数也会增加。因此,使用这些数字所涉及的相对误差就会增加。

    • 3
  3. Cory Kramer
    2025-03-04T02:53:26+08:002025-03-04T02:53:26+08:00

    根据std::numeric_limits::min

    #include <limits>
    #include <iostream>
    
    int main() {
      std::cout << std::numeric_limits<float>::min();
    }
    

    的输出为。float这与 的记录值1.17549e-38一致。FLT_MIN

    • 1

相关问题

  • 为什么编译器在这里错过矢量化?

  • 使用带有库的 CMake 编译错误[关闭]

  • 每次我尝试运行预制时都会抛出错误

  • 如何在 C++ 中创建类似于 std::byte 的八位字节类型?

  • C++17 中 std::byte 只能按位运算?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    重新格式化数字,在固定位置插入分隔符

    • 6 个回答
  • Marko Smith

    为什么 C++20 概念会导致循环约束错误,而老式的 SFINAE 不会?

    • 2 个回答
  • Marko Smith

    VScode 自动卸载扩展的问题(Material 主题)

    • 2 个回答
  • Marko Smith

    Vue 3:创建时出错“预期标识符但发现‘导入’”[重复]

    • 1 个回答
  • Marko Smith

    具有指定基础类型但没有枚举器的“枚举类”的用途是什么?

    • 1 个回答
  • Marko Smith

    如何修复未手动导入的模块的 MODULE_NOT_FOUND 错误?

    • 6 个回答
  • Marko Smith

    `(表达式,左值) = 右值` 在 C 或 C++ 中是有效的赋值吗?为什么有些编译器会接受/拒绝它?

    • 3 个回答
  • Marko Smith

    在 C++ 中,一个不执行任何操作的空程序需要 204KB 的堆,但在 C 中则不需要

    • 1 个回答
  • Marko Smith

    PowerBI 目前与 BigQuery 不兼容:Simba 驱动程序与 Windows 更新有关

    • 2 个回答
  • Marko Smith

    AdMob:MobileAds.initialize() - 对于某些设备,“java.lang.Integer 无法转换为 java.lang.String”

    • 1 个回答
  • Martin Hope
    Fantastic Mr Fox msvc std::vector 实现中仅不接受可复制类型 2025-04-23 06:40:49 +0800 CST
  • Martin Hope
    Howard Hinnant 使用 chrono 查找下一个工作日 2025-04-21 08:30:25 +0800 CST
  • Martin Hope
    Fedor 构造函数的成员初始化程序可以包含另一个成员的初始化吗? 2025-04-15 01:01:44 +0800 CST
  • Martin Hope
    Petr Filipský 为什么 C++20 概念会导致循环约束错误,而老式的 SFINAE 不会? 2025-03-23 21:39:40 +0800 CST
  • Martin Hope
    Catskul C++20 是否进行了更改,允许从已知绑定数组“type(&)[N]”转换为未知绑定数组“type(&)[]”? 2025-03-04 06:57:53 +0800 CST
  • Martin Hope
    Stefan Pochmann 为什么 {2,3,10} 和 {x,3,10} (x=2) 的顺序不同? 2025-01-13 23:24:07 +0800 CST
  • Martin Hope
    Chad Feller 在 5.2 版中,bash 条件语句中的 [[ .. ]] 中的分号现在是可选的吗? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench 为什么双破折号 (--) 会导致此 MariaDB 子句评估为 true? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng 为什么 `dict(id=1, **{'id': 2})` 有时会引发 `KeyError: 'id'` 而不是 TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob:MobileAds.initialize() - 对于某些设备,“java.lang.Integer 无法转换为 java.lang.String” 2024-03-20 03:12:31 +0800 CST

热门标签

python javascript c++ c# java typescript sql reactjs html

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve