Convert rune to int?

77.7k Views Asked by At

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

5

There are 5 best solutions below

1
On BEST ANSWER

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.

3
On

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
0
On

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)
0
On
val, _ := strconv.Atoi(string(v))

Where v is a rune

More concise but same idea as above

0
On

Here is the fix for sum2

sum2 += (int(c) - '0') * factor

Convert int to rune -> int(rune), getting integer for specific ASCII character, just subtract it.

Example int('1') - '0' = 1.

'0' -> 48

'1' -> 49

49 - 48 = 1

For English alphabet it will be ASCII values.

fmt.Println("ASCII  48, val 0 = ", int('0'))
fmt.Println("ASCII  57, val 9 = ", int('9'))

fmt.Println("ASCII  65, val A = ", int('A'))
fmt.Println("ASCII  90, val Z = ", int('Z'))

fmt.Println("ASCII  97, val a = ", int('a'))
fmt.Println("ASCII 122, val z = ", int('z'))

But for non English characters, it will be Non ASCII values, or rather greater than ASCII:

// Cyrillic
fmt.Println("Non ASCII = 1071", int('Я'))
fmt.Println("Non ASCII = 1044", int('Д'))

// Chinese
fmt.Println("Non ASCII = 19990", int('世'))
fmt.Println("Non ASCII = 30028", int('界'))

https://go.dev/play/p/2fhM7DGZ4Km