0

the result should have a negative value, but its positive.

How can I fix this?

Thanks!!

BigInteger b = new BigInteger("80000000000000004308000000000000", 16);

System.out.println("long value: "+b.longValue());

--> long value: 4830110600354856960

user955732
  • 1,330
  • 3
  • 21
  • 48
  • 1
    I do not understand, why should it be negative? – Nican Sep 28 '11 at 15:24
  • @Nican His number actually starts with the 4 and does fit into a long. I think the 8 at the start is an attempt to denote a sign using two's complement. – Jeff Ferland Sep 28 '11 at 15:47
  • @JeffFerland The BigNumber constructor specified if a number is suppose to be negative, you have to put the optional "-" sign in front. – Nican Sep 28 '11 at 15:49
  • @Nican I detailed that constrictor issue in my answer below. Just theorizing on why the asker expects a negative value. – Jeff Ferland Sep 28 '11 at 16:15

3 Answers3

1

http://download.oracle.com/javase/1,5,0/docs/api/java/math/BigInteger.html#longValue%28%29

See the above page to understand why it won't be negative. It returns the low 64bits, so your last 64 bits must be higher than Long.MAX_VALUE to cause a negative value.

SHiRKiT
  • 1,024
  • 3
  • 11
  • 30
1

Your string representation is a signed long but is being presented to BigInteger as an unsigned string (sign is denoted by using a "-" at the start of your string).

The String representation consists of an optional minus sign followed by a sequence of one or more digits in the specified radix.

Bit shifting or correcting your string is needed to make this work from a string instantiation.

I think the best answer is to convert your string to a byte array and use the BigInteger(byte[] val) instantiation which will recognize a negative or positive number based on two's complement. Many options exist for that string to byte array conversion. Take your pick.

... oh, and your number is too large to fit into a long, so that's going to be an issue too; you get the least significant bits.

Community
  • 1
  • 1
Jeff Ferland
  • 17,832
  • 7
  • 46
  • 76
0

If you always have 128-bit numbers and assume the highest bit is your sign then you can use the following lines:

BigInteger neg = BigInteger.ONE.shiftLeft(127);
BigInteger b = new BigInteger("80000000000000004308000000000000", 16);
if(b.compareTo(neg) >= 0) { 
    b = neg.subtract(b); 
}

Note: b.longValue() will only be appropriate if the number of bits fits into a long which may not be the case for such large numbers.

Howard
  • 38,639
  • 9
  • 64
  • 83