char to int conversion - java

So I have something like this:
char cr = "9783815820865".charAt(0);
System.out.println(cr); //prints out 9
If I do this:
int cr = "9783815820865".charAt(0);
System.out.println(cr); //prints out 57
I understand that the conversion between char and int is not simply from '9' to 9. My problem is right now I simply need to keep the 9 as the int value, not 57. How to get the value 9 instead of 57 as a int type?

You can try with:
int cr = "9783815820865".charAt(0) - '0';
charAt(0) will return '9' (as a char), which is a numeric type. From this value we'll just subtract the value of '0', which is again numeric and is exactly nine entries behind the entry of the '9' character in the ASCII table.
So, behind the scenes, the the subtraction will work with the ASCII codes of '9' and '0', which means that 57 - 48 will be calculated.

try this:
char c = "9783815820865".charAt(0);
int cr = Integer.parseInt(c+"");

Using Character#getNumericValue may be more idiomatic. Bear in mind that it'll convert anything above 'A' as 10.
int cr = Character.getNumericValue("9783815820865".charAt(0));
System.out.println(cr);

Related

Java syntax int from char magic [duplicate]

This question already has answers here:
Java: Subtract '0' from char to get an int... why does this work?
(10 answers)
How does subtracting the character '0' from a char change it into an int?
(4 answers)
Closed 8 years ago.
I’m learning Java through "introduction to Java programming 9th edition" by Daniel Liang at chapter 9 "strings" I’ve encountered this piece of code :
public static int hexCharToDecimal(char ch) {
if (ch >= 'A' && ch <= 'F')
return 10 + ch - 'A';
else
return ch - '0';
}
Can someone explain what just happened in here? How is possible to add/subtract chars from integers and what's the meaning behind it?
From the Docs
The char data type is a single 16-bit Unicode character.
A char is represented by its code point value:
min '\u0000' (or 0)
max: '\uffff' (or 65,535)
You can see all of the English alphabetic code points on an ASCII table.
Note that 0 == \u0000 and 65,535 == \uffff, as well as everything in between. They are corresponding values.
A char is actually just stored as a number (its code point value). We have syntax to represent characters like char c = 'A';, but it's equivalent to char c = 65; and 'A' == 65 is true.
So in your code, the chars are being represented by their decimal values to do arithmetic (whole numbers from 0 to 65,535).
For example, the char 'A' is represented by its code point 65 (decimal value in ASCII table):
System.out.print('A'); // prints A
System.out.print((int)('A')); // prints 65 because you casted it to an int
As a note, a short is a 16-bit signed integer, so even though a char is also 16-bits, the maximum integer value of a char (65,535) exceeds the maximum integer value of a short (32,767). Therefore, a cast to (short) from a char cannot always work. And the minimum integer value of a char is 0, whereas the minimum integer value of a short is -32,768.
For your code, let's say that the char was 'D'. Note that 'D' == 68 since its code point is 68.
return 10 + ch - 'A';
This returns 10 + 68 - 65, so it will return 13.
Now let's say the char was 'Q' == 81.
if (ch >= 'A' && ch <= 'F')
This is false since 'Q' > 'F' (81 > 70), so it would go into the else block and execute:
return ch - '0';
This returns 81 - 48 so it will return 33.
Your function returns an int type, but if it were to instead return a char or have the int casted to a char afterward, then the value 33 returned would represent the '!' character, since 33 is its code point value. Look up the character in ASCII table or Unicode table to verify that '!' == 33 (compare decimal values).
This is because char is a primitive type which can be used as a numerical value. Every character in a string is encoded as a specific number (not entirely true in all cases, but good enough for a basic understanding of the matter) and Java allows you to use chars in such a way.
It probably allows this mostly for historical reasons, this is how it worked in C and they probably motivated it with "performance" or something like that.
If you think it's weird then don't worry, I think so too
The other answer is incorrect actually. ASCII is a specific encoding (an encoding is some specification that says "1 = A, 2 = B, ... , 255 = Space") and that is not the one used in Java. A Java char is two bytes wide and is interpreted through the unicode character encoding.
Chars are in turn stored as integers(ASCII value) so that you can perform add and sub on integers which will return ASCII value of a char
Regardless of how Java actually stores the char datatype, what's certain is this, the character 'A' subtracted from the character 'A' would be represented as the null character, \0. In memory, this means every bit is 0. The size in memory a char takes up in memory may vary from language to language, but as far as I know, the null character is the same in all the languages, every bit is equal to 0.
As an int value, a piece of memory with every bit equal to 0 represents the integer value of 0.
And as it turns out, when you do "character math", subtracting any alphabetical character from any other alphabetical character (of the same case) results in bits being flipped in such a way that, if you were to interpret them as an int, would represent the distance between these characters. Additionally, subtracting the char '0' from any other numeric char will result in int value of the char you subtracted from, for basically the same reason.
'A' - 'A' = '\0'
'a' - 'a' = '\0'
'0' - '0' = '\0'

Output of System.out.println( m[1]+` ´+m[ 2]) [duplicate]

To my understanding a char is a single character, that is a letter, a digit, a punctuation mark, a tab, a space or something similar. And therefore when I do:
char c = '1';
System.out.println(c);
The output 1 was exactly what I expected. So why is it that when I do this:
int a = 1;
char c = '1';
int ans = a + c;
System.out.println(ans);
I end up with the output 50?
You're getting that because it's adding the ASCII value of the char. You must convert it to an int first.
Number 1 is ASCII code 49. The compiler is doing the only sensible thing it can do with your request, and typecasting to int.
You end up with out of 50 because you have told Java to treat the result of the addition as an int in the following line:
int ans = a + c;
Instead of int you declare ans as a char.
Like so:
final int a = 1;
final char c = '1';
final char ans = (char) (a + c);
System.out.println(ans);
Because you are adding the value of c (1) to the unicode value of 'a', which is 49. The first 128 unicode point values are identical to ASCII, you can find those here:
http://www.asciitable.com/
Notice Chr '1' is Dec 49. The rest of the unicode points are here:
http://www.utf8-chartable.de/
A char is a disguised int. A char represents a character by coding it into an int. So for example 'c' is coded with 49. When you add them together, you get an int which is the sum of the code of the char and the value of the int.
'1' is a digit, not a number, and is encoded in ASCII to be of value 49.
Chars in Java can be promoted to int, so if you ask to add an int like 1 to a char like '1', alias 49, the more narrow type char is promoted to int, getting 49, + 1 => 50.
Note that every non-digit char can be added the same way:
'a' + 0 = 97
'A' + 0 = 65
' ' + 0 = 32
'char' is really just a two-byte unsigned integer.
The value '1' and 1 are very different. '1' is encoded as the two-byte value 49.
"Character encoding" is the topic you want to research. Or from the Java language spec: http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.2.1

The most efficient way to decipher some text

I am developing a small application where I am given some string "MRUGDQ" and a shift value 3 for example. Then I shift each letter to left by 3 and the result would be "JORDAN". For instance M would be replaced by J and R would be replaced by O and so on.
So now this is the approach I was thinking of using, but I was wondering if this is efficient and can I improve my solution?
Assumptions I make:
I am assuming my string will be either capital A to Z letter or small a to z letter and therefore the ascii range is from 65 to 90 and 97 to 122 respectively.
Pesudo Code
get ascii value of char
(assume char happens to be between the capital letter range)
add the shift value to the char ascii value
if new ascii value <= 90
replace old letter by new letter
else
int diff = new ascii value - 90
while (new ascii value <= 90) {
decrement diff value by 1
increment new ascii value by 1
}
add remaining diff to 65 and set that as new ascii value
replace old letter by new letter
Do that for each letter in the string.
Please let me know if my approach is correct or if I can be more efficient.
I don't see much to improve, except your handling of the new char is out of range.
If you like to "roll" the overlapping amount back to the beginning of your range, than just calculate: (x % 90) + 64(*) (with x being the ascii value after adding the shift value).
Example:
'Y' (89) + 3 = '\' 92
92 % 90 = 2
2 + 64 = 'B' (66)
You need to start from 64, to avoid skipping over 'A', which has the value 65.
(*) The general formula is: (value % upper bound) + (lower bound - 1).
You could also use (value % upper bound + 1) + lower bound.

What is the value of a Char in java?

Let's say I have a String. If I do this:
for (int index = 0; index < ch.length(); index++) {
char c = ch.charAt(index);
System.out.println(String.format("%04x", (int) c));
}
What will the output be ?
I tried a and got 0061, which seems to be the UTF-8/ASCII value of A.
Then I tried 𐅑 and got d800 dd51 which seems not to be a UTF value.
Just wondering, what is the int value of a Char in Java.
I believe your ch variable in your for loop is a String type and you want to access each character in that then cast it to it's ascii value? Well that's what your code does. I ran it after making minor corrections and using String ch = "abcdef" and it gave me the out put of:
0061
0062
0063
0064
0065
0066
Which is exactly what your print statement instructs:
-cast the character to its' ascii value
-output four character long value.
If it helps, the ascii value for a, b, c, d, e and f are 61, 62, 63, 64, 65 and 66.

Fast way converting a byte array to corresponding Integer

First, this sounds like the problem here:
How to convert a byte array to its numeric value (Java)?
But the origin of my Byte-Array is a String, something like this:
byte[] foo = new byte[8];
foo = "12345678".getBytes();
Is there a faster way (yes its really about doing this quick) than
Integer.parseInt(new String(foo))?
The String contains only digits which represent a Integer.
try this
int res = 0;
for(int i = foo.length -1, m = 1; i >=0; i--, m *= 10) {
res += (foo[i] & 0xF) * m;
}
You could try something like this:
byte foo[] = "12345678".getBytes();
//Since it is an 'integer' essentially, it will contain ASCII values of decimal digits.
long num = 0; //Store number here.
for(int i = foo.length - 1; i >= 0; i--)
{
num = num * 10 + (foo[i] - '0'); // or (foo[i] - 48) or (foo[i] & 0xf)
}
num stores the required number.
Precaution: Make sure you use decimal number only.
EDIT:
The Mechanism
On calling getBytes() of the String "12345678", the byte[] returned is as follows:
The values we see are the ASCII or Unicode values for the eqivalent characters.
There are several ways to extract their equivalent character as ints:
Since the arrangement of the digit chars, i.e. '0', '1', '2', etc. are done in the desired order - ascending and sequentially, we can extract the characters by subtrcting the ASCII value of '0' i.e. 48.
#Evgeniy Dorofeev correctly pointed out the method of masking:
'0' => 48 => 11 0000
We notice that if we extract the last 4 bits, we get the required int.
To do this, we need to extract them in the following way.
Let us take foo[1], i.e. 50
50 & 0xf (original)
= 50 & 15 (in Decimal)
= 11 0010 & 1111 (in Binary)
= 0010 (result)
= 2 (Decimal)
Hence, the required digit is obtained. It in necessary to add it to num int the correct way (which I expect of every programmer to have some knowledge about).

Categories

Resources