【问题标题】:Long long int on 32 bit machines32 位机器上的 long long int
【发布时间】:2011-03-05 14:04:32
【问题描述】:

非常简单的问题,我读到 GCC 支持 long long int 类型。但是,当 CPU 只有 32 位宽时,如何用它进行数学运算呢?

【问题讨论】:

    标签: c++ c types


    【解决方案1】:

    编译器将综合使用多条 CPU 指令来执行运算的数学运算(或使用函数调用)。例如,添加操作将添加 long long 值的低位组件(低位字),然后将该操作的进位输入到 long long 的高位字上的添加操作中.

    所以下面的C代码:

    long long a;
    long long b;
    long long c;
    
    // ...
    c = a + b;
    

    可能由如下所示的指令序列表示:

    mov eax, [a.low]   ; add the low order words
    add eax, [b.low]
    
    mov edx, [a.high]  ; add the high order words, 
    adc edx, [b.high]  ; including the carry 
    
    mov [c.low], eax
    mov [c.high], edx
    

    如果您考虑一下,早在long long 出现之前,8 位和 16 位系统的编译器就必须对 16 位和/或 32 位值执行此类操作。

    【讨论】:

      【解决方案2】:

      在内部,类型由高位字和低位字表示,如:

      struct long
      {
        int32 highWord;
        uint32_t lowWord;
      }
      

      编译器需要知道它是 32 位还是 64 位环境,然后选择正确的数字表示 - 如果是 64 位,则可以原生完成,如果是 32 位,编译器必须处理高/低字之间的数学运算。

      如果您查看 math.h,您可以看到用于此的函数,并自己使用它们。另外,请注意 little-endian 和 big-endian (see wiki) 之间的区别,具体用法取决于操作系统。

      【讨论】:

      • 另外两件事:首先,此结构的顺序取决于机器顺序。
      • 其次,对这个结构体进行操作的函数调用可供你使用。它们在 math.h 中声明。
      • 希望lowByte 真的是uint32_t :-P
      • 在这种情况下,这个词是 'word' 而不是 'byte' :)
      • 好吧,还有一个,如果它是一个结构,我如何在没有任何头文件的情况下使用它,就像任何其他数据类型一样? (Visual C++ 2010 速成版)
      【解决方案3】:

      说架构是 32 位(或 64 位或其他)通常只是处理器能力的近似值。通常你只指具有该数字的指针的宽度,算术可能会完全不同。例如,x86 架构有 32 位指针,大多数算术运算是在 32 位寄存器中执行的,但它也原生支持一些基本的 64 位操作。

      此外,您不应认为标准整数类型具有一定的规定宽度。特别是 long long 至少为 64 位,但可能更宽。如果您想确定宽度,请使用 typedefs int32_t, int64_t。

      如果您想知道 gcc(或任何其他编译器)对 long long 的作用,您必须查看特定目标平台的规范

      【讨论】:

        【解决方案4】:

        如果您有可访问的 32 位系统,只需编译和测试即可。 gcc 有一个标志-S,它打开汇编语言输出。这是它在我的 32 位英特尔上产生的结果:

        // read two long longs from stack into eax:edx and ecx:ebx
        movl    32(%esp), %eax
        movl    36(%esp), %edx
        movl    24(%esp), %ecx
        movl    28(%esp), %ebx
        // a+b
        addl    %ecx, %eax
        adcl    %ebx, %edx
        // a-b
        subl    %ecx, %eax
        sbbl    %ebx, %edx
        // etc
        

        【讨论】:

          【解决方案5】:

          最有可能作为一个班级,而不是本机。任何编译器都可以/可以支持任何大数字集的方式相同。

          【讨论】:

            猜你喜欢
            • 2013-12-05
            • 1970-01-01
            • 1970-01-01
            • 2013-08-01
            • 2017-02-08
            • 2019-06-15
            • 1970-01-01
            • 2011-11-08
            • 1970-01-01
            相关资源
            最近更新 更多