# How does subtracting the character ‘0’ from a char change it into an int?

Posted on

How does subtracting the character ‘0’ from a char change it into an int?

This method works in C, C++ and Java. I would like to know the science behind it.

The value of a `char` can be 0-255, where the different characters are mapped to one of these values. The numeric digits are also stored in order `'0'` through `'9'`, but they’re also not typically stored as the first ten `char` values. That is, the character `'0'` doesn’t have an ASCII value of `0`. The char value of `0` is almost always the null character.

Without knowing anything else about ASCII, it’s pretty straightforward how subtracting a `'0'` character from any other numeric character will result in the char value of the original character.

So, it’s simple math:

``````'0' - '0' = 0  // Char value of character 0 minus char value of character 0
// In ASCII, that is equivalent to this:
48  -  48 = 0 // '0' has a value of 48 on ASCII chart
``````

So, similarly, I can do integer math with any of the `char` numberics…

``````(('3' - '0') + ('5' - '0') - ('2' - '0')) + '0') = '6'
``````

The difference between `3`, `5`, or `2` and `0` on the ASCII chart is exactly equal to the face value we typically think of when we see that numeric digit. Subtracting the `char '0'` from each, adding them together, and then adding a `'0'` back at the end will give us the char value that represent the char that would be the result of doing that simple math.

The code snippet above emulates `3 + 5 - 2`, but in ASCII, it’s actually doing this:

``````((51 - 48) + (53 - 48) - (50 - 48)) + 48) = 54
``````

Because on the ASCII chart:

``````0 = 48
2 = 50
3 = 51
5 = 53
6 = 54
``````

In C the `+` and `-` operators apply integer promotion*1 to their arguments, thus the result of subtracting (or adding) two `char`s is an `int`*2.

From the C-Standard:

5.1.2.3 Program execution

[…]

10 EXAMPLE 2 In executing the fragment

``````char c1, c2;
/* ... */
c1 = c1 + c2;
``````

the ‘‘integer promotions’’ require that the abstract machine promote the value of each variable to `int` size and then add the two `int`s […]

Applying this to the OP’s implicitly given use case of

``````char c = 42;
... = c - `0`;
``````

This would be lead to the above being the same as:

``````... = (int) c - (int) `0`; /* The second cast is redundant, as per Jens' comment. */
^                ^
+------ int -----+
``````

*1: If the operators arguments have a lower rank than `int` they are promoted to an `int`.

*2: `char` has a lower rank than `int`.

There’s no change going on. `'0'` is an int in C. It is a fancy way to write `48` (assuming ASCII).

You can convince yourself of this fact by computing the size of `'0'`:

``````  printf ("sizeof '0'   is %zun", sizeof '0');
printf ("sizeof(char) is %zun", sizeof(char));
``````

which in the first line very likely prints 4 (or 2) but probably not 1 like in the second row (again: in C; it’s different for C++).

The numeric constant `0`, without any qualifications, has type `int`. The result of the binary subtraction operation on a `char` and an `int` also has type `int` due to the usual type promotion process.