Decimal-Java 是一个用于在 java.math.BigDecimal 与 IEEE-754r 之间相互转换的库

发布: (2026年2月24日 GMT+8 17:15)
4 分钟阅读

Source: Hacker News

decimal-java

Decimal-java 是一个库,用于在 java.math.BigDecimal 与 IEEE‑754r(IEEE‑754‑2008)十进制字节表示之间相互转换。

Java CI with Gradle
Maven Central

Maven

从 Maven 获取 decimal-java

<dependency>
    <groupId>org.firebirdsql</groupId>
    <artifactId>decimal-java</artifactId>
    <version>2.0.1</version>
</dependency>

或使用以下坐标:

org.firebirdsql
decimal-java
2.0.1

许可证

此库遵循 MIT 许可证;另请参阅 LICENSE.md

状态

API 稳定,预计不会更改。

  • 版本 2.0.0 及以上需要 Java 17 或更高,并使用模块名 org.firebirdsql.decimal 进行模块化。
  • 版本 1.0.2 需要 Java 7 或更高,并声明自动模块名 org.firebirdsql.decimal

Goals

该库提供 java.math.BigDecimal 与 IEEE‑754r 十进制格式之间的转换。具体支持的字节表示为:

  • decimal32
  • decimal64
  • decimal128

其他格式(任意精度十进制)暂无计划。

非目标

该库 包含对十进制值的数学运算。进行算术运算时,请使用带有 MathContext.DECIMAL128MathContext.DECIMAL64MathContext.DECIMAL32BigDecimal

用法

完整的 Javadoc(最新标记发布):

解码 Decimal32

byte[] bytes = {(byte) 0xc7, (byte) 0xf4, (byte) 0xd2, (byte) 0xe7};
Decimal32 decimal32 = Decimal32.parseBytes(bytes);
BigDecimal bigDecimal = decimal32.toBigDecimal();
assertEquals(new BigDecimal("-1.234567E+96"), bigDecimal);

toBigDecimal() 在值为无穷大或 NaN 时抛出 DecimalInconvertibleException;异常中包含实际的类型和符号。

编码 Decimal32

BigDecimal bigDecimal = new BigDecimal("-7.50E-7");
Decimal32 decimal32 = Decimal32.valueOf(bigDecimal);
byte[] bytes = decimal32.toBytes();
assertArrayEquals(new byte[] {(byte) 0xa1, (byte) 0xc0, 0x03, (byte) 0xd0}, bytes);

如果 BigDecimal 不适合 Decimal32,会进行四舍五入;溢出则四舍五入为无穷大。若要拒绝溢出:

Decimal32 decimal32 = Decimal32.valueOf(bigDecimal, OverflowHandling.THROW_EXCEPTION);
byte[] bytes = decimal32.toBytes();
assertArrayEquals(new byte[] {(byte) 0xa1, (byte) 0xc0, 0x03, (byte) 0xd0}, bytes);

Decimal64Decimal128 的转换方式类似。

可用的 valueOf 重载

  • BigDecimal
  • BigInteger(包括在四舍五入时抛出 DecimalOverflowExceptionvalueOfExact(BigInteger)
  • String
  • double

父类 DecimalDecimal32Decimal64Decimal128 的超类)同样提供十进制类型之间的转换。

转换方法

  • toBytes()
  • toBigDecimal() – 对于无穷大/NaN 抛出 DecimalInconvertibleException
  • toString()
  • doubleValue()
  • toDecimal(Class)toDecimal(Class, OverflowHandling)

若要获取 BigInteger,请使用 toBigDecimal().toBigInteger(),并注意大数值(尤其是 Decimal128)可能会占用大量内存。

背景

Firebird 4.0 在协议中引入了 SQL DECFLOAT 类型(精度为 16 位和 34 位),使用 decimal64decimal128。Jaybird,Firebird 的 JDBC 驱动,需要支持这些格式。由于没有找到合适的库,decimal-java 被创建并作为独立项目发布,以供更广泛的使用。Jaybird 包含该库的副本,以避免在非 Maven/Gradle 环境中产生额外的依赖。

参考文献

SPDX-License-Identifier: MIT

0 浏览
Back to Blog

相关文章

阅读更多 »

商店3

gradle 任务 runQuantumtype: JavaExec { dependsOn prepareLibDir, classes systemProperty 'org.gradle.scan.acceptTerm', 'true' doFirst { setTmpDir buildFileSystem'...