【发布时间】:2018-01-16 20:22:48
【问题描述】:
我一直认为有符号乘法和除法需要与相应的无符号运算不同的电路逻辑。在另一个论坛上有人说,unsigned-ALUs 可以在不修改有符号参数的情况下使用并给出有效的结果。
我只是用一个小程序测试了这个
#include <stdio.h>
void main()
{
short a, b;
long long c;
c = 0;
a = -32768;
do
{
b = -32768;
do
if( (int)((unsigned)a * (unsigned)b) != ((int)a * b) )
++c;
while( ++b != -32768 );
} while( ++a != -32768 );
printf( "%.0lf\n", (double)c );
}
这将打印零,即乘法的工作方式类似于上述假设。那么为什么有符号和无符号乘法有不同的指令,这在电路逻辑中是如何表示的呢?
而且我没有谈论部门。我是否正确地假设,我之前的假设是至少需要不同的电路逻辑来进行划分?
【问题讨论】:
-
乘法给出与操作数相同大小的结果并不关心符号。可以为您提供完整双倍大小结果的变体。
-
我不知道你从哪里得到 unsigned-ALU 无需修改即可用于签名操作。那是完全错误的。许多操作(如添加和非扩展 mul)不依赖于操作数的符号,但有些操作,如扩展 mul/div,尽管您可以轻松地从无符号操作中获得有符号结果,反之亦然Why are signed and unsigned multiplication different instructions on x86(-64)?,@987654322 @
-
也就是说,您可以使用相同的逻辑和一些技巧来执行有符号和无符号操作,而无需加倍电路。还有
void main()is wrong -
这是一个很好的问题,但请注意,使用 C 的“测试”部分充满了未定义的行为 (signed integer overflow)、乘法 (
-32768 * -32768overflows a signedint) 和循环计数器!如果使用 gcc,this code is safe with-fwrapv,我想。 (如果没有它,它可能会发生,尤其是-O0。) -
"void main()",未定义的溢出行为 - 这一切在这里都无关紧要。
标签: assembly integer-arithmetic