i have hex value 03E7 which is string in type.i need to apply 2s compliment in this string.and the resultant hex value should be in string format.i first converted it to binary then converted .is there is any simple method?
Negative numbers are the 2's complement of positive numbers and vice versa, so I suppose you could parse your string into an int, multiply by -1, and then parse it back into the resulting hex string.
int intVal = Integer.parseInt("03E7", 16);
String twosComplement = Integer.toHexString((-1 * intVal));
Related
I have next method for converting to int from hex:
public static byte[] convertsHexStringToByteArray2(String hexString) {
int hexLength = hexString.length() / 2;
byte[] bytes = new byte[hexLength];
for (int i = 0; i < hexLength; i++) {
int hex = Integer.parseInt(hexString.substring(2 * i, 2 * i + 2), 16);
bytes[i] = (byte) hex;
}
return bytes;
}
when I use it for "80" hex string I get strange, not expected result:
public static void main(String[] args) {
System.out.println(Arrays.toString(convertsHexStringToByteArray2("80"))); // gives -128
System.out.println(Integer.toHexString(-128));
System.out.println(Integer.toHexString(128));
}
the output:
[-128]
ffffff80
80
I expect that "80" will be 128. What is wrong with my method?
I have next method for converting to int from hex
The method you posted converts a hex String to a byte array, and not to an int. That's why it is messing with its sign.
Converting from hex to int is easy:
Integer.parseInt("80", 16)
$1 ==> 128
But if you want to get a byte array for further processing by just casting:
(byte) Integer.parseInt("80", 16)
$2 ==> -128
It "changes" its sign. For further information on primitives and signed variable types take a look at Primitive Data Types, where it says:
The byte data type is an 8-bit signed two's complement integer. It has a minimum value of -128 and a maximum value of 127 (inclusive). The byte data type can be useful for saving memory in large arrays, where the memory savings actually matters. They can also be used in place of int where their limits help to clarify your code; the fact that a variable's range is limited can serve as a form of documentation.
One could easily invert the sign by just increasing the value to convert:
(byte) Integer.parseInt("80", 16) & 0xFF
$3 ==> 128
That gets you a byte with the value you expect. Technically that result isn't correct and you must to switch the sign again, if you want to get an int or a hex string back again. I'd suggest you to don't use a byte array if you only want to convert between hex and dec.
A byte in Java stores numbers from -128 to 127. 80 in hex is 128 as an integer, which is too large to be stored in a byte. So, the value wraps around. Use a different type to store your value (such as a short).
How do I convert a String written as Binary, to binary (in byte array)?
If I have a String:
String binary = "0000"
I want the binary data to be 0000.
below is what happens when I set the binary to a byte array (which in turn returns 48, which is ASCII)
Binary String: 0000
Binary Byte array: 48
Binary Byte array: 48
Binary Byte array: 48
Binary Byte array: 48
I'm not good at explaining so hopefully the above example was enough to tell you what I want.
EDIT: This is to set the data into a binary file.
Use this:
System.out.println(Integer.toBinaryString(Integer.parseInt("000",2))); // gives 0
System.out.println(Integer.toBinaryString(Integer.parseInt("010",2))); // gives 10
System.out.println(Integer.toBinaryString(Integer.parseInt("100",2))); // gives 100
Maybe you want this:
int i = Integer.valueOf(binary, 2); // ie base 2
This call expects the input to be a string of 0 and 1 chars.
Then if you want an array of bytes:
byte[] bytes = new ByteBuffer().putInt(i).compact().array();
Convert into Decimal from Binary
System.out.println(new BigInteger("1010",2).toString()); // 10 decimal
Convert into Binary/Octal/Hex from Decimal
You can use BigInteger#toString(radix) method to get value in any radix.
System.out.println(new BigInteger("10").toString(2)); // 1010 binary
System.out.println(new BigInteger("10").toString(8)); // 12 octal
System.out.println(new BigInteger("10").toString(16)); // a hexadecimal
Let me explain you a bit more how it works with different base
(10)10 = (1010)2
(10)10 = (12)8
(10)10 = (a)16
JBBP framework has in utils a special method to convert a string contains a binary defined data into byte array
byte [] converted = JBBPUtils.str2bin("00000000");
When dealing with signed int conversion to hex, only Integer.toString(value, 16) is useful
see a post on subject
but I need to format with 4 hex digits (leading zeros for positive numbers and not 32bits/8chars for negatif numbers),
in C++ the right function is IntToHex( value,4)
http://docwiki.embarcadero.com/Libraries/XE3/en/System.SysUtils.IntToHex
But I didn't fiund the equivalent in Java (Android).
Found it :
int StepRef =-2;
String SS = String.format("%08X",StepRef);
String SS4 = SS.substring(SS.length() - 4);
i have a hex value "FF30" in string format.i need the two's complement value of this number.now i am doing,first converting it to binary then taking the 2's complement.is there is any simple way.
Do you need to apply the 2's complement operation to this value, or do you need to just interpret it as a 2's complement number? If the latter, then skip the second line of code below.
I think this will work for you.
int val = Integer.parseInt("FF30", 16);
int result = (~val) + 1;
Update
Since you imply in your comments that you want the result converted back to a string, that's a simple matter of calling "toHexString" and chopping off any padded bits that were prefixed
String hex = "FF30";
int length = hex.length();
long value = Long.parseLong(hex, 16); // convert hex string to long
long result = (~value) + 1; // compute the 2's complement
// convert the result value back to a hex string (keeping the same length and dropping any sign-extension bits)
String resultAsString = Long.toHexString(result);
// chop off the prefix of the string so the result is the same length as the input
int newLength = resultAsString.length();
if (newLength > length)
{
resultAsString = resultAsString.substring(newLength-length);
}
System.out.print(resultAsString);
It seems I have a two's complement issue with Java's BigInteger.
I have a 64-bit integer where only the msb and the second msb are set to 1, the rest is 0.
In decimal this comes up to: -4611686018427387904
The Java side of my application receives this decimal number as a string, and converts it to BigInteger like so:
BigInteger bi = new BigInteger("-4611686018427387904", 10);
Then, it needs to display this number both in binary and hex forms.
I tried to use:
String bin = bi.toString(2);
String hex = bi.toString(16);
but I'm getting:
-100000000000000000000000000000000000000000000000000000000000000
-4000000000000000
whereas I expect to get:
1100000000000000000000000000000000000000000000000000000000000000
c000000000000000
Any tips?
Number always fits in 64 bits:
If your number always fits in 64 bits you can put it in a long and then print the bits / hex digits.
long l = bi.longValue();
String bin = Long.toBinaryString(l);
String hex = Long.toHexString(l);
System.out.println(bin);
System.out.println(hex);
Number may not always fit in 64 bits:
If the number does not always fit in 64 bits, you'll have to solve it "manually". To convert a number to it's two's complement representation you do the following:
If number is positive, do nothing
If number is negative:
Convert it to its absolute value
Complement the bits
Add 1
For a BigInteger the conversion looks as follows:
if (bi.compareTo(BigInteger.ZERO) < 0)
bi = bi.abs().not().add(BigInteger.ONE);
If you print it using bi.toString(2) you'll still get the sign character, instead of a leading 1. This can be solved by simply appending .replace('-', '1') to the string.
There is a BigInteger.toByteArray() method, that returns two's complement representation of BigInteger as a byte[]. All you need is to print that array in hex or binary form:
byte[] bs = bi.toByteArray();
for (byte b: bs) {
System.out.print(String.format("%02X", 0xff & b));
}
The binary number 1100000000000000000000000000000000000000000000000000000000000000 is definitely a positive number, right. It's equal to 2^63 + 2^62.
I don't see why you'd expect a negative number to become positive when you convert to base 2 or base 16.
You are confusing the base n representation with the internal representation of numbers.
If the number is 64 bits or less, then the simple way to solve this is to convert to a long and then use Long.toHexString().
what you mean?
Do you want to get Two's complement?
if you mean that, maybe i can give you an example
import java.util.*;
public class TestBina{
static void printBinaryInt(int i){
System.out.println("int:"+i+",binary:");
System.out.print(" ");
for(int j=31;j>=0;j--)
if(((1<<j)&i)!=0)
System.out.print("1");
else
System.out.print("0");
System.out.println();
}
public static void main(String [] args){
Random rand = new Random();
int i = rand.nextInt();
int j = rand.nextInt();
printBinaryInt(i);
printBinaryInt(j);
printBinaryInt(10);
printBinaryInt(-10);
}
}