开发者

Java: Subtract '0' from char to get an int... why does this work?

This works fine:

int foo = bar.charAt(1) - '0';

Yet this doesn't - because bar.charAt(x) returns a char:

int fo开发者_JAVA百科o = bar.charAt(1);

It seems that subtracting '0' from the char is casting it to an integer.

Why, or how, does subtracting the string '0' (or is it a char?) convert another char in to an integer?


That's a clever trick. char's are actually of the same type / length as shorts. Now when you have a char that represents a ASCII/unicode digit (like '1'), and you subtract the smallest possible ASCII/unicode digit from it (e.g. '0'), then you'll be left with the digit's corresponding value (hence, 1)

Because char is the same as short (although, an unsigned short), you can safely cast it to an int. And the casting is always done automatically if arithmetics are involved


This is an old ASCII trick which will work for any encoding that lines the digits '0' through '9' sequentially starting at '0'. In Ascii, '0' is a character with value 0x30 and '9' is 0x39. Basically, if you have a character that is a digit, subtracting '0' "converts" it to it's digit value.

I have to disagree with @Lukas Eder and suggest that it is a terrible trick; because the intent of this action aproaches 0% obvious from code. If you are using Java and have a String that contains digits and you want to convert said String to an int I suggest that you use Integer.parseInt(yourString);.

This technique has the benifit of being obvious to the future maintenance programmer.


'0' is a char too. It turns out, the characters in Java have a unicode (UTF-16) value. When you use the - operator with characters Java performs the operation with the integer values.

For instance, int x = 'A' - '0';// x = 17


chars are converted to int implicitly:

   public static void main(String [] args) throws Exception {
     String bar = "abc";
     int foo = bar.charAt(1) - '0';
     int foob = bar.charAt(1);
     System.err.println("foo = " + foo + "   foob = " + foob);
   }

output: foo = 50 foob = 98.

Maybe you put two int foo ... and this is because it didn't work?


The following code works perfectly fine!

int foo = bar.charAt(1);

Similar to reference types, any Java primitive can be assigned without casting to another primitive of a type it is considered a subtype of. The subtyping rules for primitives are given by JLS section 4.10.1. char is considered a subtype of int, so any char may be assigned to an int.


Your code may compile without error & run without throwing an exception, but converting between char's & int's is bad practice. First, it makes the code confusing, leading to maintenance headaches down the road. Second, clever "tricks" can prevent compilers from optimizing the byte code. One of the best ways to get fast code is to write dumb code (i.e., not clever code).


Because in Java if you do not specify a type indicator with a number then it assumes Integer. What I mean by that, if you want to set a Long value, it would need to be 0L.

Performing a numerical operation on two different numerics, the result takes the larger. Hence, a char (which is a numerical value) minus an integer, results in an integer.

You will find that this works also

long val = bar.charAt(1) - 0L;


Your second snipped should work fine though:

int foo = bar.charAt(1);

A char, just like a short or byte, will always be silently cast to int if needed.

This will compile just fine: int i = 'c';


I will echo what @Mark Peters has said above in case people overlook his comment.

As I quote: " Don't make the mistake of thinking that '0' == 0. In reality, '0' == 48 "


'5' has the int value of 53

if we write '5'-'0' it evaluates to 53-48, or the int 5

if we write char c = 'B'+32; then c stores 'b'

'b' = 98.

Please refer ASCII chart https://en.cppreference.com/w/cpp/language/ascii

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜