计算进位标志

时间:2015-07-01 19:38:24

标签: java x86 intel carryflag

我正在用Java编写一个x86解释器,并且有一个Python脚本,可以使用NASM测试我对x86指令的实现。 根据此测试,除了进位标志外,所有标志都设置正确。 有趣的是:

long result;
    switch (op) {
    case ADD:
        result = Math.abs(x) + Math.abs(y);
        if (result > U_MAX)
            registers.carry_flag = true;
        else
            registers.carry_flag = false;
        break;

其中 U_MAX 是4294967295L(全部32位设置)。
我发现的所有答案都没有意识到携带和溢出是两回事。那么,如何在Java中正确实现进位标志?

2 个答案:

答案 0 :(得分:2)

所有这些绝对价值的业务都是不必要的,并且坦率地令人困惑,并且它具有Math.abs(Integer.MIN_VALUE)为负的边缘情况(当你开始使用它时并不奇怪,但它看起来不像这个代码期望它),你可以用更简单的方式计算进位。

例如,使用旧的“结果是无符号的少于一个操作数”。结果当然只是x + y(作为int),签名与添加无关。然后使用Java 8,您可以使用Integer.compareUnsigned,否则您可以使用此标识:

x <u y = (x ^ Integer.MIN_VALUE) <s (y ^ Integer.MIN_VALUE)

其中<u<s的无符号小于和小于的符号。

您还可以计算(x & 0xffffffffL) + (y & 0xffffffffL)并将其用于结果(强制转换为int)和进位标志(第33位)。

答案 1 :(得分:0)

如果x和y是整数,则Math.abs(x)和Math.abs(y)是整数。假设x = y = Integer.MAX_VALUE,添加Math.abs(x)+ Math.abs(y)的结果将为负数,如此程序所示:

public class t {
    public static void main(String args[]) {
        int x = Integer.MAX_VALUE;
        int y = Integer.MAX_VALUE;
        System.out.println(x+y);
    }
}

$ javac t.java
$ java t
 -2

因此,您应该先添加x和y long,或投放到long,然后再添加:result = ((long)Math.abs(x)) + ((long)Math.abs(y));