Is there a Java library for unsigned number type wrappers? [closed]

醉酒当歌 提交于 2019-11-27 01:15:24

问题


Obviously, Java doesn't support unsigned number types natively, and that's not going to change soon (comments starting in 2002). However, when working with databases, such as MySQL, they may come in handy every now and then. There are a lot of questions dealing with how to simulate unsigned numbers. For example:

  • unsigned short in java
  • Java: Unsigned numbers
  • Understanding Java unsigned numbers

All of them superficially describe how it could be done. But is there any library actually going all the way and implementing suitable wrappers for UByte, UShort, UInteger, ULong? Preferably, those wrappers would extend java.lang.Number and provide an arithmetic API similar to that of java.math.BigInteger.

As can be seen in this document, there's a lot to think of, and a lot that can go wrong (e.g. how to bitwise shift, how to multiply, etc), so I don't want to do it myself. Also, I don't want to just use the next higher type (e.g. Short instead of Byte, etc.). I want the notion of an 8-bit, 16-bit, 32-bit, 64-bit number preserved, for best interaction with databases, for instance.

UPDATE:

Before you answer! Consider that I know all the workarounds, but I'd really really like to have exactly those 4 types with exactly the above properties. And maybe someone has already done that, so that's why I ask. No need to remind me of the workarounds.


回答1:


When I needed this functionality inside of jOOQ, I haven't found anything like it, so I rolled my own Open Source library that I call jOOU (U for Unsigned):

http://github.com/jOOQ/jOOU

I understand that some may think this is overkill, but I'd really like to have precisely those wrappers wrapping what other languages call ubyte, ushort, uint, ulong. Hopefully with Valhalla, those wrappers can be turned into value types.

Of course, contributions to the arithmetics / bitwise operation implementations are very welcome!




回答2:


There are some reasons why nobody created these wrappers in the way you want.

  • Performance
  • Garbage collector overhead
  • no autoboxing / unboxing
  • bad / useless interface.
  • easier ways to deal with it exists

The first four points are demonstrated by a small C example:

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

This would be translated into:

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

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

Several wrapper objects must be created, multiplyBy and add will generate some more. This will put quite some burden on the garbage collector if many calculations are done this way. The wrapping and unwrapping will also eat up your CPUs for nothing.

That even simple arithmetic is a PITA to write or read is also obvious.

For the same reasons NOBODY does arithmetic using the signed wrapper types.

All this is unnecessary if you do the calculations using the next-bigger signed type and cut off the upper part like this:

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

Transfer between Java and a database can also be done using the next biggest signed type. And since JDBC will not create these unsigned wrapper types you would have to do exactly that by yourself only to transform the data into the unsigned wrappers thereafter.

I have done some CPU intensive data processing for myself and handled binary protocols. On these occasions I wished I had unsigned datatypes also. But emulating them in Java with wrapper types would have been more problematic than dealing with the problem directly on each single occasion.




回答3:


The solution that is used in commons-primitives for an array of unsignedInt it to pass around a long consider this as an unsigned int. You can read more here:

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




回答4:


    // 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



回答5:


Another library to consider is Google's Guava. It supports the following unsigned types:

  • UnsignedInteger
  • UnsignedLong

they do extend Number and implement arithmetic operations.



来源:https://stackoverflow.com/questions/8193031/is-there-a-java-library-for-unsigned-number-type-wrappers

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!