gpt4 book ai didi

c++ - 将类型转换 float 与零进行比较时的奇怪行为

转载 作者:行者123 更新时间:2023-11-30 01:16:23 25 4
gpt4 key购买 nike

我目前正在尝试深入学习浮点表示,所以我尝试了一下。这样做的时候,我偶然发现了一些奇怪的行为;我无法真正弄清楚发生了什么,非常感谢您提供一些见解。很抱歉,如果有人回答了这个问题,我发现很难用谷歌搜索!

#include <iostream>
#include <cmath>
using namespace std;

int main(){

  float minVal = pow(2,-149); // set to smallest float possible
  
  float nextCheck = static_cast<float>(minVal/2.0f); // divide by two
  bool isZero = (static_cast<float>(minVal/2.0f) == 0.0f); // this evaluates to false
  bool isZero2 = (nextCheck == 0.0f); // this evaluates to true
  cout << nextCheck << " " << isZero << " " << isZero2 << endl;
  // this outputs 0 0 1
  
  return 0;

}

本质上发生的事情是:

  • 我将 minVal 设置为可以使用以下方式表示的最小 float 单精度
  • 除以 2 应该得到 0 -- 我们处于最小值
  • 确实,isZero2 确实返回 true,但 isZero 返回 false。

这是怎么回事——我本以为它们是一样的?编译器是不是在耍小聪明,说任何数相除都不可能为零?

感谢您的帮助!

最佳答案

isZeroisZero2 可以计算出不同的值,并且 isZero 可以为假的原因是允许 C++ 编译器实现比表达式类型指示的精度更高的中间浮点运算,但必须在赋值时删除额外的精度。

通常,在为 387 历史 FPU 生成代码时,生成的指令要么在 80 位扩展精度类型上工作,要么,如果 FPU 设置为 53 位有效数(例如在 Windows 上),一个奇怪的具有 53 位尾数和 15 位指数的浮点类型。

无论哪种方式,minVal/2.0f 的计算都是因为指数范围允许表示它,但是将它分配给 nextCheck 会将其舍入为零。

如果你使用的是GCC,还有一个问题是-fexcess-precision=standard还没有为C++前端实现,也就是说g++生成的代码没有实现正是标准所建议的。

关于c++ - 将类型转换 float 与零进行比较时的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26690196/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com