Cannot convert all hex values to binary - java

Scanner scanner = new Scanner(System.in);
String input = scanner.nextLine();
System.out.println(input);
int a = Integer.parseInt(input.substring(2), 16);
System.out.println(Integer.toBinaryString(a));
Above mentioned code that takes in hex value and convert it into binary. However, this would not work on input "0xBE400000" but it works fine for "0x41C20000"

BE400000 is larger than Integer.MAX_VALUE (whose hex representation is 7FFFFFFF).
Therefore you'll need to parse it with
long a = Long.parseLong(input.substring(2), 16);

Since 0xBE400000 is in the range of an unsigned int you can use: parseUnsignedInt(String s, int radix)
int a = Integer.parseUnsignedInt(input.substring(2), 16);
With parseUnsignedInt(input, 16) you can parse values from 0x00000000 to 0xFFFFFFFF, where:
0x00000000 = 0
0x7FFFFFFF = 2147483647 (Integer.MAX_VALUE)
0x80000000 = -2147483648 (Integer.MIN_VALUE)
0xFFFFFFFF = -1
0xBE400000 = -1103101952

You can use Long
long l = Long.parseLong(input.substring(2), 16);
but if your value is greater than 2^63 - 1 you may use use a BigInteger's constructor:
BigInteger(String val, int radix)
Translates the String representation of a BigInteger in the specified radix into a BigInteger.
BigInteger b = new BigInteger(input.substring(2), 16);

Related

How can I convert this large number hex value to decimal

I am trying to convert string ABCDEF1234567890 to decimal value:
long result = 0;
String hex = "0123456789ABCDEF";
decimal = decimal.toUpperCase();
for(int i = 0; i < decimal.length(); i++) {
char c = decimal.charAt(i);
result += hex.indexOf(c) * Math.pow(16, decimal.length() - 1 - i);
}
return Long.toString(result);
I know the class BigInteger but i don't know how to use it in my code. please help me
The BigInteger class has a constructor which accepts a string and radix:
final BigInteger bigInt = new BigInteger(hex, 16);
Note that your specific hex value 0123456789ABCDEF fits into a variable of type long (Long.MAX_VALUE == 0x7fffffffffffffffL) and Long#parseLong accepts a string and radix as well:
final long value = Long.parseLong(hex);

about Java byte type value greater than 256

public void demo(byte[] p,byte[] buffer){
SecretKeySpec signingKey = new SecretKeySpec(p, "HmacSHA1");
int count = 4096;
int num = 1;
Mac mac = Mac.getInstance("HmacSHA1");
mac.init(signingKey);
while(num < count){
byte[] sig = new byte[4];
sig[0] = (byte)num;
mac.update(buffer,0,buffer.length);
mac.update(sig,0,4);
String result = byteArrayToHex(mac.doFinal());
num ++;
}}
if the num value is 256.Will result in incorrect results
what should I do?
I don't know how to do it.
You asked:
Java byte type value greater than 256
Not possible to store values higher than 255.
A byte in Java is an octet, 8-bits. This is true of both the byte primitive type and the Byte wrapper class.
As a signed value, that means a range of -128 to 127. As an unsigned value, that means a range of 0 to 255. In neither case is there room to represent the number 256 or higher.
See details in Comment by Bolwidt.

Binary complement 0 to 1, 1 to 0

I have a number , let say 4 which is in binary represented as 100 , what i will like to achieve is to complement the number i.e. replace 1 by 0 and 0 by 1 . I can achieve it like this
public class Foo {
public static void main(String[] args) {
String binaryString = Integer.toBinaryString(4);
StringBuilder out = new StringBuilder();
char[] chars = binaryString.toCharArray();
char x;
for (char ch : chars) {
if (ch == '1') {
x = '0';
} else {
x = '1';
}
out.append(x);
}
System.out.println(Integer.parseInt(out.toString(), 2));
}
}
What is the most efficient way to achieve the same result in terms of time complexity? Please note that input can be very big numbers and we need to take care of Integer overflow.
Updated
negating a number like ~n will give wrong result , for e.g.
System.out.println(~4);
outputs -5 , expected 3
What is the most efficient way to achieve the same result in terms of time complexity?
Given that the size of int is fixed at 32, the time complexity is O(1). Your program is pretty inefficient, though, because it creates a coupe of strings, does string parsing, and so on.
You can do this faster if you skip the conversion to binary altogether, and simply invert the number, like this:
int val = 4;
int msb = int msb = 32 - Integer.numberOfLeadingZeros(val);
int inverse = ~val & ((1 << msb)-1);
System.out.println(inverse);
The ~ operator is a unary operator that produces a binary complement of the value. The loop computes the position of the most significant bit (MSB). ((1 << msb)-1) is a mask that removes all bits higher than the MSB.
Demo.
You can try using bitwise negation:
private int flipBits(int n) {
return ~n;
}
Why not do something like this:
public static void main(String[] args) {
String binaryString = Integer.toBinaryString(4);
binaryString = binaryString.replaceAll("1", "-");
binaryString = binaryString.replaceAll("0", "1");
binaryString = binaryString.replaceAll("-", "0");
Only 3 lines of code to convert...
BigInteger allows you to use a number of arbitrary length. The way to find the negation is to find the max value possible given the input length and substract the input value from it
//you might want to validate that the string really is a binary number string
BigInteger myNum = new BigInteger(inputStr, 2);
BigInteger max = new BigInteger("2");
max = max.pow(inputStr.length()).subtract(new BigInteger("1"));
BigInteger ans = max.substract(myNum);

How to convert a hex to a number that looks the same when printed in decimal?

I have the following code in Java:
int hex = 0x63;
The decimal value of 6316 is equal to 9910. I would like to convert this hex value to a decimal that is equal to 6310.
the hex value is 0x63, I want to have a decimal value as 63 based on the hex value
This is called a Binary-coded decimal (BCD) representation. There are many ways to convert a number from BCD to decimal. Perhaps the simplest one is to print it as hex, and then parse it back as a decimal:
int hex = 0x63;
int dec = Integer.valueOf(Integer.toHexString(hex), 10);
Demo on ideone.
you can use this:
int hex = 0x63;
int decimalValue = Integer.parseInt(hex+"", 10);
System.out.println("Decimal value is :" + decimalValue);
try this:
int hex = 0x63F2FC;//just an example (containg letters)
String hexStr = Integer.toHexString(hex);
String decimal = "";
char[] tmp = hexStr.toCharArray();
for (int i = 0; i < tmp.length ; i++)
decimal += (Character.isDigit(tmp[i])?tmp[i]+"":"");

Hex digit to binary with only 4 digits

int[] LETTERS = {0x69F99}
I want to convert every single hex digit to binary, for example the 1st hex digit from the 1st hex string (6):
String hex = Integer.toHexString(LETTERS[0]);
String binary = Integer.toBinaryString(hex.charAt(0));
System.out.println(binary);
OUTPUT:110110
If I do this Integer.toBinaryString(6) the output will be 110, but I want something with 4 digits, is it possible?
I'd just pad the string as appropriate with your favorite library or a utility function.
With Guava:
String binary = Strings.padStart(Integer.toBinaryString(hex.charAt(0)), 4, '0'));
Another option would be to simply fill a character buffer and render it as a string, which is essentially what the OpenJDK implementation does:
public static String intToBin(int num) {
char[] buf = new char[4];
buf[0] = num & 0x1;
buf[1] = num & 0x2;
buf[2] = num & 0x4;
buf[3] = num & 0x8;
return new String(buf);
}
You have no string here - just an array with one int so you essentially try to convert this integer into nibbles and this can be done this way:
int num = 0x12345678;
String bin32 = String.format("%32s", Integer.toBinaryString(num)).replace(" ", "0");
System.out.printf("all 32bits=[%s]\n", bin32);
for(int nibble = 0; nibble < 32; nibble += 4)
{
System.out.printf("nibble[%d]=[%s]\n", nibble, bin32.subSequence(nibble, nibble+4));
}
gives:
all 32bits=[00010010001101000101011001111000]
nibble[0]=[0001] ie hex digit 1 as bin
nibble[4]=[0010] ie hex digit 2 as bin
nibble[8]=[0011]
nibble[12]=[0100]
nibble[16]=[0101]
nibble[20]=[0110]
nibble[24]=[0111]
nibble[28]=[1000] ie hex digit 8 as bin

Categories