计算进位标志
Calculating Carry Flag
我正在 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中正确实现进位标志?
如果 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));
所有这些绝对价值业务都是不必要的,坦率地说令人困惑,并且它有一个边缘案例 Math.abs(Integer.MIN_VALUE)
是负面的(当你认真对待它时并不奇怪,但它看起来不像这个代码期望它),你可以用更简单的方式计算进位。
例如使用旧的 "result is unsigned less than one operand"。结果当然只是x + y
(如int
),符号与加法无关。然后用Java8,可以用Integer.compareUnsigned,否则可以用这个身份:
x <u y = (x ^ Integer.MIN_VALUE) <s (y ^ Integer.MIN_VALUE)
其中 <u
和 <s
分别是无符号小于和有符号小于。
您还可以计算 (x & 0xffffffffL) + (y & 0xffffffffL)
并将其用于结果(转换为 int
)和进位标志(第 33 位)。
我正在 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中正确实现进位标志?
如果 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));
所有这些绝对价值业务都是不必要的,坦率地说令人困惑,并且它有一个边缘案例 Math.abs(Integer.MIN_VALUE)
是负面的(当你认真对待它时并不奇怪,但它看起来不像这个代码期望它),你可以用更简单的方式计算进位。
例如使用旧的 "result is unsigned less than one operand"。结果当然只是x + y
(如int
),符号与加法无关。然后用Java8,可以用Integer.compareUnsigned,否则可以用这个身份:
x <u y = (x ^ Integer.MIN_VALUE) <s (y ^ Integer.MIN_VALUE)
其中 <u
和 <s
分别是无符号小于和有符号小于。
您还可以计算 (x & 0xffffffffL) + (y & 0xffffffffL)
并将其用于结果(转换为 int
)和进位标志(第 33 位)。