Convert rune to int?

45,905

Solution 1

The problem is simpler than it looks. You convert a rune value to an int value with int(r). But your code implies you want the integer value out of the ASCII (or UTF-8) representation of the digit, which you can trivially get with r - '0' as a rune, or int(r - '0') as an int. Be aware that out-of-range runes will corrupt that logic.

Solution 2

For example, sum += (int(c) - '0') * factor,

package main

import (
    "fmt"
    "strconv"
    "unicode/utf8"
)

func main() {
    s := "9780486653556"
    var factor, sum1, sum2 int
    for i, c := range s[:12] {
        if i%2 == 0 {
            factor = 1
        } else {
            factor = 3
        }
        buf := make([]byte, 1)
        _ = utf8.EncodeRune(buf, c)
        value, _ := strconv.Atoi(string(buf))
        sum1 += value * factor
        sum2 += (int(c) - '0') * factor
    }
    fmt.Println(sum1, sum2)
}

Output:

124 124

Solution 3

why don't you do only "string(rune)".

s:="12345678910"
var factor,sum int
for i,x:=range s{
    if i%2==0{
            factor=1
        }else{
        factor=3
    }
        xstr:=string(x) //x is rune converted to string
        xint,_:=strconv.Atoi(xstr)
        sum+=xint*factor
}
fmt.Println(sum)
Share:
45,905
miku
Author by

miku

A program is generally exponentially complicated by the number of notions that it invents for itself. To reduce this complication to a minimum, you have to make the number of notions zero or one, which are two numbers that can be raised to any power without disturbing this concept. Since you cannot achieve much with zero notions, it is my belief that you should base systems on a single notion.

Updated on November 22, 2020

Comments

  • miku
    miku over 3 years

    In the following code, I iterate over a string rune by rune, but I'll actually need an int to perform some checksum calculation. Do I really need to encode the rune into a []byte, then convert it to a string and then use Atoi to get an int out of the rune? Is this the idiomatic way to do it?

    // The string `s` only contains digits.
    var factor int
    for i, c := range s[:12] {
        if i % 2 == 0 {
            factor = 1
        } else {
            factor = 3
        }
        buf := make([]byte, 1)
        _ = utf8.EncodeRune(buf, c)
        value, _ := strconv.Atoi(string(buf))
        sum += value * factor
    }
    

    On the playground: http://play.golang.org/p/noWDYjn5rJ

  • miku
    miku over 10 years
    Thanks, but that's not quite what I want. You are initializing the rune with 42 - that would yield the * character according to my ASCII table. What I get is a string and range yields runes, that represent the the character. Using int on the rune would give me the value of the representation, not the display value, which I need. I made a short snippet, that hints at the difference: play.golang.org/p/JLlmKnddGv
  • peterSO
    peterSO over 10 years
    @miku: see my revised answer.
  • miku
    miku over 10 years
    Ah, nice trick. I don't know why your answer has been downvoted.
  • Evgeniy Maynagashev
    Evgeniy Maynagashev almost 4 years
    For those who is wondering how int(r-'0') even work, short explanation: "subtracting the value of rune '0' from any rune '0' through '9' will give you an integer 0 through 9". Resulting type after subtraction r-'0' will be int32 (base type of runes), that is why if you need int type - you will also need int() conversion.