是否存在用于无符号数字类型包装器的Java库?

时间:2011-11-19 09:09:32

标签: java numbers unsigned

显然,Java本身并不支持无符号数字类型and that's not going to change soon(从2002年开始的评论)。但是,在使用MySQL等数据库时,它们可能会偶尔派上用场。有很多问题涉及如何模拟无符号数。例如:

所有这些都表面上描述了可以完成的方式。但是,是否有任何库实际上一直在为UByteUShortUIntegerULong实现合适的包装器?优选地,那些包装器将扩展java.lang.Number并提供类似于java.math.BigInteger的算术API。

this document中可以看出,有很多可以想到的,还有很多可能出错的地方(比如如何按位移位,如何繁殖等),所以我不会&#39我想自己做。另外,我不想只使用下一个更高的类型(例如Short而不是Byte等)。我希望保留8-bit16-bit32-bit64-bit号码的概念,以便与数据库进行最佳互动。

更新

在回答之前!考虑到我知道所有的解决方法,但我真的非常希望确切地拥有具有上述属性的4种类型。也许有人已经这样做了,这就是我问的原因。无需提醒我解决方法。

5 个答案:

答案 0 :(得分:27)

当我在jOOQ内部需要这个功能时,我找不到类似的东西,所以我推出了自己的开源库,我称之为jOOU(U代表无符号):

http://github.com/jOOQ/jOOU

我知道有些人可能会认为这有点过分,但我真的希望准确地包含其他语言称为ubyteushortuint,{{1 }}。希望与Valhalla一起,这些包装可以变成价值类型。

当然,非常欢迎对算术/按位操作实现的贡献!

答案 1 :(得分:20)

有些原因导致没有人以你想要的方式创建这些包装器。

  • 性能
  • 垃圾收集器开销
  • 没有自动装箱/拆箱
  • 糟糕/无用的界面。
  • 更容易处理它的方法

前四点由小C示例证明:

unsigned int x=42, y, m=5, t=18;
y = x * m + t;

这将被翻译成:

UInteger m = new UInteger(5);
UInteger t = new UInteger(18);
UInteger x = new UInteger(42);

UInteger y = x.multiplyBy(m);
y = y.add(t);

必须创建多个包装器对象,multiplyByadd将生成更多。如果以这种方式进行许多计算,这将给垃圾收集器带来相当大的负担。包装和展开也会耗尽你的CPU。

即使简单的算术也是PITA写入或读取也很明显。

出于同样的原因,NOBODY使用签名的包装器类型进行算术运算。

如果您使用下一个更大的签名类型进行计算并切断上半部分,则所有这些都是不必要的:

long x=42, y, m=5, t=18
y = (x*m + t) & 0xFFFFFFFF;

Java和数据库之间的转移也可以使用下一个最大的签名类型完成。由于JDBC不会创建这些未签名的包装器类型,因此您必须自己完成此操作才能将数据转换为未签名的包装器。

我为自己完成了一些CPU密集型数据处理并处理了二进制协议。在这些场合,我希望我也有未签名的数据类型。但是使用包装器类型在Java中模拟它们比在每个场合直接处理问题更有问题。

答案 2 :(得分:2)

在commons-primitives中使用的解决方案,用于unsignedInt数组,它传递给long作为unsigned int。你可以在这里阅读更多内容:

http://commons.apache.org/primitives/apidocs/org/apache/commons/collections/primitives/ArrayUnsignedIntList.html

答案 3 :(得分:2)

    // Java 8
    int vInt = Integer.parseUnsignedInt("4294967295");
    System.out.println(vInt); // -1
    String sInt = Integer.toUnsignedString(vInt);
    System.out.println(sInt); // 4294967295

    long vLong = Long.parseUnsignedLong("18446744073709551615");
    System.out.println(vLong); // -1
    String sLong = Long.toUnsignedString(vLong);
    System.out.println(sLong); // 18446744073709551615

    // Guava 18.0
    int vIntGu = UnsignedInts.parseUnsignedInt(UnsignedInteger.MAX_VALUE.toString());
    System.out.println(vIntGu); // -1
    String sIntGu = UnsignedInts.toString(vIntGu);
    System.out.println(sIntGu); // 4294967295

    long vLongGu = UnsignedLongs.parseUnsignedLong("18446744073709551615");
    System.out.println(vLongGu); // -1
    String sLongGu = UnsignedLongs.toString(vLongGu);
    System.out.println(sLongGu); // 18446744073709551615

答案 4 :(得分:1)

另一个要考虑的库是Google的 Guava 。它支持以下无符号类型:

他们确实扩展 Number 并实现算术运算。