In all standardised character sets the character '0'
(which prints as a zero on screen) has a non-zero numeric value.
There are a number of reasons for this - including the convention (used in C) of using a character with numeric value of 0
being used to mark the end of a string of characters. This convention, if '0'
had a numeric value of zero, mean that it would not be possible to represent a value like 100
as a string (every digit '0'
would mark the end of the string).
In character sets compatible with ASCII, '0'
has a numeric value of 48
. There are standardised character sets with '0'
having a different numeric value.
Fortunately, in all standardised character sets, the arabic numerals ('0'
, '1'
, .... '9'
) are a contiguous set so, if x
is a character containing an arabic numeral, x - '0'
will convert x
to its corresponding numeric value (e.g. '0' - '0'
gives an integral value of 0
, '1' - '0'
is 1
, etc).
So, when examining digits presented in a string, it is necessary to subtract '0'
from each to convert it to its numeric value. For example, adding the characters of "12"
as 10*'1' + '2'
will (for an ASCII character set) give a value of 540
, but subtracting '0'
from each character (i.e. 10*('1' - '0') + ('2' - '0'
) will give 12
.
This can be demonstrated in the following code snippet.
#include <iostream>
int main()
{
char digit = '0';
std::cout << digit << '\n'; // will print 0 (followed by newline)
std::cout << (int)digit << '\n'; // for an ASCII character set will print 48
std::string test = "12";
int incorrect_sum = 0;
int correct_sum = 0;
for (const auto c : test)
{
incorrect_sum *= 10;
incorrect_sum += c;
correct_sum *= 10;
correct_sum += c - '0'; // note the correction here
}
std::cout << incorrect_sum << ' ' << correct_sum << '\n'; // will print 540 and 12
}