【问题标题】:32bit int * 32bit int = 64 bit int?32 位整数 * 32 位整数 = 64 位整数?
【发布时间】:2009-04-19 11:00:47
【问题描述】:

换句话说,这是否按预期工作?

int32 i = INT_MAX-1;
int64 j = i * i;

还是我需要先将 i 转换为 64 位?

【问题讨论】:

标签: c++ integer-overflow


【解决方案1】:

您需要将至少一个操作数转换为乘法。在乘法完成时,系统不知道您打算分配给 int64。

(除非 int64 实际上是您特定系统的原生 int 类型,这似乎不太可能)

【讨论】:

  • 常见技巧是先在 1L 上相乘而不是强制转换:int64 j = 1L * i * i;如果您的 long 长度为 64 位,则此方法有效。
  • 如果你的 long 只有 32 位,你可以在大多数现代编译器上使用 1LL。
  • 或者您可以使用 stdint.h 中的 INT64_C(1) 使其合理可移植(您可能需要为 MS 编译器挖掘 stdint.h,可能来自 MinGW 或来自 azillionmonkeys.com/qed/pstdint.h跨度>
  • 什么是 int32 和 int64?它们应该类似于 中的 int32_t 和 int64_t 吗?
【解决方案2】:

这取决于 int32 和 int64 是什么。

简而言之,在任何算术运算之前,所有整数都至少提升到“int”大小(可能是 64 位),如果二元运算符的等级大于 int,则提升到更大操作数的大小。

表达式的结果如何使用(是否存储到更广泛的类型)与表达式组成部分的提升无关。

【讨论】:

    【解决方案3】:

    基本答案是否定的,它不会做你想做的事。
    但它确实做了预期的事情。

    关于数学运算需要注意的两点:

    • 两个操作数的类型相同。
    • 生成的类型将与输入相同。

    如果编译器注意到操作数之间不匹配,它将转换其中一个操作数以使两者都匹配(请参阅Which variables should I typecast when doing math operations in C/C++?)。注意:这是独立于结果发生的情况进行的。

    【讨论】:

      【解决方案4】:

      给定两个数字 a,b,每个数字使用 len_a 和 len_b 位。

      您的输出数据类型至少需要:len_a 和 len_b 位。

      在上面的代码中,您有两个 31 位数字(因为 INT_MAX - 1 = 0x7FFFFFFE 使用 31 位),您需要将其中一个类型转换为 int64_t 因为它会在转换为之前执行 32 位乘法和溢出int64_t。


      定点乘法所需的位数:

      len_output = howManyBits( a * b )
                 = len_a + len_b
      

      显示上述规则的一个简单示例:

      a     = 7
      len_a = 3
      
      b     = 7
      len_b = 3
      
      c = a * b
        = 49 ( decimal )
        = 0x31 ( hex )
      
      len_c = howManyBits( 0x31 ) 
            = 6
      

      您可以编写一个函数来计算位数。或者,如果您只是想快速进行健全性检查以确认这一点,请使用 Windows Calc 之类的工具,它将数字转换为二进制形式并计算使用的位数。

      【讨论】:

        【解决方案5】:

        参见:14. 简单整数类型和 memsize 类型的混合使用。 http://www.viva64.com/art-1-2-599168895.html

        【讨论】:

          猜你喜欢
          • 2019-03-25
          • 1970-01-01
          • 2013-09-18
          • 2011-06-10
          • 2019-08-17
          • 1970-01-01
          • 2011-09-12
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多