【问题标题】:x86 80-bit floating point type in JavaJava中的x86 80位浮点类型
【发布时间】:2015-10-29 15:56:42
【问题描述】:

我想模拟 x86 扩展精度类型并执行算术运算并转换为 Java 中的其他类型。

我可以尝试使用 BigDecimal 来实现它,但涵盖围绕 NaN、无穷大和强制转换的所有特殊情况可能是一项乏味的任务。我知道一些库提供了比双精度更高的其他浮点类型,但我希望具有与 x86 80 位浮点相同的精度。

是否有提供这种浮点类型的 Java 库?如果没有,您能否提供其他提示,以比提出自定义 BigDecimal 解决方案更轻松地实现这种数据类型?

【问题讨论】:

  • 这听起来是个有趣的问题,但为什么要模拟 80 位扩展精度格式呢?为什么不模仿更精确的东西?
  • 在这种情况下,与标准 IEEE 754 相比,模拟对次正规数的古怪处理会很有趣:en.wikipedia.org/wiki/…
  • BigDecimal 适合这个问题; BigDecimal 表示 十进制 的 10 次方数;您想要的类型表示 二进制 2 的幂数,混合它们并不是一个好计划。
  • “不是一个好计划”是轻描淡写的。 “注定要失败”更像是这样:)
  • @NayukiMinase:80 位浮点不像其他类型那样具有次正规,因为它使用显式而不是隐式前导 1。当存储指数低于最小允许值的结果时,需要进行一些特殊处理,但与其他需要对加载和存储进行特殊处理的格式相比,它的麻烦要少。

标签: java floating-point precision x86-emulation


【解决方案1】:

如果您知道您的 Java 代码实际上将在 x86 处理器上运行,请在汇编(或 C,如果 C 编译器支持)中实现 80 位算术并使用 JNI 调用。

如果您的目标是特定的非 x86 平台,请查看 qemu 代码。应该有一些方法可以只删除执行 80 位浮点操作的部分。 (编辑:qemu 的实现是SoftFloat。)。用 JNI 调用它。

如果您真的想要跨平台的纯 Java 80 位算法,您可能仍然可以将其与开源 CPU 模拟器中的 C 实现进行比较,以确保您解决了正确的极端情况。

【讨论】:

  • 我非常同意你的回答。深入研究 C/asm,或重用现有的 C 代码,或构建一个新的实现,与本机代码或现有的模拟器进行比较。
  • 我想用纯Java代码。我想我必须按照您的建议查看用另一种语言编写的现有实现。
【解决方案2】:

最好将 80 位值保存为 long(用于尾数)和 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;

有点麻烦,但并非完全不可行。关键是 把数字分解成足够小的碎片,这样你就可以做所有的数学运算 输入“长”。

顺便说一句,请注意,如果其中一个数字最初没有相同的指数, 有必要跟踪是否有任何位“掉到最后” 将其向左或向右移动以匹配第一个数字的指数,以便 之后能够正确地对结果进行四舍五入。

【讨论】:

  • 谢谢!这是帮助我实施的最有用的提示。
【解决方案3】:

这有点与 java strictfp 选项相反,限制计算在 80 位的情况下为 8 个字节。

所以我的答案是在 64 位机器上运行 JVM,也许在某些虚拟机管理程序/OS VM 上,所以你有一个开发平台。

【讨论】:

  • 那行不通。 strictfp 允许一些余地,但依靠 JIT 实际使用 80 位浮点数作为中间值对我来说听起来是错误的。此外,strictfp(或反向选项)不会影响存储,它仍然是双位宽度。
  • 即使你省略了 strictfp 关键字,现代 JVM 也可能会使用 x86 SSE 指令来执行纯 64 位或 32 位 FP 数学运算,而不是使用 x87 更宽的寄存器。
  • 感谢您的启发。所以简单地找一个80位的JVM,然后用一个VM来拥有一个可移植的开发环境,按照上面的cmets不会那么容易。用于嵌入式设备的 Java JVM 通常有模拟器;虽然它们通常是商业的,而 Real Java 是用于 64 位 fp 的。
猜你喜欢
  • 1970-01-01
  • 2012-11-08
  • 1970-01-01
  • 1970-01-01
  • 2015-01-12
  • 2012-09-30
  • 2010-09-24
  • 2022-06-11
  • 1970-01-01
相关资源
最近更新 更多