Optimal code in Java to convert Integer value into Hexadecimal - java

I need to convert integer value into hexadecimal.
I have done with some logical, but I want the optimized solutions.
EDIT : Sorry I forgot to post that I am not allowed to use any in-built functions.

Easy:
String hex = Integer.toHexString(int);
Basically what this does is creating a new string, and then calling a method from the Integer class called toHexString which needs an int arg.
So pass the int you wanna change into this method and you'll get a String with the hexadecimal version of your int back.
You can put hexadecimal values in int types, but you cannot convert from int type to another int type, as far as i know, when you are doing hexadecimal conversions.
Remember that the value you get back is a String, so you cannot modify the value, otherwise you'll get an number format exception.

Assuming you don't want to use the built in toHexString for some reason, here's one pretty efficient way to do it:
public static char toHexChar(int i) {
i&=15;
return (i<10)? (char)(i+48) : (char)(i+55);
}
public static String toHexString(int n) {
char[] chars=new char[8];
for (int i=0; i<8; i++) {
chars[7-i]=toHexChar(n);
n>>=4;
};
return new String(chars);
}

Well then have a look at the implementation of Integer.toHexString(int). The following code is extracted from the Integer class in the java standard library.
public class Test {
final static char[] digits = {
'0' , '1' , '2' , '3' , '4' , '5' ,
'6' , '7' , '8' , '9' , 'a' , 'b' ,
'c' , 'd' , 'e' , 'f'
};
private static String intAsHex(int i) {
char[] buf = new char[32];
int charPos = 32;
int radix = 1 << 4;
int mask = radix - 1;
do {
buf[--charPos] = digits[i & mask];
i >>>= 4;
} while (i != 0);
return new String(buf, charPos, (32 - charPos));
}
public static void main(String... args) {
System.out.println(intAsHex(77));
}
}
Output: 4d

Check this
public class IntToHexa {
public static void main(java.lang.String args[]){
/*
* Here we need an integer to convert.
* [1]You can pass as command line argument
* [2]You can get as input from console
* [3]Take a constant. Here I'm taking a constant
*/
int intToConvert = 450;
java.lang.StringBuilder convertedHexa = new java.lang.StringBuilder("");
while (intToConvert > 15){
/*
* If the reminder is less than 10, add the remainder. else get the equivalent hexa code
* Here I'm getting the character code and adding the charater to the hexa string.
* For that I'm getting the difference between the reminder and 10.
* For example, if the reminder is 13, the reminder will be 3.
* Then add that difference to 65. In this example, it will become 68.
* Finally, get the quivalent char code of the result number. Here it will be D.
* Same for number, I'm adding it to 48
*/
convertedHexa.append(intToConvert % 16 < 10 ? ((char)(48 + (intToConvert % 16))) : ((char)(65 + (intToConvert % 16 - 10))));
intToConvert /= 16;
}
convertedHexa.append(intToConvert % 16 < 10 ? ((char)(48 + (intToConvert % 16))) : ((char)(65 + (intToConvert % 16 - 10))));
java.lang.System.out.println(convertedHexa.reverse());
}
}

Related

Is there a faster way to convert a hexadecimal fractional part to a decimal one?

I wrote a program that generates digits of pi in hexadecimal. Every so often, at benchmark values, I would like to convert the hexadecimal value I have into a decimal one and save it to a file. Currently I am using BigDecimal to do that math with this code:
private static String toDecimal(String hex) {
String rawHex = hex.replace(".", "");
BigDecimal base = new BigDecimal(new BigInteger(rawHex, 16));
BigDecimal factor = new BigDecimal(BigInteger.valueOf(16).pow(rawHex.length() - 1));
BigDecimal value = base.divide(factor);
return value.toPlainString().substring(0, hex.length());
}
Note that this method will only work for hexadecimal values with one digit in the integral part, pi included, do not copy and paste this for general use.
So this code works fine, but for the latest benchmark, 2.5m digits, the conversion took 11.3 hours to complete.
Is there any faster way to do this manually?
I tried dividing the first decimal place by 16, the second by 16^2, etc but this would quickly get out of hand. Maybe some way of bitshifting the digits back to keep the divisor low? But potentially the n+1, n+2, n+3, etc digits need to be processed to get the correct value for n.
First, I believe your function toDecimal is wrong as it doesn't correctly convert input ".1a" (it's off by a factor of 16), for example, and throws an exception for input ".800". The third line should be:
BigDecimal factor = new BigDecimal(BigInteger.valueOf(16).pow(rawHex.length()));
The exception arises from:
return value.toPlainString().substring(0, hex.length());
The converted value could be shorter than the input value and you get a java.lang.StringIndexOutOfBoundsException.
Moving on:
In truth I have not benchmarked this against your current method; I just offer this as "food for thought." Here I am doing the multiplications as a child is taught to do it in school and in your case we have a large loop just to produce one digit. But if you could somehow adapt this to use BigDecimal (it's not clear how you would) it might be quicker than your current approach (what's really needed is a BigHexadecimal class).
It can be observed that converting a fraction from one base to another can be done using multiplications. In this case we have the following hexadecimal fraction (we can ignore the integer portion, which is 3 when converting pi):
.h1h2h3h4 ... hn
where hn is the nth hexadecimal "nibble".
We wish to convert the above to the following decimal fraction:
.d1d2d3d4 ... dn
where dn is the nth decimal digit.
If we were to multiply both quantities by 10, we would get:
h'1.h'2h'3h'4 ... h'n
The primes (`) denote that we have completely new hexadecimal nibble values following the multiplication.
and
d1.d2d3d4 ... dn
The multiplication by 10 just shifts the decimal fraction one place to the left.
We must note that the quantities to the left of the decimal point must be equal, i.e. d1 == h'1. Thus we repeatedly multiply our hexadecimal fraction by 10 and each time we do we take the integer portion as the next decimal digit for our conversion. We repeat this until either our new hexadecimal fraction becomes 0 or some arbitrary number of decimal digits have been produced:
See Java Demo
class Test {
private static String toDecimal(String hex, int numberDigits) {
/* converts a string such as "13.1a" in base 16 to "19.1015625" in base 10 */
int index = hex.indexOf('.');
assert index != -1;
StringBuilder decimal = new StringBuilder((index == 0) ? "" : String.valueOf(Integer.parseInt(hex.substring(0, index), 16)));
decimal.append('.');
int l = hex.length() - index - 1;
assert l >= 1;
int firstIndex = index + 1;
int hexDigits[] = new int[l];
for (int i = 0; i < l; i++) {
hexDigits[i] = Integer.parseInt(hex.substring(i + firstIndex, i + firstIndex + 1), 16);
}
while (numberDigits != 0 && l != 0) {
int carry = 0;
boolean allZeroes = true;
for (int i = l - 1; i >= 0; i--) {
int value = hexDigits[i] * 10 + carry;
if (value == 0 && allZeroes) {
l = i;
}
else {
allZeroes = false;
carry = (int)(value / 16);
hexDigits[i] = value % 16;
}
}
numberDigits--;
if (carry != 0 || (numberDigits != 0 && l != 0))
decimal.append("0123456789".charAt(carry));
}
return decimal.toString();
}
public static void main(String[] args) {
System.out.println(toDecimal("13.1a", 15));
System.out.println(toDecimal("13.8", 15));
System.out.println(toDecimal("13.1234", 15));
}
}
Prints:
19.1015625
19.5
19.07110595703125
Thank you to #Booboo for the solution to this problem. I improved on his code a little so it should work in every case. I wanted to post it here for future visitors.
/**
* Converts a hex number string to a decimal number string.
*
* #param hex The hex number string.
* #param accuracy The number of decimal places to return in the decimal number string.
* #return The decimal number string.
*/
public static String hexToDecimal(String hex, int accuracy) {
if (!hex.matches("[0-9A-Fa-f.\\-]+") || (accuracy < 0)) {
return "";
}
boolean negative = hex.startsWith("-");
hex = hex.replaceAll("^-", "");
String integral = hex.contains(".") ? hex.substring(0, hex.indexOf(".")) : hex;
String fraction = hex.contains(".") ? hex.substring(hex.indexOf(".") + 1) : "";
if (integral.contains("-") || fraction.contains(".") || fraction.contains("-")) {
return "";
}
StringBuilder decimal = new StringBuilder();
decimal.append(negative ? "-" : "");
decimal.append(integral.isEmpty() ? "0" : new BigDecimal(new BigInteger(integral, 16)).toPlainString());
if (fraction.isEmpty() || (accuracy == 0)) {
return decimal.toString();
}
decimal.append(".");
int numberDigits = accuracy;
int length = Math.min(fraction.length(), numberDigits);
int[] hexDigits = new int[numberDigits];
Arrays.fill(hexDigits, 0);
IntStream.range(0, length).boxed().parallel().forEach(i -> hexDigits[i] = Integer.parseInt(String.valueOf(fraction.charAt(i)), 16));
while ((numberDigits != 0)) {
int carry = 0;
for (int i = length - 1; i >= 0; i--) {
int value = hexDigits[i] * 10 + carry;
carry = value / 16;
hexDigits[i] = value % 16;
}
decimal.append(carry);
numberDigits--;
}
return decimal.toString();
}
/**
* Converts a hex number string to a decimal number string.
*
* #param hex The hex number string.
* #return The decimal number string.
* #see #hexToDecimal(String, int)
*/
public static String hexToDecimal(String hex) {
String fraction = hex.contains(".") ? hex.substring(hex.indexOf(".") + 1) : "";
return hexToDecimal(hex, fraction.length());
}
public static void main(String[] args) {
//integer
Assert.assertEquals("0", hexToDecimal("0"));
Assert.assertEquals("1", hexToDecimal("1"));
Assert.assertEquals("9", hexToDecimal("9"));
Assert.assertEquals("15", hexToDecimal("F"));
Assert.assertEquals("242", hexToDecimal("F2"));
Assert.assertEquals("33190", hexToDecimal("81A6"));
Assert.assertEquals("256", hexToDecimal("100"));
Assert.assertEquals("1048576", hexToDecimal("100000"));
Assert.assertEquals("5191557193152165532727847676938654", hexToDecimal("FFF6AA0322BC458D5D11A632099E"));
Assert.assertEquals("282886881332428154466487121231991859970997056152877088222", hexToDecimal("B897A12C89896321C454A7DD9E150233CBB87A9F0233DDE"));
Assert.assertEquals("-256", hexToDecimal("-100"));
Assert.assertEquals("-144147542", hexToDecimal("-8978456"));
Assert.assertEquals("-332651442596728389665499138728075237402", hexToDecimal("-FA42566214321CC67445D58EE874981A"));
Assert.assertEquals("33190", hexToDecimal("81a6"));
//decimal
Assert.assertEquals("0.10", hexToDecimal("0.1a"));
Assert.assertEquals("0.5", hexToDecimal("0.8"));
Assert.assertEquals("0.0711", hexToDecimal("0.1234"));
Assert.assertEquals("0.528966901", hexToDecimal("0.876A5FF4A"));
Assert.assertEquals("-0.528966901", hexToDecimal("-0.876A5FF4A"));
Assert.assertEquals("-0.00000000", hexToDecimal("-0.00000001"));
Assert.assertEquals("-0.62067648792835838863907521427468", hexToDecimal("-0.9EE4A7810C666FF7453D06A44621030E"));
Assert.assertEquals("0.528966901", hexToDecimal("0.876a5ff4a"));
Assert.assertEquals("0.528966901", hexToDecimal(".876a5ff4a"));
Assert.assertEquals("-0.528966901", hexToDecimal("-.876a5ff4a"));
//combined
Assert.assertEquals("15.33693", hexToDecimal("F.56412"));
Assert.assertEquals("17220744.33934412", hexToDecimal("106C488.56DF41A2"));
Assert.assertEquals("282886881332428154466487121231991859970997056152877088222.62067648792835838863907521427468", hexToDecimal("B897A12C89896321C454A7DD9E150233CBB87A9F0233DDE.9EE4A7810C666FF7453D06A44621030E"));
Assert.assertEquals("-17220744.33934412", hexToDecimal("-106C488.56DF41A2"));
Assert.assertEquals("-282886881332428154466487121231991859970997056152877088222.62067648792835838863907521427468", hexToDecimal("-B897A12C89896321C454A7DD9E150233CBB87A9F0233DDE.9EE4A7810C666FF7453D06A44621030E"));
Assert.assertEquals("-17220744.33934412", hexToDecimal("-106c488.56df41a2"));
Assert.assertEquals("3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808", hexToDecimal("3.243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89452821E638D01377BE5466CF34E90C6CC0AC29B7C97"));
//accuracy
Assert.assertEquals("-0.00000", hexToDecimal("-0.00000001", 5));
Assert.assertEquals("-0.000000000232830", hexToDecimal("-0.00000001", 15));
Assert.assertEquals("-0", hexToDecimal("-0.00000001", 0));
Assert.assertEquals("282886881332428154466487121231991859970997056152877088222.5", hexToDecimal("B897A12C89896321C454A7DD9E150233CBB87A9F0233DDE.9EE4A7810C666FF7453D06A44621030E", 1));
Assert.assertEquals("3.14", hexToDecimal("3.243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89452821E638D01377BE5466CF34E90C6CC0AC29B7C97", 2));
Assert.assertEquals("3.1415926535", hexToDecimal("3.243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89452821E638D01377BE5466CF34E90C6CC0AC29B7C97", 10));
Assert.assertEquals("3.1415926535897932384626433", hexToDecimal("3.243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89452821E638D01377BE5466CF34E90C6CC0AC29B7C97", 25));
//invalid
Assert.assertEquals("", hexToDecimal("0.00000.001"));
Assert.assertEquals("", hexToDecimal("0.00000-001"));
Assert.assertEquals("", hexToDecimal("156-081.00000001"));
Assert.assertEquals("", hexToDecimal("hello"));
Assert.assertEquals("", hexToDecimal("9g"));
Assert.assertEquals("", hexToDecimal("9G"));
Assert.assertEquals("", hexToDecimal("546.FDA", -1));
Assert.assertEquals("", hexToDecimal("546.FDA", -999));
}

charAt() and Math.pow()

Background:
I am making a simple base converter for a class assignment. I am fairly close to completion but need to tidy up the conversion algorithm to convert the user inputted value (in a given base) to a base 10 value.
Attempt:
import java.util.Scanner;
public class BaseConverter {
public static void main(String[] args) {
String numIn, intro1, prompt1, prompt2, output1;
int baseIn;
double numOut;
boolean flag = true;
Scanner kb = new Scanner(System.in);
intro1 = "This program converts values in different number bases to a decimal value.";
prompt1 = "Type in a number base (2 - 9): ";
while (flag == true){
System.out.println(intro1);
System.out.println(prompt1);
baseIn = kb.nextInt();
//Checking base value for outliers outside given range
if (baseIn < 2 || baseIn > 9) {
System.out.println("Base must be between 2 and 9");
System.exit(1);
}
prompt2 = "Type in a base "+baseIn+" number: ";
System.out.println(prompt2);
numIn = kb.next();
// System.out.println(numStore);
int counter = 0;
// Let's pretend baseIn is 3 and i starts at 3
for (int i = numIn.length(); i >= 1; i--){
numOut = (numIn.charAt(i-1) * Math.pow(baseIn, counter++));
System.out.println(numOut);
}
}//while
}// method
}//class
The problem:
This line does not return the expected value
numOut = (numIn.charAt(i-1) * Math.pow(baseIn, counter++));
For example, in string "10", numOut should be (0*(2*0)) or zero on the first iteration of the for loop. Instead, it returns 48.0.
My Thoughts:
I have a sneaking suspicion it has to do with the charAt() method as debugging the Math.pow() method showed it returning expected values. Suppose it's something to do with all the different variable types? I'm unsure.
Yes you're right charAt is the problem.
When you type let's say "10", the integer value of the character '0' is 48 and for '1' it's 49 according to the encoding table Java uses to encode characters.
If you take a look at it, you see that 0 is encoded as 0x0030 = 3*16^1 = 48, 1 as 0x0031 = 3*16^1 + 1*16^0 = 49 and so on.
If you want to get the numeric value of the character itself you can use
numOut = Character.getNumericValue(numIn.charAt(i-1)) * Math.pow(baseIn, counter++);
The charAt method returns the char of your input, in this case '0', not 0. The Unicode value for the char '0' is not 0, it's 48.
Fortunately, the values '0' through '9' are consecutive Unicode values, 48 through 57 respectively, so you can "subtract" out the 48 by subtracting '0' before multiplying.
numOut = ( (numIn.charAt(i-1) - '0') * Math.pow(baseIn, counter++));
You'll still need to validate that what the user typed is in fact a valid "digit" in the chosen base.
You'll also want to add the values of numOut together to get the decimal result at the end.

How to rotate a single character based on a specific range of ascii characters in Java?

I am trying to come up with a function that accepts a character and a number. The number is the number of times the character should be "rotated". The accepted ASCII codes are 32 to 126.
Example of rotate = If a character "A" was rotated twice, it would end up as the character "C". If "A" was rotated three times, it would end up as the letter "D". If you look at the ASCII table:
http://www.jimprice.com/ascii-0-127.gif
Given my limit of the ASCII value being 32 to 126... ascii value 065 rotated would be ascii value 067. ascii value 124 rotated 5 times would be ascii value 34.
For example:
if I passed the function "!" (ASCII code 33) and the number 2, the
output character should be "#" (ASCII code 35).
if I passed "}"
(ASCII code 125) and the number 3, I should get the output character
"!" (ASCII code 33).
What is the best way to accomplish this in java (can it support negative numbers for the distance to rotate instead of just positive if you want to rotate the other way around)?
Try something like:
static char rotate(char c, int distance) {
assert 32 <= c && c < 127;
if (distance < 0) distance = distance % (127 - 32) + 127 - 32;
return (char) ((c + distance - 32) % (127 - 32) + 32);
}
Edit: Added the if (distance... line to support negative distances.
Do like this
public static char numToChar(int num,int rotate){
int result = num+rotate;
if(result>126){
result =31+(result-126);
}
return (char)result;
}
System.out.println(numToChar(33,2));
System.out.println(numToChar(125,3));
Output
#
!
You could use this approach
public static char rotateChar(char in, int shift) {
/* cast char to int */
int v = (int) in;
/* to cover wrap-around */
v += (shift % 95);
/* 32 - 126 = -95 */
return (char) ((v > 126) ? v - 95 : v);
}
public static void main(String[] args) {
System.out.printf("! + 2 = %s\n",
String.valueOf(rotateChar('!', 2)));
System.out.printf("} + 3 = %s\n",
String.valueOf(rotateChar('}', 3)));
System.out.printf("b - 1 = %s\n",
String.valueOf(rotateChar('b', -1)));
}
! + 2 = #
} + 3 = !
b - 1 = a
Try This.
public static void main(String[] args) {
String ascii;
String rotate;
Scanner in = new Scanner(System.in);
System.out.println("Enter ASCII Character");
ascii = in.nextLine();
System.out.println("Enter Rotate value");
rotate = in.nextLine();
int output=(Integer.parseInt(ascii)+Integer.parseInt(rotate))% 126;
if(output<32) output=output+32;
System.out.println("output="+output);
System.out.println(Character.toString ((char) output));
}

Java - Change int to ascii

Is there a way for java to convert int's to ascii symbols?
Do you want to convert ints to chars?:
int yourInt = 33;
char ch = (char) yourInt;
System.out.println(yourInt);
System.out.println(ch);
// Output:
// 33
// !
Or do you want to convert ints to Strings?
int yourInt = 33;
String str = String.valueOf(yourInt);
Or what is it that you mean?
If you first convert the int to a char, you will have your ascii code.
For example:
int iAsciiValue = 9; // Currently just the number 9, but we want Tab character
// Put the tab character into a string
String strAsciiTab = Character.toString((char) iAsciiValue);
There are many ways to convert an int to ASCII (depending on your needs) but here is a way to convert each integer byte to an ASCII character:
private static String toASCII(int value) {
int length = 4;
StringBuilder builder = new StringBuilder(length);
for (int i = length - 1; i >= 0; i--) {
builder.append((char) ((value >> (8 * i)) & 0xFF));
}
return builder.toString();
}
For example, the ASCII text for "TEST" can be represented as the byte array:
byte[] test = new byte[] { (byte) 0x54, (byte) 0x45, (byte) 0x53, (byte) 0x54 };
Then you could do the following:
int value = ByteBuffer.wrap(test).getInt(); // 1413829460
System.out.println(toASCII(value)); // outputs "TEST"
...so this essentially converts the 4 bytes in a 32-bit integer to 4 separate ASCII characters (one character per byte).
You can convert a number to ASCII in java. example converting a number 1 (base is 10) to ASCII.
char k = Character.forDigit(1, 10);
System.out.println("Character: " + k);
System.out.println("Character: " + ((int) k));
Output:
Character: 1
Character: 49
In fact in the last answer
String strAsciiTab = Character.toString((char) iAsciiValue);
the essential part is (char)iAsciiValue which is doing the job (Character.toString useless)
Meaning the first answer was correct actually
char ch = (char) yourInt;
if in yourint=49 (or 0x31), ch will be '1'
In Java, you really want to use Integer.toString to convert an integer to its corresponding String value. If you are dealing with just the digits 0-9, then you could use something like this:
private static final char[] DIGITS =
{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
private static char getDigit(int digitValue) {
assertInRange(digitValue, 0, 9);
return DIGITS[digitValue];
}
Or, equivalently:
private static int ASCII_ZERO = 0x30;
private static char getDigit(int digitValue) {
assertInRange(digitValue, 0, 9);
return ((char) (digitValue + ASCII_ZERO));
}
The most simple way is using type casting:
public char toChar(int c) {
return (char)c;
}
tl;dr
Use Character#toString, not char.
String result = Character.toString( yourAsciiNumber ) ;
Ex:
Character.toString( 97 ) // LATIN SMALL LETTER A
a
Character.toString( 128_567 ) // FACE WITH MEDICAL MASK
😷
char is legacy
The char type in Java is legacy, and is essentially broken. As a 16-bit value, char is incapable of representing most characters defined by Unicode.
This succeeds:
System.out.println( Character.toString( 128_567 )); // Unicode code points handle full-range of Unicode characters.
😷
This fails:
System.out.println( ( char ) 128_567 ); // `char` fails with most Unicode characters.
See code run live at IdeOne.com.
Code point
Use code point integer numbers to represent individual letters.
US-ASCII is a subset of Unicode. So, any US-ASCII number (0-127) is also a Unicode code point (0-1,114,111).
To change a code point number to a String object containing a single character, call Character#toString.
String x = Character.toString( 97 ) ;
a
See this code run live at IdeOne.com.
The most simple way is to get integer and just use the casting operator
Ex
int num = 33;
System.out.println((char) num); //Outputs 33
//if you want to find the integer value of character instead.
//Just do the reverse
char ch = '%';
System.out.println((int) ch);

(Java) Specify number of bits (length) when converting binary number to string?

I'm trying to store a number as a binary string in an array but I need to specify how many bits to store it as.
For example, if I need to store 0 with two bits I need a string "00". Or 1010 with 6 bits so "001010".
Can anyone help?
EDIT: Thanks guys, as I'm rubbish at maths/programming in general I've gone with the simplest solution which was David's. Something like:
binaryString.append(Integer.toBinaryString(binaryNumber));
for(int n=binaryString.length(); n<numberOfBits; n++) {
binaryString.insert(0, "0");
}
It seems to work fine, so unless it's very inefficient I'll go with it.
Use Integer.toBinaryString() then check the string length and prepend it with as many zeros as you need to make your desired length.
Forget about home-made solutions. Use standard BigInteger instead. You can specify number of bits and then use toString(int radix) method to recover what you need (I assume you need radix=2).
EDIT: I would leave bit control to BigInteger. The object will internally resize its bit buffer to fit the new number dimension. Moreover arithmetic operations can be carried out by means of this object (you do not have to implement binary adders/multipliers etc.). Here is a basic example:
package test;
import java.math.BigInteger;
public class TestBigInteger
{
public static void main(String[] args)
{
String value = "1010";
BigInteger bi = new BigInteger(value,2);
// Arithmetic operations
System.out.println("Output: " + bi.toString(2));
bi = bi.add(bi); // 10 + 10
System.out.println("Output: " + bi.toString(2));
bi = bi.multiply(bi); // 20 * 20
System.out.println("Output: " + bi.toString(2));
/*
* Padded to the next event number of bits
*/
System.out.println("Padded Output: " + pad(bi.toString(2), bi.bitLength() + bi.bitLength() % 2));
}
static String pad(String s, int numDigits)
{
StringBuffer sb = new StringBuffer(s);
int numZeros = numDigits - s.length();
while(numZeros-- > 0) {
sb.insert(0, "0");
}
return sb.toString();
}
}
This is a common homework problem. There's a cool loop that you can write that will compute the smallest power of 2 >= your target number n.
Since it's a power of 2, the base 2 logarithm is the number of bits. But the Java math library only offers natural logarithm.
math.log( n ) / math.log(2.0)
is the number of bits.
Even simpler:
String binAddr = Integer.toBinaryString(Integer.parseInt(hexAddr, 16));
String.format("%032", new BigInteger(binAddr));
The idea here is to parse the string back in as a decimal number temporarily (one that just so happens to consist of all 1's and 0's) and then use String.format().
Note that you basically have to use BigInteger, because binary strings quickly overflow Integer and Long resulting in NumberFormatExceptions if you try to use Integer.fromString() or Long.fromString().
Try this:
String binaryString = String.format("%"+Integer.toString(size)+"s",Integer.toBinaryString(19)).replace(" ","0");
where size can be any number the user wants
Here's a simple solution for int values; it should be obvious how to extend it to e.g. byte, etc.
public static String bitString(int i, int len) {
len = Math.min(32, Math.max(len, 1));
char[] cs = new char[len];
for (int j = len - 1, b = 1; 0 <= j; --j, b <<= 1) {
cs[j] = ((i & b) == 0) ? '0' : '1';
}
return new String(cs);
}
Here is the output from a set of sample test cases:
0 1 0 0
0 -1 0 0
0 40 00000000000000000000000000000000 00000000000000000000000000000000
13 1 1 1
13 2 01 01
13 3 101 101
13 4 1101 1101
13 5 01101 01101
-13 1 1 1
-13 2 11 11
-13 3 011 011
-13 4 0011 0011
-13 5 10011 10011
-13 -1 1 1
-13 40 11111111111111111111111111110011 11111111111111111111111111110011
Of course, you're on your own to make the length parameter adequate to represent the entire value.
import java.util.BitSet;
public class StringifyByte {
public static void main(String[] args) {
byte myByte = (byte) 0x00;
int length = 2;
System.out.println("myByte: 0x" + String.valueOf(myByte));
System.out.println("bitString: " + stringifyByte(myByte, length));
myByte = (byte) 0x0a;
length = 6;
System.out.println("myByte: 0x" + String.valueOf(myByte));
System.out.println("bitString: " + stringifyByte(myByte, length));
}
public static String stringifyByte(byte b, int len) {
StringBuffer bitStr = new StringBuffer(len);
BitSet bits = new BitSet(len);
for (int i = 0; i < len; i++)
{
bits.set (i, (b & 1) == 1);
if (bits.get(i)) bitStr.append("1"); else bitStr.append("0");
b >>= 1;
}
return reverseIt(bitStr.toString());
}
public static String reverseIt(String source) {
int i, len = source.length();
StringBuffer dest = new StringBuffer(len);
for (i = (len - 1); i >= 0; i--)
dest.append(source.charAt(i));
return dest.toString();
}
}
Output:
myByte: 0x0
bitString: 00
myByte: 0x10
bitString: 001010
So here instead of 8 you can write your desired length and it will append zeros accordingly. If the length of your mentioned integer exceeds that of the number mentioned then it will not append any zeros
String.format("%08d",1111);
Output:00001111
String.format("%02d",1111);
output:1111

Categories

Resources