【问题标题】:Which arithmetic operations are the same on unsigned and two's complement signed numbers?无符号数和二进制补码有符号数的哪些算术运算相同?
【发布时间】:2014-02-23 20:46:06
【问题描述】:

我正在设计一个简单的玩具指令集和附带的模拟器,并且我正在尝试找出支持哪些指令。在算术方面,我目前有无符号加减乘除。但是,我似乎无法找到以下问题的明确答案:哪些算术运算符需要有符号版本,哪些无符号和二进制补码有符号版本等效?

因此,例如,二进制补码中的 1111 等于 -1。如果你给它加 1 并假装它是一个无符号数,你会得到 0000,即使将它视为 -1 也是正确的。但是,这适用于所有数字吗?那么其他三个操作(减法、乘法、除法)呢?

【问题讨论】:

标签: binary twos-complement instructions instruction-set


【解决方案1】:

加法、减法和乘法是一样的:

  1. 您的输入和输出大小相同
  2. 您的溢出行为是模 2 环绕n

部门不同。

许多指令集提供输出大于输入的乘法运算,对于有符号和无符号,这些也是不同的。

此外,如果您使用 C 编写模拟器,则需要注意该语言的一些错误功能。

  1. C 中带符号算术的溢出是未定义的行为。要获得可靠的模 2n 行为算术,必须使用无符号类型执行。
  2. C 会将小于 int 的类型提升为 int。需要非常小心地避免此类提升(在计算开始时添加 0u 或乘以 1u 是一种方法)。
  3. 从无符号类型到有符号类型的转换是由实现定义的,我见过的实现是明智的,但可能有些不是。

【讨论】:

    【解决方案2】:

    加法和减法对于有符号和无符号 2s 补码是相同的,假设您要以大多数 CPU 的正常方式处理溢出/下溢,即只是环绕。乘法和除法不同。所以你只需要一个加法例程和一个减法例程而不管有符号性,但你需要单独的有符号和无符号乘法和除法。

    【解决方案3】:

    您的所有操作都需要溢出检查,否则在某些情况下它们会返回不正确的值。这些检查的未签名版本与签名版本不同,因此您需要分别实现每个例程。

    【讨论】:

    • 因为这是一个指令集模拟器,我希望整数上溢/下溢会以通常的方式运行,即环绕模 2^N,因此加减法对于有符号和未签名。
    • 实际指令集通常处理这种情况的方式是使用多个标志来检测不同类型的溢出。
    猜你喜欢
    • 2015-11-28
    • 2011-06-23
    • 2021-11-27
    • 2021-07-30
    • 2013-10-28
    • 2020-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多