I want to check if a string is numeric.
For example:
"abcd123"
should return false
. "1.4"
or "240"
should return true
. I thought about using ParseInt
and ParseFloat
(from the strconv
package), but am not sure if that is the right way.
I was thinking of using strconv ParseInt and ParseFloat but not sure if that is the right way.
Well, it's certainly a right way.
You don't need to use ParseInt, though. ParseFloat will do the job.
func isNumeric(s string) bool {
_, err := strconv.ParseFloat(s, 64)
return err == nil
}
See an example here: https://play.golang.org/p/D53HRS-KIL
If you need to convert the string to a floating-point number strconv.ParseFloat
is the first choice.
Here you just need to know that there is only "0123456789"
and maximum one '.'
in your string, here for me isNumDot
is 12x
faster than isNumeric
, see:
Consider this (1.7 seconds) - optimized for performance:
func isNumDot(s string) bool {
dotFound := false
for _, v := range s {
if v == '.' {
if dotFound {
return false
}
dotFound = true
} else if v < '0' || v > '9' {
return false
}
}
return true
}
and this (21.7 seconds - doing more extra works "converts the string to a floating-point number"):
func isNumeric(s string) bool {
_, err := strconv.ParseFloat(s, 64)
return err == nil
}
Try it:
package main
import (
"fmt"
"strconv"
"time"
)
func isNumDot(s string) bool {
dotFound := false
for _, v := range s {
if v == '.' {
if dotFound {
return false
}
dotFound = true
} else if v < '0' || v > '9' {
return false
}
}
return true
}
func isNumeric(s string) bool {
_, err := strconv.ParseFloat(s, 64)
return err == nil
}
func main() {
fmt.Println(isNumDot("240")) //true
fmt.Println(isNumDot("abcd123")) //false
fmt.Println(isNumDot("0.4.")) //false
fmt.Println(isNumDot("240 ")) //false
benchmark(isNumDot)
benchmark(isNumeric)
}
func benchmark(f func(string) bool) {
var res bool
t := time.Now()
for i := 0; i < 100000000; i++ {
res = f("a 240") || f("abcd123") || f("0.4.") || f("240 ")
}
fmt.Println(time.Since(t))
fmt.Println(res)
}
output:
true
false
false
false
1.7822s
false
21.723s
false
Using the benchmark (isNumDot
is faster than isNumeric
):
BenchmarkIsNumDot-8 34117197 31.2 ns/op 0 B/op 0 allocs/op
BenchmarkIsNumeric-8 1931089 630 ns/op 192 B/op 4 allocs/op
// r = isNumDot("2.22")
BenchmarkIsNumDot-8 102849996 11.4 ns/op 0 B/op 0 allocs/op
BenchmarkIsNumeric-8 21994874 48.5 ns/op 0 B/op 0 allocs/op
// r = isNumDot("a 240")
BenchmarkIsNumDot-8 256610877 4.58 ns/op 0 B/op 0 allocs/op
BenchmarkIsNumeric-8 8962381 140 ns/op 48 B/op 1 allocs/op
The benchmark:
package main
import (
"testing"
)
var r bool
func BenchmarkIsNumDot(b *testing.B) {
for i := 0; i < b.N; i++ {
r = isNumDot("a 240") || isNumDot("abcd123") || isNumDot("0.4.") || isNumDot("240 ")
}
}
func BenchmarkIsNumeric(b *testing.B) {
for i := 0; i < b.N; i++ {
r = isNumeric("a 240") || isNumeric("abcd123") || isNumeric("0.4.") || isNumeric("240 ")
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With