I’m working on processing video files in Java.  Often, video files will have "unsigned int" or other types that don’t exist in Java.  Unsigned int is easy enough to simulate (using a long), but what about an unsigned long?  No Java primitive integer type is large enough to hold the value of an unsigned long.  Double could do it, but then you lose the ability to use bitwise shift operators and have them do what you expect.

Enter java.math.BigInteger.  BigInteger is a standard, but often overlooked, part of the Java.  The following sample shows how I use BigInteger to simulate an unsigned long in Java.

import java.math.*;

public class ReadUnsignedLong {

    public static void main(String[] args) {
        byte input[] = {(byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff}; // 64 bits, signed long = -1
        BigInteger signed = new BigInteger(input);
        BigInteger unsigned = new BigInteger(1, input);
        System.out.println("Max Long : " + Long.MAX_VALUE);
        System.out.println("Min Long : " + Long.MIN_VALUE);
        System.out.println("Signed   : " + signed);
        System.out.println("Unsigned : " + unsigned);
        
        System.out.println("Unsigned > Long.MAX_VALUE ? " + ((unsigned.compareTo(BigInteger.valueOf(Long.MAX_VALUE))==1) ? "true" : "false"));
        System.out.println("Signed == -1 ? " + (signed.compareTo(BigInteger.valueOf(-1)) == 0 ? "true" : "false"));
                
        System.out.println("Signed * 2 : " + (signed.multiply(BigInteger.valueOf(2))));
        System.out.println("Unsigned * 2 : " + (unsigned.multiply(BigInteger.valueOf(2))));

    }

}

Note that the trick here is to use the BigInteger(signum, byte[]) constructor.  By forcing the signum to positive (using a 1), you get the unsigned value of the byte array.

The output:

Max Long : 9223372036854775807

Min Long : -9223372036854775808

Signed   : -1

Unsigned : 18446744073709551615

Unsigned > Long.MAX_VALUE ? true

Signed == -1 ? true

Signed * 2 : -2

Unsigned * 2 : 36893488147419103230

4 Responses to “BigInteger as unsigned long in Java”

  1. Thanks! Was trying to wrap my brain around this problem and found your post.

  2. You saved me, i am reading unsigned 64 bits long for my peter-dwarf library

    • Cool site, Peter. I had never heard of Dwarf, but I will look into it. Also, I dabbled a bit in OS development a few years ago. It certainly teaches you a lot about what is going on behind the curtain.

      I’ll see if I can link your page from this blog somewhere (I don’t allow URLs in comments, because spammers). Anyone curious before then can see it at http://peter.kingofcoders.com though.

      Edit: OK, apparently the names are linked to the submitted URLs. Strange I thought I turned that off. Oh well, click on the link above or Peter’s name if you are interested.

  3. I like your writing style truly enjoying this website.

Leave a Reply

Your email address will not be published. Required fields are marked *