【问题标题】:Finding the smallest integer that can not be represented as an IEEE-754 32 bit float [duplicate]查找不能表示为 IEEE-754 32 位浮点数的最小整数 [重复]
【发布时间】:2011-04-22 20:27:15
【问题描述】:

可能重复:
Which is the first integer that an IEEE 754 float is incapable of representing exactly?

首先,这是一个家庭作业问题,只是为了立即解决这个问题。当然,我不是在寻找用勺子喂食的解决方案,也许只是一个指向正确方向的小指针。

所以,我的任务是找到不能表示为 IEEE-754 浮点数(32 位)的最小正整数。我知道在“5 == 5.00000000001”之类的东西上测试相等性会失败,所以我想我只需遍历所有数字并以这种方式进行测试:

int main(int argc, char **argv)
{
    unsigned int i; /* Loop counter. No need to inizialize here. */

    /* Header output */
    printf("IEEE floating point rounding failure detection\n\n");

    /* Main program processing */
    /* Loop over every integer number */
    for (i = 0;; ++i)
    {
        float result = (float)i;

        /* TODO: Break condition for integer wrapping */

        /* Test integer representation against the IEEE-754 representation */
        if (result != i)
            break; /* Break the loop here */
    }

    /* Result output */
    printf("The smallest integer that can not be precisely represented as IEEE-754"
           " is:\n\t%d", i);


    return 0;
}

这失败了。然后我尝试从浮点“结果”中减去整数“i”,即“i”,希望获得可以尝试检测的“0.000000002”,但也失败了。

有人可以指出我可以依赖的浮点属性来获得所需的中断条件吗?

-------- 更新下面---------------

感谢您对此的帮助!我在这里学到了很多东西:

  1. 我最初的想法确实是正确的,并确定了要在其上运行的机器(Solaris 10,32 位)上的结果,但无法在我的 Linux 系统(64 位和 32 位)上运行。

  2. Hans Passant 添加的更改使该程序也适用于我的系统,这里似乎存在一些我没有预料到的平台差异,

谢谢大家!

【问题讨论】:

  • 它是如何失败的?当我编译并执行你的代码时,输​​出是 16777217。
  • @KennyTM:该死,我以为我擅长搜索!抱歉复制了。
  • @Henrik:它只是不断回绕 (INT_MAX -> 0),从未因结果而中断。

标签: c floating-point floating-accuracy


【解决方案1】:

问题是你的相等测试是一个浮点测试。 i 变量将首先转换为浮点数,当然会产生相同的浮点数。将 float 转换回 int 以获得整数相等测试:

float result = (float)i;
int truncated = (int)result;
if (truncated != i) break;

如果它以数字 16 开头,那么您找到了正确的数字。将其转换为十六进制,并解释为什么这是一个未能获得成绩奖励的那个。

【讨论】:

  • 谢谢!这成功了,我很高兴我最初的想法被证明是有效的:)
【解决方案2】:

我认为您应该将浮点数的表示形式推理为(基数、符号、有效数、指数)

这里是Wikipedia的摘录,可以给你一个线索:

给定的格式包括:

* Finite numbers, which may be either base 2 (binary) or base 10

(十进制)。每个有限数是最 简单地用三个整数描述:s= 符号(零或一),c= 有效数 (或“系数”),q=指数。 有限数的数值 是 (−1)s × c × bq 其中 b 是基数(2 或 10)。例如,如果符号为 1 (表示负数),有效数字 是 12345,指数是 -3,并且 基数为 10,则 数字是 -12.345。

【讨论】:

    【解决方案3】:

    那就是FLT_MAX+1。见float.h

    编辑:或者实际上没有。检查math.h中的modf()函数

    【讨论】:

    • @Hans 是的,肯定有更小的数字无法表示。
    • 试试(1<<FLT_MANT_DIG)+1
    猜你喜欢
    • 2016-02-09
    • 1970-01-01
    • 2012-01-06
    • 1970-01-01
    • 2013-02-16
    • 2017-03-29
    • 1970-01-01
    • 1970-01-01
    • 2021-12-14
    相关资源
    最近更新 更多