Consider this simple piece of go code.func SomeFunc(val1, val2 int) int {max := math.Max(val1, val2)return max}Hold it, I know what you're thinking "But math.Max() can take in only float64s". Right. So, in order to make the code compile, I have to do this :func SomeFunc(val1, val2 int) int {max := int(math.Max(float64(val1), float64(val2)))return max}It looks very verbose for doing something very simple. Is there any way I can add a function to the math package that takes in ints abd return an int (Like extension methods in C#).The function signature I add would be like this :func Max(val1, val2 int) int
func Max(a, b int) int {
if a < b {
return a
}
return b
}
You should almost always attempt to avoid trying to use functions that take floats's in order to process ints, since the float and int number types have very different properties.
On 64 bit platforms, a go 'int' is 64 bits, and a float64 can only represent integral values between 0 and +- 2^53. For each order of magnitude further from zero, the precision halves, so 2^60 and 2^60+127 may be indistinguishable, which is a major problem (you will likely convert the output to an int that doesn't match one of the inputs you gave to math.Max.
In go, just because you can convert between numeric types to use a function in the stdlib doesn't mean it's a good idea -- the stdlib may provide functions for non-trivial cases (look at the source for math.Max, which handles NaN and +-Inf), yet not provide implementations for the type you care about -- when this happens, consider very carefully whether it's reasonable to convert (such as with float32), or if it's such a simple func to write that you're expected to write it yourself.
func Max(a, b int) int {
if a >= b {
return a
}
return b
}
Similarly, any thoughts on what licence I should put in there? I'm fine with a "do whatever you want with it" kind of thing.
Well, I would like to make one on my own:
func Max(a, b int) int {
if a > b {return a}
return b
}
Just to demonstrate how dangerous, in actual real life (yes, really), the idea is of using float64 intermediates for int operations: http://play.golang.org/p/RrZXeSgmftRun it, and you'll see that "the max of x and y is neither x nor y, but less than both!" I'm sure that's exactly what you expected, right? Any proximal values in the range [2^54,2^64) will have this pathological behavior. Any proximal values in the range [2^53, 2^54) will at least have the result equal to either value, but with this implementation, it will still act like a minimizing function instead of having the maximizing behavior that one would hope. And 2^53 isn't even that large compared to the maximum int64 value (it's a least a difference of ten orders of magnitude).
math.Max is not intended for int types. I would write my own, which is exactly:
func Max(a, b int) int {
if a < b {
return a
}
return b
}