How is an Integer converted to ASCII in Java Behind the Scenes? - java

I'm not asking for a built-in class that accomplishes this, I'm just curious on how encoding works behind the scenes in java. For example, An integer in java can be stored in 4 bytes, between -2147483648 and 2147483647. Lets use 500 as the number for this demonstration. From what I understand, the computer initially stores this number in memory as 1F4 in hex, which is 00000000 00000000 00000001 11110100 in binary. When I looked up how ASCII works, it encodes each digit 0-9 to its corresponding ASCII value (0 translates to 048). However, how is the binary number stored in ram able to separate each digit so that each digit can be encoded to its corresponding ASCII value? We know that the number is 500, but this is just an abstraction. The computer just sees 1's and 0's. So how is the 5 mapped to 053, and both 0's mapped to 048 for this example. Does the jvm account for this automatically behind the scenes? Or am I misunderstanding how the entire process works. Thanks.

Well, IF I understand your question directly...
You could start by dividing your integer by 10 and getting the remainder -- the mod function in Java (%) is useful for this.
int digitInteger = originalNumber % 10;
The digitInteger variable now holds a number 0-9, the integer version of the ASCII (or Unicode, or whatever) of the last digit in the number. Unfortunately for your example, this will be a fairly boring 0.
Let us instead use the number 543 as our example, it will make things easier. If originalNumber was 543, then digitInteger will now be 3. Since 48 represents ASCII 0, then you can add that to digitInteger to get the ASCII equivalent. I'll leave it to you put that somewhere, since Java does not deal with ASCII as its default encoding. (Unicode, I believe, has the same values as ASCII for these digits).
Now you execute something like
originalNumber = originalNumber / 10;
This integer division will truncate the digit you just isolated, 3 in our case, and originalNumber is now 54.
You repeat this process - mod by 10 to isolate the last digit, convert to character, prepend to characters previously found, integer divide by 10 to truncate the last digit -- until originalNumber is 0 -- digitInteger, as you can probably see now, will be 4 on the next round and 5 on the round after that, and you prepend those to the 3 you got the first time to get your ASCII equivalent.

Related

Java - charAt getting wrong character

I am trying to make an algorithm that will do the following:
64
797
7
===
79
that will take 7, multiply it by 7, and then write the last digit of the answer down and then multiply it by seven and add the first digit of 7 times 7, and so on - so if you do it three times (write it down), you get what I wrote up there as a multiplication.
I got a not good code, instead of showing (for example) whats above in this form:
7,9,4
9,7,6
and so on I get something like this:
7, 9, 52
9, 55, 54
My code:
for(int i = 0; i<3; i++){//Run the code three times
temp=upper*7%10+tens;//get the temp but keeping the upper because I am going to need it for the tens part
tens=(upper*7+"").charAt(0);//get the first character of upper*7
System.out.println(upper+", "+temp+", "+tens);
upper=temp;
}
As far as I can see the problem is in the charAt, because obviously the first character of 7*7 is not 52.
EDIT
Now that the code is working fine I have another problem. I tried my new working code (put tens as the int value of the string value of the char instead of just the char), I have another problem. Hooray!
Last tens: 0 Now's plain number:7, New:9, Tens:4
Last tens: 4 Now's plain number:9, New:7, Tens:6
Last tens: 6 Now's plain number:7, New:15, Tens:4
Last tens: 4 Now's plain number:15, New:9, Tens:1
Last tens: 1 Now's plain number:9, New:4, Tens:6
My code now is as the same as the old code just with the tens fixed. But now, I am getting 15 for a number. That is supposed to be a digit. Whats wrong? I honestly don't know if the code I wrote will fullfil my purpose. What code will?
I strongly suspect that the problem is the type of tens. You haven't shown this in your code, but I suspect it's int.
So this line:
tens = (upper*7+"").charAt(0);
takes the first character from a string, and then stores it in an int. So for example, the character '4' is Unicode 52 ('0') is 48. The conversion to int just converts the UTF-16 code unit from an unsigned 16-bit value to a signed 32-bit value.
You're then displaying the value of tens - but if tens is indeed an int, it's going to display that as a number.
As far as I can see the problem is in the charAt, because obviously the first character of 7*7 is not 52.
Well, the first character of the string representation of 7*7 will be '4'. When that's been converted to an int, you'll see that as 52.
If you just want tens as a char, you should declare it as type char. You shouldn't do arithmetic with that value of course - but then when you display it, you'll see 4 displayed, because the string conversion will still treat it just as a character instead of as a number.

Hamming Code: Number of parity bits

I'm trying to write a method in java that will take an input of any number of 0 or 1 digits and output that line after being encoded with Hamming Code.
I have managed to write the code when knowing the number of digits the input will have (in this case 16) because knowing the number of digits in the input, I immediately know the number of parity bits there have to be added (5 in this case) to a total of 21 digits in the final output. I am working with int arrays so I need to declare a size in the beginning and my code works based on those exact sizes.
Can you guys think of any way/algorithm that can give me the number of digits the output will have (after adding the relevant parity digits to the number of input digits) based solely on the number of input digits?
Or do I have to tackle this problem in a totally different way? Any suggestions? Thank you in advance!
Cheers!
From my understanding, you get your 6th parity bit at 32 bits of input, 7th at 64, etc. so what you need is floor(lg(n)) + 1, which in java you can get by using 32 - Integer.numberOfLeadingZeros(n).
Assuming your input is made up entirely of 0s and 1s, you would do
int parityDigits = 32 - Integer.numberOfLeadingZeros(input.length());
Is your input a String or individual bits? If you input as a String, you can convert each character to a bit, and the length of the String gives you the length of the array.
If you need to input the bits one at a time, store them in an ArrayList. When all bits have been entered, you can convert your list to an array easily, or use the size of the list etc.

Java algorithm to Compress small numeric number

I need to compress 20-40 char size of a numeric number to a 6 char size number. So far I have tried Huffman and some Zip algorithms but not getting the desired outcome.
Can some one please advise any other Algorithm/API for this work in Java?
Example:
Input: 98765432101234567890
Desired Output: 123456
Please note: I didn't mean the output has to come as 12345 for the given input. I only mean that if I specify 20 byte number, it should be compressed to a 6 byte number.
Usage: Compressed number will be feeded to a device (which can only take up-to-6 numeric chars). Device will decode the number back to the original number.
Assumption/Limits:
If required both client and device(server) can share some common
properties required for encoding/decoding the number.
Only one request can be made to a device i.e. all data should be fed
in one request, no chunk of small packets
Thanks.
This will be the best you can get assuming that any combination of digits is a legal input:
final String s = "98765432101234567890";
for (byte b : new BigInteger('0'+s).toByteArray())
System.out.format("%02x ", b & 0xff);
Prints
05 5a a5 4d 36 e2 0c 6a d2
Storing a number in binary form is theoretically the most efficient way since every combination of bits is a distinct legal value.
You may have other options only if there is more redundancy in your input, that is there are some constraints on the legal digit combinations.
The way you specify it, this is not possible. There simply are more 20 digit numbers than there are 6 digit numbers, so if you map 20 digits to only six digits, some 20 digit numbers will have to be mapped to the same six digit number. If you know that not all numbers will be valid or even have the same likelyhood, this can be used for compression, but otherwise this is impossible.
Although a reversible (bijective) mapping from 20 digit numbers to six digit numbers is impossible it is still possible to map long numbers to shorter output. This works by reducing the requirement that the output needs to be a number. The only important consideration is that the output sequence needs to have the same number of possibilities as the input. Here is an example:
There are 10^20 possible 20 digit numbers
If you use a sequence of full 8-bit ASCII (256 characters) of length x you will have 256^x possible outputs. If you solve this for x, you will notice that 256^9 > 10^20 so 9 ASCII characters are enough to encode 20^10 possible numerical inputs.
Marko's answer to the same question will tell you how to convert a number to it's byte representation which may be used as input. But be aware that this input will not be numerical and may contain many strange symbols.

Java: How to get high and low 16bit values from a 32bit HEX?

Need a solution on how to perform the following: receive a decimal value, convert it to 32-bit Hex, then separate that 32-bit hex and get high 16-bit and low 16-bit values. I have been digging around net and cannot find much info.
Not sure why you are converting to hex but to turn a 32-bit value straight into two 16-bit values.
int x = ...
short high = x >> 16;
short low = x & 0xFFFF;
I expect this is a homework problem. Accordingly, I will give you information that can help you solve it rather than a solution.
Convert the number to hexadecimal. This can be done with the Integer's toHexString() method.
Add enough zeroes to the left to make it eight characters long (8 hexadecimal characters represent 32 bits). You can do this by adding zeroes one by one in a loop until it's 8 characters long, or (better approach) just add 7 zeroes to the left and only deal with the rightmost 8 characters.
Take the the rightmost 4 characters as the lower 16 bits and the 4 characters immediately to the left of that as the higher 16 bits. This can be done with the String's substring() method along with length() and some simple subtraction.
Some APIs you might find useful:
http://download.oracle.com/javase/6/docs/api/java/io/DataInputStream.html
http://download.oracle.com/javase/6/docs/api/java/lang/Integer.html#parseInt(java.lang.String, int)
http://download.oracle.com/javase/6/docs/api/java/lang/Integer.html#toHexString(int)
http://commons.apache.org/codec/apidocs/org/apache/commons/codec/binary/Hex.html

Padding a number with zeroes

Lets say I have a number 345, I want to have so that I end up with 0345. I.e.
int i = 0345;
How can I take an existing number and shift it along or append a 0.
I know you are talking about an int, but maybe what you want is to pad a number with leading 0s. A quick way is with the String.format static method.
int num = 345;
String.format("%04d", num);
would return:
"0345"
The 4d tells it to add 0s to the left if it has less than 4 digits, so you can change it to a 5 and it would give you:
"00345"
Using a 0 on the start of the number when declaring it means it's octal, so 0345 is actually 229 in decimal. I'm not sure how you expect to add a zero to a number using bitwise operations, which work on the binary representation of the number. If you want to add it to the decimal representation, it won't mean anything, since the number is always stored in binary, and the value is converted for your convenience to decimal when being displayed. When doing any computations, the decimal value is not important, only the binary one.
If you're interested only in displaying the value with a 0 at the start, then you could append the 0 to a String containing that number which can be easily done like this "0" + i.

Categories