patterngoCritical
What is the correct way to find the min between two integers in Go?
Viewed 0 times
findbetweencorrecttheintegerswayminwhattwo
Problem
I imported the math library in my program, and I was trying to find the minimum of three numbers in the following way:
where v1 is declared as:
However, when I run my program I get the following error:
I thought it was weird because I have another program where I write
and that program outputs
so I ended up casting the values as float64, so that
With this approach, I got the following error:
so to get rid of the problem, I just casted the result back to
I thought this was extremely inefficient and hard to read:
I also wrote a small
Is there anything that I'm doing terrible wrong?
Here's a program that you can use to reproduce the issues above, line 36 specifically:
package main
```
import (
"math"
)
func main() {
LevenshteinDistance("stackoverflow", "stackexchange")
}
func LevenshteinDistance(s string, t string) int {
if s == t {
return 0
}
if len(s) == 0 {
return len(t)
}
if len(t) == 0 {
return len(s)
}
v0 := make([]int, len(t)+1)
v1 := make([]int, len(t)+1)
for i := 0; i < le
v1[j+1] = math.Min(v1[j]+1, math.Min(v0[j+1]+1, v0[j]+cost))where v1 is declared as:
t := "stackoverflow"
v1 := make([]int, len(t)+1)However, when I run my program I get the following error:
./levenshtein_distance.go:36: cannot use int(v0[j + 1] + 1) (type int) as type float64 in argument to math.MinI thought it was weird because I have another program where I write
fmt.Println(math.Min(2,3))and that program outputs
2 without complaining.so I ended up casting the values as float64, so that
math.Min could work:v1[j+1] = math.Min(float64(v1[j]+1), math.Min(float64(v0[j+1]+1), float64(v0[j]+cost)))With this approach, I got the following error:
./levenshtein_distance.go:36: cannot use math.Min(int(v1[j] + 1), math.Min(int(v0[j + 1] + 1), int(v0[j] + cost))) (type float64) as type int in assignmentso to get rid of the problem, I just casted the result back to
intI thought this was extremely inefficient and hard to read:
v1[j+1] = int(math.Min(float64(v1[j]+1), math.Min(float64(v0[j+1]+1), float64(v0[j]+cost))))I also wrote a small
minInt function, but I think this should be unnecessary because the other programs that make use of math.Min work just fine when taking integers, so I concluded this has to be a problem of my program and not the library per se.Is there anything that I'm doing terrible wrong?
Here's a program that you can use to reproduce the issues above, line 36 specifically:
package main
```
import (
"math"
)
func main() {
LevenshteinDistance("stackoverflow", "stackexchange")
}
func LevenshteinDistance(s string, t string) int {
if s == t {
return 0
}
if len(s) == 0 {
return len(t)
}
if len(t) == 0 {
return len(s)
}
v0 := make([]int, len(t)+1)
v1 := make([]int, len(t)+1)
for i := 0; i < le
Solution
Starting with Go 1.21,
I'm leaving the previous content below in case someone needs a different simple generic function that isn't built in or can otherwise use the historical answers.
Until Go 1.18 a one-off function was the standard way; for example, the stdlib's sort.go does it near the top of the file:
You might still want or need to use this approach so your code works on Go versions below 1.18!
Starting with Go 1.18, you can write a generic
min and max are available as builtins and you do not need to write them at all. (Thanks @ufukty for highlighting this in a comment.)I'm leaving the previous content below in case someone needs a different simple generic function that isn't built in or can otherwise use the historical answers.
Until Go 1.18 a one-off function was the standard way; for example, the stdlib's sort.go does it near the top of the file:
func min(a, b int) int {
if a < b {
return a
}
return b
}You might still want or need to use this approach so your code works on Go versions below 1.18!
Starting with Go 1.18, you can write a generic
min function which is just as efficient at run time as the hand-coded single-type version, but works with any type with ` operators:
func min[T constraints.Ordered](a, b T) T {
if a < b {
return a
}
return b
}
func main() {
fmt.Println(min(1, 2))
fmt.Println(min(1.5, 2.5))
fmt.Println(min("Hello", "世界"))
}
There's been discussion of updating the stdlib to add generic versions of existing functions, but if that happens it won't be until a later version.
math.Min(2, 3) happened to work because numeric constants in Go are untyped. Beware of treating float64s as a universal number type in general, though, since integers above 2^53` will get rounded if converted to float64.Code Snippets
func min(a, b int) int {
if a < b {
return a
}
return b
}func min[T constraints.Ordered](a, b T) T {
if a < b {
return a
}
return b
}
func main() {
fmt.Println(min(1, 2))
fmt.Println(min(1.5, 2.5))
fmt.Println(min("Hello", "世界"))
}Context
Stack Overflow Q#27516387, score: 183
Revisions (0)
No revisions yet.