Reputation: 34061
Consider following module
defmodule Parse do
def number([ ?- | tail ]), do: _number_digits(tail, 0) * -1
def number([ ?+ | tail ]), do: _number_digits(tail, 0)
def number(str), do: _number_digits(str, 0)
defp _number_digits([], value), do: value
defp _number_digits([ digit | tail ], value) when digit in '0123456789' do
_number_digits(tail, value*10 + digit - ?0)
end
defp _number_digits([ non_digit | _ ], _) do
raise "Invalid digit '#{[non_digit]}'"
end
end
When I import the file into shell and execute following statement:
iex(3)> Parse.number('123')
as output I've got
123
What I really do not understand is this line:
value*10 + digit - ?0
What does ?0 really mean? I know, when I write ?x on shell, it shows me the code point like
iex(13)> ?5
53
iex(14)> ?t
116
The ?0 has code point -48. The example above with 123, the calculation with first iteration number 1 would looks like(value*10 + digit - ?0):
0 * 10 + 1 - 48
When I calculate by myself, I would get as result -47 but I've got 1, why?
Upvotes: 3
Views: 1681
Reputation: 19153
?
followed by a character gives you that character's Unicode code point value.
The - ?0
done in the second clause of the _number_digits
function subtracts the code point of the character '0' from the digit's code point value. This conveniently gives you the integer 0 for the digit '0', 1 for the digit '1', etc.
Thus, the entire value*10 + digit - ?0
expression first multiples the running total (value
) by 10 (since we're dealing with base-10 input strings), then adds the value for the current digit under consideration. This happens recursively until all digits of the input string are consumed, given you the integer represented by the input string.
Upvotes: 14