How to convert only the integer part of a BigDecimal to hex string?
Solution 1
Judging by your example you should use BigInteger
instead of BigDecimal
. This way you could use
new BigInteger("18446744073709551616").toString(16)
If you can't change type of original object convert it to BigInteger later in method
new BigDecimal("18446744073709551616").toBigInteger().toString(16);
Solution 2
Take into account that converting a decimal value into hex requires an exponent. You could get the hexadecimal String representing a numeric value using Formatter
.
%A : The result is formatted as a hexadecimal floating-point number with a significand and an exponent
%X: The result is formatted as a hexadecimal integer
Use the %A
conversion if you want to convert a decimal value:
System.out.println(String.format("%A", myBigDecimal));
Curiously, the code above is correct regarding the javadoc for Formatter
, but there seems to be a related 9-year-old error in the javadocs, that has been fixed a few weeks ago in Java 8: 5035569 : (fmt) assertion error in Formatter for BigDecimal and %a. You can use the analog code below:
System.out.println(String.format("%A", myBigDecimal.doubleValue()));
EDIT
Judging by the value in your post, you don't really care about the fractional part. You could use the %X
conversion in the pattern and just provide the BigInteger
representation:
BigDecimal bd = new BigDecimal("18446744073709551616");
System.out.println(String.format("%X", bd.toBigInteger()));
Solution 3
Theoretically it is possible to represent BigDecimal as a hex string, simiolar to Double.toHexString
0x1.199999999999p+1
but AFAIK there is no standard way to do it and custom implementation will not be easy
becks
Updated on June 05, 2022Comments
-
becks almost 2 years
I have a number of type BigDecimal, for example 18446744073709551616, and I want to convert it to hexadecimal value. I'm fine with truncating the fractional portion.
Is there a way to do this instead of doing it manually?
-
becks about 11 yearsbut for toString method it converts for example "16" to "10" not F as it should be in HEX representation. is there anything to get the correct one ?
-
Pshemo about 11 years@becks it is correct result. Hex
F
is dec15
. Take a looka=10
,b=11
,c=12
,d=13
,e=14
,f=15
. So decimal16
would be10
hexadecimal. -
becks about 11 yearsI get this error for the first one -- java.util.IllegalFormatConversionException: a != java.math.BigDecimal at java.util.Formatter$FormatSpecifier.failConversion(Formatter.java:3999)
-
becks about 11 yearsI get this, but is there a method to convert it automatically to letters representation instead of 10 11 to 15 ? or I do it manually ?
-
Xavi López about 11 yearsYes, it's strange and might be related to a bug: 5035569 : (fmt) assertion error in Formatter for BigDecimal and %a (the javadoc for
Formatter
states it's possible to convert aBigDecimal
). Use the form below, usingdoubleValue()
and it will work. -
Pshemo about 11 years@becks What do you mean? It converts dec to hex correctly (with
a,b,c,d,e,f
)new BigInteger("30").toString(16)
returns"1e"
which is expected result. -
Xavi López about 11 years
-
becks about 11 yearsThanks for the clarification. I used doublevalue for the above value in the code but the result was 0X1.0P64 instead of 0XFFFFFFFFFFFFFF80 is this expected ?
-
Pshemo about 11 yearssince 16 *
1
+ 1 *e
= 16 + 14 = 30. -
becks about 11 yearsI tried it for the value in my post but it converted it to 10000000000000000 instead of FFFFFFFFFFFFFF80 Is this expected ?
-
Evgeniy Dorofeev about 11 yearsI am getting java.util.IllegalFormatConversionException: a != java.math.BigDecimal for String.format("%A", new BigDecimal("1.1")
-
Xavi López about 11 yearsThere's an error in the javadocs. It turns out
%A
doesn't acceptBigDecimal
. Pass inBigDecimal.doubleValue()
. -
Pshemo about 11 years@becks why do you think
18446744073709551616
isFFFFFFFFFFFFFF80
? -
becks about 11 yearssorry guys, I miss calculated it. Thanks a lot for the help :-)
-
Pavel Evstigneev over 7 yearsThis will remove leading zeros
-
Pshemo over 7 years@PavelEvstigneev Remember that purpose of BigInteger is to hold very big numbers which
int
orlong
can't hold. How many leading zeroes would you expect and why? -
Pavel Evstigneev over 7 yearsI try to use it for MD5 and SHA1 hash sums, and if result should be starting with 0 then .toString(16) will remove leading zero
-
Pshemo over 7 years@PavelEvstigneev in that case you are probably looking for solution like stackoverflow.com/questions/32186197/… (although I would use
replace(' ','0')
instead ofreplace(" ","0")
for possible performance increase). If I am not mistaken BigInteger can't simply assume amount of needed leading zeroes since it isn't type with predefined size like int (32 bits) or long (64 bits). It could be nice to have method liketoString(radix, predefinedSize)
to handle cases like yours, but I am not aware of any of these in standard Java. -
Pshemo over 7 years@PavelEvstigneev This answer of Jon Skeet may also interest you: stackoverflow.com/a/10275845