我正在用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中正确实现进位标志?
答案 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));