代码之家  ›  专栏  ›  技术社区  ›  rajachan

在32位应用程序中提供错误输出的64位算法

  •  1
  • rajachan  · 技术社区  · 12 年前

    我不明白为什么下面相同的操作报告两个不同的输出。当我的num被声明为负值,并且我将num添加到baseAddr时,我看到我的addr超过了32位范围。另一方面,如果我将num声明为正值并进行减法运算,我确实看到了正确的结果。即准确地报告了我的结果输出。有人能解释一下下面的计算出了什么问题吗?

    /* Architecture is powerpc. Program cross-compiled for powerpc. Gcc Version- 4.6.2 */
    #include <stdio.h>
    typedef unsigned long long u_int64;
    typedef unsigned long u_int32;
    
    int main() {
       u_int64 baseAddr = 0x8e008128;
       u_int32 num = -360;
       u_int64 addr = baseAddr + num;
       printf("\nAddr 1st step = 0x%llx\n", addr);
    
       /* Same operation, but slightly different */
       num = 360;
       addr = baseAddr - num;
       printf("\nAddr 2nd step = 0x%llx\n", addr);
       return 0;
    }
    
    /* Output:
    Addr printed is 0x18e007fc0, but I need just 0x8e007fc0
    /diagsk10copy/bin # ./e500GPR
    
    Addr 1st step = 0x18e007fc0 //Wrong
    Addr 2nd step = 0x8e007fc0
    */
    
    2 回复  |  直到 12 年前
        1
  •  4
  •   nneonneo    12 年前

    u_int32 是一个无符号类型;将-360赋值给它将导致整数溢出并导致 num 持有非常大的正值。

        2
  •  3
  •   Community Dai    7 年前

    u_int32 未签名。负面的 360 分配给它的将被重新解释为32位正数。当您将其添加到 u_int64 ,值 得到32个零的扩展 以匹配另一个操作数的大小。这不是你想要的:因为这个数字是负数,所以你需要上半部分的所有1,以便在加法结果以比可以表示的最大值大一的数字为模减少后,加法产生所需的效果 u输入64 *

    如果您申报 num u输入64 ,第一部分和第二部分产生预期数量( demo on ideone )。

    u_int64 baseAddr = 0x8e008128;
    u_int64 num = -360;
    u_int64 addr = baseAddr + num; // Works!
    printf("\nAddr 1st step = 0x%llx\n", addr);
    


    * 6.2.5(9)“涉及无符号操作数的计算永远不会过度,因为无法由结果的无符号整数类型表示的结果会以比结果类型所能表示的最大值大一的数字为模进行减少。”。谢谢, Daniel Fischer 用于查找标准的相关部分!