【问题标题】:Float and Int Both 4 Bytes? How Come?Float 和 Int 都是 4 个字节?怎么会?
【发布时间】:2012-02-03 12:14:27
【问题描述】:

Int 是 4 个字节,范围为 +- 2^31 浮点数为 4 个字节,范围为 +- 1.2E(+- 38)

Float 包含 Real Line 上的更多点,但等于 int 的大小。 float 的符号-指数-分数表示是否如此令人敬畏(或 Int 的 2 的补码如此可悲)以至于出现了这种大小差异?我错过了什么吗?

我只是觉得非常令人惊讶的是,代表(实际上)整条实线的东西与代表整数的东西大小相同。

【问题讨论】:

标签: floating-point int


【解决方案1】:

也许你应该学习how floating point numbers are represented in a computer.它与整数的表示方式有很大的不同。

另外值得注意的是,int 并不总是 4 字节长,它取决于系统。

【讨论】:

  • 浮点数也不总是 4 个字节。一些 8 位微控制器编译器可以选择使用 24 位浮点数。
【解决方案2】:

这两种类型代表实线上相同数量的点 - 它们只是间隔不同。最高和第二高的浮动之间的差异是 ca。 256!

【讨论】:

  • 实际上 float 代表实线上的更少点,因为 float 有很多 NaN 值:2^24 - 2 = 16'777'214 准确地说(-2 表示 + /-infinity) 其中 2^23 = 8'388'608 被称为“安静的 NaN”(都被认为是等效的*,因此它们浪费了很多值)。其余的是“信令 NaN”,尽管就 IEEE-754 标准而言它们是不同的,但它们很少有真正的用途,因此它们携带的额外信息(“有效负载”)被大多数系统忽略。浮点数也有两个不同的零(+/-0 是不同的)。总结:float 的实数值比 int 少 16'777'217。
【解决方案3】:

我相信这里的重点是 int 是精确的,而 float 可能是四舍五入的。浮点数中的一部分数据描述了小数点的位置,而另一部分则确定了数值。因此,虽然您可能能够显示 1.2E38,但只有前几个数字可能是正确的,其余的可能用 0 填充。

发件人:http://en.wikipedia.org/wiki/Floating_point

“七位十进制数字还可以表示 1.234567、123456.7、0.00001234567、1234567000000000 等”

这取决于特定系统如何实现浮点数。

【讨论】:

    【解决方案4】:

    我只是觉得非常令人惊讶的是,代表(实际上)整条实线的东西与代表整数的东西大小相同。

    一旦您意识到 32 位 int 可以精确表示许多整数,而 32 位 float 不能准确表示,也许这会变得不那么令人惊讶。

    float 代表的不同数字比 int 少,但它们分布的范围更广。

    还值得注意的是,连续的floats 之间的间距随着远离零而变宽,而连续的ints 之间的间距保持不变。

    【讨论】:

    • 正是我想要的。谢谢!
    【解决方案5】:

    好吧,这里有一个简单的解释:

    int 和 float 通常占用内存中的“一个单词”。今天,随着向 64 位系统的转变,这可能意味着您的字是 64 位或 8 个字节,从而可以表示大量数字。或者,它仍然可能是 32 位系统,这意味着内存中的每个字占用 4 个字节。通常可以逐字访问内存。

    intfloat 之间的区别不在于它们在内存中的物理空间,而在于 ALU(算术逻辑单元)对数字的行为方式。 int 表示其直接对应的二进制数(嗯,几乎——它使用two's complement notation)。另一方面,float 被编码(通常采用 IEEE 754 标准格式)以表示指数形式的数字(即 2.99*10^6 是指数形式)。

    我认为您的误解在于浮点可以表示更多信息的误解。虽然floats 可以表示更大数量的数字,但它不能以同样高的精度表示它们,因为它必须考虑对指数进行编码。指数本身可能是一个相当大的数字。因此,您从浮点数中获得的有效位数较少(这意味着表示的信息较少),而 ints 表示整数范围,它们表示的数字的大小要小得多。

    【讨论】:

    • 谢谢。那真的很有帮助。 IEEE 754 标准揭示了偶数自然数逼近的本质。
    【解决方案6】:

    根据标准的浮点标准要求 base=2 而不是 base=10 和 24 位(精度)。由于它不是以 10 为底,因此以 2 为底的格式只能表示一组确定的实数(这是表示实数时出错的内在原因)。这也意味着,正如您之前所说的那样,与 int 相比,float 并不代表更多的数字。

    【讨论】:

      【解决方案7】:

      事实上,某种数据类型的长度在平台上是不同的。但是现在让我们说floatint 是相同的,4 个字节。

      4 字节等于 32 位,二进制的范围是

      00000000000000000000000000000000

      1111111111111111111111111111111

      此时,我们应该回忆一下几何序列,上面的和等于

      2^32 + 2^31 + ... + 2^1 + 2^0 = 2147483648

      注意,C 重新定义了从数学到语言的范围,如 unsignedsigned 通过 shift。

      也就是说它也可以定义float

      看到EEEEEEEMMMMMMMMMMMMMMMMMMMMMMMMM

      S = 符号(1 位)

      E = 指数(8 位)

      M = 尾数(23 位)

      值计算遵循IEEE-754,这并不容易,但我们可以在754 converter尝试:)

      现在,范围,(见指数技巧?它的意思是 E-127,减号!)

      0 00000001 00000000000000000000000

      0 11111110 1111111111111111111111

      数学,

      2^-126 * 1.00000000000000000000000 = 1.1754943508222875 × 10^-38

      2^(128) * 1.1111111111111111111111 = 3.7809151880104275 x 10^38

      注意尾数有一个隐藏的 1,否则你总是得到 0:

      最后机器一开始就是为了救命,所以在我们选择数据类型之前,我们最好从头文件中检查范围,例如

      #include <stdio.h>
      #include <limits.h>
      #include <float.h>
      
      int main()
      {
          printf("Range of signed char %d to %d\n", SCHAR_MIN, SCHAR_MAX);
          printf("Range of unsigned char 0 to %d\n\n", UCHAR_MAX);
      
          printf("Range of signed short int %d to %d\n", SHRT_MIN, SHRT_MAX);
          printf("Range of unsigned short int 0 to %d\n\n", USHRT_MAX);
      
          printf("Range of signed int %d to %d\n", INT_MIN, INT_MAX);
          printf("Range of unsigned int 0 to %lu\n\n", UINT_MAX);
      
          printf("Range of signed long int %ld to %ld\n", LONG_MIN, LONG_MAX);
          printf("Range of unsigned long int 0 to %lu\n\n", ULONG_MAX);
      
          // In some compilers LLONG_MIN, LLONG_MAX
          printf("Range of signed long long int %lld to %lld\n", LLONG_MIN, LLONG_MAX); 
          // In some compilers ULLONG_MAX
          printf("Range of unsigned long long int 0 to %llu\n\n", ULLONG_MAX); 
      
          printf("Range of float %e to %e\n", FLT_MIN, FLT_MAX);
          printf("Range of double %e to %e\n", DBL_MIN, DBL_MAX);
          printf("Range of long double %e to %e\n", LDBL_MIN, LDBL_MAX);
      
          return 0;
      }
      

      【讨论】:

        猜你喜欢
        • 2023-03-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-10-11
        • 2019-02-22
        • 1970-01-01
        • 2017-05-19
        相关资源
        最近更新 更多