# How can I do arithmetics with Char objects?

**URL:** <https://discourse.julialang.org/t/how-can-i-do-arithmetics-with-char-objects/48908>\
**Category:** General Usage\
**Created:** [October 23, 2020, 8:23pm UTC](https://discourse.julialang.org/t/how-can-i-do-arithmetics-with-char-objects/48908 "2020-10-23T20:23:06Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![jcbritobr](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jcbritobr/32/219275_2.png) [@jcbritobr](https://discourse.julialang.org/u/jcbritobr)\
**Post date:** [October 23, 2020, 8:23pm UTC](https://discourse.julialang.org/t/how-can-i-do-arithmetics-with-char-objects/48908/1 "2020-10-23T20:23:06Z")

</div>

Hi, I’m trying to subtract to char, but goting this issue - ERROR: InexactError: trunc(UInt32, -65)  
Please, may someone help?

```julia
function generate_frequencies(data::String)

    data = replace(strip(lowercase(data)), "\n" => "")

    num_count = 0

    frequencies = Dict{Char, Int64}

    for c in data

        println(typeof(c))

        ch = Char(c - 'a') # this fails 

        println(typeof(ch))

        if ch >= 'a' && ch <= 'z'

            if haskey(frequencies, ch)

                frequencies[ch] += 1

                num_count += 1

            else

                frequencies[ch] = 0

            end

        end

    end

    frequencies / num_count

end

```

---

<div class="post-metadata">

**Author:** ![simeonschaub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/simeonschaub/32/216566_2.png) [@simeonschaub](https://discourse.julialang.org/u/simeonschaub)\
**Post date:** [October 23, 2020, 8:30pm UTC](https://discourse.julialang.org/t/how-can-i-do-arithmetics-with-char-objects/48908/2 "2020-10-23T20:30:00Z")

</div>

Character code points are always positive, but `c - 'a'` can be negative if `c` is a `Char` with a character code point less than that of `a`, for example if `c == ':'`:

```julia
julia> ':' - 'a'
-39

```

The best way around this is probably just to work with regular signed integers instead of converting the result of this subtraction back to a `Char`.

---

<div class="post-metadata">

**Author:** ![jcbritobr](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jcbritobr/32/219275_2.png) [@jcbritobr](https://discourse.julialang.org/u/jcbritobr)\
**Post date:** [October 23, 2020, 8:35pm UTC](https://discourse.julialang.org/t/how-can-i-do-arithmetics-with-char-objects/48908/3 "2020-10-23T20:35:26Z")

</div>

> [@jcbritobr](#):
>
> `frequencies = Dict{Char, Int64}`

I need work with char because I had a dictionary ` frequencies = Dict{Char, Int64}` where I will aggregate the frequencies of chars. I cant believe this cant be done.

---

<div class="post-metadata">

**Author:** ![jcbritobr](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jcbritobr/32/219275_2.png) [@jcbritobr](https://discourse.julialang.org/u/jcbritobr)\
**Post date:** [October 23, 2020, 8:40pm UTC](https://discourse.julialang.org/t/how-can-i-do-arithmetics-with-char-objects/48908/4 "2020-10-23T20:40:11Z")

</div>

I had changed the code to get the default Char from c, but also, I cant even compare if the entry exists in the dictionary  
no method matching haskey(::Type{Dict{Char,Int64}}, ::Char) 🙁

---

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [October 23, 2020, 8:42pm UTC](https://discourse.julialang.org/t/how-can-i-do-arithmetics-with-char-objects/48908/5 "2020-10-23T20:42:29Z")

</div>

@jcbritobr if you are building some text processing pipeline, consider checking the projects in the JuliaText organization: [https://github.com/JuliaText](https://github.com/JuliaText)

I will let people with more experience in text processing address the specific issue you are having with low level char operations.

---

<div class="post-metadata">

**Author:** ![jcbritobr](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jcbritobr/32/219275_2.png) [@jcbritobr](https://discourse.julialang.org/u/jcbritobr)\
**Post date:** [October 23, 2020, 8:44pm UTC](https://discourse.julialang.org/t/how-can-i-do-arithmetics-with-char-objects/48908/6 "2020-10-23T20:44:17Z")

</div>

Thank you @juliohm. I’m Julio too. 🙂

---

<div class="post-metadata">

**Author:** ![jcbritobr](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jcbritobr/32/219275_2.png) [@jcbritobr](https://discourse.julialang.org/u/jcbritobr)\
**Post date:** [October 23, 2020, 9:02pm UTC](https://discourse.julialang.org/t/how-can-i-do-arithmetics-with-char-objects/48908/7 "2020-10-23T21:02:56Z")

</div>

I found one of the issues. The dictionary was created incorrectly. In think was not initialized  
This fix

> no method matching haskey(::Type{Dict{Char,Int64}}, ::Char)

frequencies = Dict{Char, Int64}()

---

<div class="post-metadata">

**Author:** ![Jeff\_Emanuel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeff_emanuel/32/15440_2.png) [@Jeff\_Emanuel](https://discourse.julialang.org/u/Jeff_Emanuel)\
**Post date:** [October 23, 2020, 9:29pm UTC](https://discourse.julialang.org/t/how-can-i-do-arithmetics-with-char-objects/48908/8 "2020-10-23T21:29:30Z")

</div>

Do you really want to do this

> [@jcbritobr](#):
>
> `ch = Char(c - 'a') # this fails `

when you test like this?

> [@jcbritobr](#):
>
> `if ch >= 'a' && ch <= 'z'`

---

<div class="post-metadata">

**Author:** ![jcbritobr](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jcbritobr/32/219275_2.png) [@jcbritobr](https://discourse.julialang.org/u/jcbritobr)\
**Post date:** [October 23, 2020, 9:40pm UTC](https://discourse.julialang.org/t/how-can-i-do-arithmetics-with-char-objects/48908/9 "2020-10-23T21:40:59Z")

</div>

Yep, you had a point. The logics are wrong, but the issue is conversion. I was fixing the code just right now and I get it working.

1. Subtracting c-‘a’ I was dealing with an index, but i had a dictionary and the char is just what I need
2. Map the result dividing all values by the num\_count, to get the frequency.

Thank you all guys, for help

```julia
function generate_frequencies(data::String)

    data = replace(strip(lowercase(data)), "\n" => "")

    num_count = 0

    frequencies = Dict{Char, Int64}()

    for c in data

        if c >= 'a' && c <= 'z'

            if haskey(frequencies, c)

                frequencies[c] += 1

                num_count += 1

            else

                frequencies[c] = 0

            end

        end

    end

    map!(x -> floor(x / num_count), values(frequencies))

    frequencies

end

```

---

<div class="post-metadata">

**Author:** ![jcbritobr](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jcbritobr/32/219275_2.png) [@jcbritobr](https://discourse.julialang.org/u/jcbritobr)\
**Post date:** [October 23, 2020, 9:42pm UTC](https://discourse.julialang.org/t/how-can-i-do-arithmetics-with-char-objects/48908/10 "2020-10-23T21:42:13Z")

</div>

Julia is not so easy. We must pay attention. There is a lot of tricks, and I’m a begginer. Just started yesterday.

---

<div class="post-metadata">

**Author:** ![Jeff\_Emanuel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeff_emanuel/32/15440_2.png) [@Jeff\_Emanuel](https://discourse.julialang.org/u/Jeff_Emanuel)\
**Post date:** [October 23, 2020, 9:49pm UTC](https://discourse.julialang.org/t/how-can-i-do-arithmetics-with-char-objects/48908/11 "2020-10-23T21:49:12Z")

</div>

> [@jcbritobr](#):
>
> ```julia-auto
> frequencies[c] = 0
> 
> ```

Do you really want to initialize the count to zero on the first occurrence? You also miss incrementing num\_count on first occurrences.

> [@jcbritobr](#):
>
> Julia is not so easy.

Those logic errors are not inherent to Julia.

---

<div class="post-metadata">

**Author:** ![jcbritobr](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jcbritobr/32/219275_2.png) [@jcbritobr](https://discourse.julialang.org/u/jcbritobr)\
**Post date:** [October 23, 2020, 10:19pm UTC](https://discourse.julialang.org/t/how-can-i-do-arithmetics-with-char-objects/48908/12 "2020-10-23T22:19:25Z")

</div>

Its working. The code on first occurrence is just to initialize the key for letter. It must not increment. Here are my results

![image](https://global.discourse-cdn.com/julialang/original/3X/c/a/cacbf34a7f0f627251f891182266db734ac08392.png)

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [October 23, 2020, 10:49pm UTC](https://discourse.julialang.org/t/how-can-i-do-arithmetics-with-char-objects/48908/13 "2020-10-23T22:49:11Z")

</div>

I think what @Jeff_Emanuel meant was that

> [@jcbritobr](#):
>
> ```julia-auto
> frequencies[c] = 0
> 
> ```

should be

```julia
frequencies[c] = 1

```

instead.

Otherwise, what you are storing is not the number of occurrences but one less than the number of occurrences. A letter that only appears a single time will have value zero.

---

<div class="post-metadata">

**Author:** ![jcbritobr](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jcbritobr/32/219275_2.png) [@jcbritobr](https://discourse.julialang.org/u/jcbritobr)\
**Post date:** [October 23, 2020, 10:55pm UTC](https://discourse.julialang.org/t/how-can-i-do-arithmetics-with-char-objects/48908/14 "2020-10-23T22:55:10Z")

</div>

Yes. Makes all sense. You both are right. 🙂 Here are the plot fixed.  
Because I’m a beginner, I can’t do more posts today 🙁

 ![image](https://global.discourse-cdn.com/julialang/original/3X/c/f/cf83a811d083a4e809e66a7801e2e96ad87cc867.png)

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [October 23, 2020, 11:05pm UTC](https://discourse.julialang.org/t/how-can-i-do-arithmetics-with-char-objects/48908/15 "2020-10-23T23:05:10Z")

</div>

Just to make sure it’s clear in the end, when you do `c - 'a'` you get an offset of the character `c` from `'a'`: this is logically an integer, not a character, because it is an offset. You can convert that offset back to a character, but that gives you the character whose Unicode code point is that offset — which doesn’t make a whole lot of sense. For example:

```julia
julia> c = 'k'
'k': ASCII/Unicode U+006B (category Ll: Letter, lowercase)

julia> c - 'a'
10
# 'k' is 10 chars after 'a'

julia> Char(c - 'a')
'\n': ASCII/Unicode U+000A (category Cc: Other, control)
# newline has code point 10

```

You can use these offsets as keys if you want to: then your keys for English letters will be 0 through 25. But in that case your dict should have type `Dict{Int, Int}` instead of `Dict{Char, Int}`. This would also allow using a much more efficient data structure for counting frequencies, like `fill(0, 26)` which is a `Vector{Int}`. However, in all of these cases, when you translate the data back to characters, you’ll have to do `'a' + offset` to get a character back from an offset.

The other approach is what you chose yourself, which is to just use `Char` values as keys and not try to subtract `'a'` from them. This has the advantage that it is simpler and will handle absolutely any character value at all if you decide to stop filtering the characters.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [October 24, 2020, 2:58am UTC](https://discourse.julialang.org/t/how-can-i-do-arithmetics-with-char-objects/48908/16 "2020-10-24T02:58:41Z")

</div>

> [@jcbritobr](#):
>
> Here are my results

If you are comparing letter frequencies for English text to a non-English language like Portugese, you probably want to strip diacritical marks from the data:

```jl
julia> data = "Portugal, oficialmente República Portuguesa, é um país soberano unitário localizado no sudoeste da Europa, cujo território se situa na zona ocidental da Península Ibérica e em arquipélagos no Atlântico Norte.";

julia> using Unicode

julia> Unicode.normalize(data, stripmark=true, casefold=true)
"portugal, oficialmente republica portuguesa, e um pais soberano unitario localizado no sudoeste da europa, cujo territorio se situa na zona ocidental da peninsula iberica e em arquipelagos no atlantico norte."

```
