我想模拟 x86 扩展精度类型并执行算术运算并强制转换为 Java 中的其他类型。
我可以尝试使用 BigDecimal 来实现它,但涵盖围绕 NaN、无穷大和强制转换的所有特殊情况可能是一项乏味的任务。我知道一些库提供了比双精度更高的其他浮点类型,但我希望具有与 x86 80 位浮点相同的精度。
是否有提供这种浮点类型的 Java 库?如果没有,您能否提供其他提示,以比提出自定义 BigDecimal 解决方案更轻松地实现这种数据类型?
我想模拟 x86 扩展精度类型并执行算术运算并强制转换为 Java 中的其他类型。
我可以尝试使用 BigDecimal 来实现它,但涵盖围绕 NaN、无穷大和强制转换的所有特殊情况可能是一项乏味的任务。我知道一些库提供了比双精度更高的其他浮点类型,但我希望具有与 x86 80 位浮点相同的精度。
是否有提供这种浮点类型的 Java 库?如果没有,您能否提供其他提示,以比提出自定义 BigDecimal 解决方案更轻松地实现这种数据类型?
如果您知道您的 Java 代码实际上将在 x86 处理器上运行,请在汇编(或 C,如果 C 编译器支持)中实现 80 位算术并使用 JNI 调用。
如果您的目标是特定的非 x86 平台,请查看 qemu 代码。应该有某种方法可以只删除执行 80 位浮点操作的部分。(编辑:qemu 的实现是SoftFloat。)。用 JNI 调用它。
如果您真的想要跨平台的纯 Java 80 位算法,您可能仍然可以将其与开源 CPU 仿真器中的 C 实现进行比较,以确保您解决了正确的极端情况。
最好将 80 位值保存为 a long
(用于尾数)和a(用于int
指数和符号)的组合。对于许多操作,将 long 的上半部分和下半部分放入单独的“long”值中可能是最实用的,因此将两个数字相加的代码和匹配的符号和指数可能类似于:
long resultLo = (num1.mant & 0xFFFFFFFFL)+(num2.mant & 0xFFFFFFFFL);
long resultHi = (num1.mant >>> 32)+(num2.mant >>> 32)+(resultLo >>> 32);
result.exp = num1.exp; // Should match num2.exp
if (resultHi > 0xFFFFFFFFL) {
exponent++;
resultHi = (resultHi + ((resultHi & 2)>>>1)) >>> 1; // Round the result
}
rest.mant = (resultHi << 32) + resultLo;
周围有点麻烦,但并非完全不可行。关键是将数字分解成足够小的碎片,以便您可以将所有数学运算都输入“long”。
顺便说一句,请注意,如果其中一个数字最初没有相同的指数,则有必要在将其向左或向右移动以匹配第一个数字的指数时跟踪是否有任何位“落到最后”,所以以便之后能够正确舍入结果。
这有点与 java strictfp选项相反,它将计算限制为 8 个字节,而它执行 80 位。
所以我的答案是在 64 位机器上运行 JVM,也许在一些虚拟机管理程序/OS VM 上,所以你有一个开发平台。