首页 文章

IEEE-754中的浮点数可用单精度表示多少个整数? [重复]

提问于
浏览
-1

这个问题在这里已有答案:

有人可以帮我理解如何计算在IEEE-754 with single precision中用浮点表示多少个整数(整数,而不是小数)?

2 回答

  • 2

    在IEEE-754中使用单精度可以用浮点表示多少个整数?

    有多种方法可以确定这一点 .

    具有单精度的IEEE-754或binary32可以编码0到224的所有整数值 - 编码具有24位精度(23隐式显式编码1) . 所以使用底片(而不是-0),

    (- 2^24 ... 2^24) is 0x2000000 - 1 different integer values
    

    所有有限FP值224和更高也是整数或"integers" .

    来自function to retrieve the number of available distinct values within a range?的是以下不可移植的C代码,它返回每个 float 的序列号,通常是binary32 .

    #include <stdint.h>
    #include <string.h>
    // Return a sequence number for each `float` value.
    // Numerically sequential `float` values will have successive (+1) sequence numbers.
    uint32_t float_sequence(float x) {
      uint32_t u32;
      memcpy(&u32, &x, sizeof u32);
      if (u32 & 0x80000000) {
        u32 ^= 0x80000000;
        return 0x80000000 - u32;
      }
      return u32 + 0x80000000;
    }
    

    使用 float_sequence(FLT_MAX) - float_sequence(1 << 24) + 1 ,我们得到有限数 float > = 224 .

    int main(void) {
      int32_t imax = 1L << 24;
      printf("%" PRIx32 "\n", float_sequence(FLT_MAX) - float_sequence((float)imax) + 1);
      printf("%" PRIx32 "\n", (uint32_t) (imax - -imax) - 1);
      printf("%" PRIx32 "\n", float_sequence((float) -imax) - float_sequence(-FLT_MAX) + 1);
      return 0;
    }
    

    产量

    34000000
    1ffffff
    34000000
    

    因此总共0x69FFFFFF或 1,778,384,895 整数值或所有可能的binary32位模式的约41% .

    如果-0被认为不同于0,还有一个 .

    请注意,最大有限二进制32(带符号)需要128位整数才能将其存储为整数 .

    如果将整数限制为64位2的补码,则设置计数为0x29FFFFFE或704,643,070 .

  • 2

    我很懒,所以我编写了一个强力搜索如下(这假设 float 映射到IEEE-754 binary32 浮点类型):

    #include <stdio.h>
    #include <stdlib.h>
    #include <stdint.h>
    #include <math.h>
    
    int main (void)
    {
        volatile union {
            float f;
            uint32_t i;
        } num;
        uint32_t count = 0;
        num.i = 0;
        do {
            if ((num.f == floorf (num.f)) && !isinf (num.f)) count++;
            num.i++;
        } while (num.i);
        printf ("count = %u\n", count);
        return EXIT_SUCCESS;
    }
    

    在速度相当快的PC上,不到一分钟后,程序会吐出:

    count = 1778384896
    

    如果要将-0视为冗余0,则减1 . 建议使用一个C编译器提供的最大IEEE-754兼容性来编译此代码 . 我在Windows上使用了英特尔编译器版本13并指定了 /fp:strict .

相关问题