Why Pow(NaN, 0) is equal to 1 is correct?

std examples says:

// Pow(NaN, y) = NaN
// Pow(x, NaN) = NaN

If y is any number (includes 0), then in fact examples and actual result is different:

package main

import (

func main() {
	fmt.Println(math.Pow(0, math.NaN())) // Output: NaN
	fmt.Println(math.Pow(math.NaN(), 0)) // Output: 1

According to the src of the pow func, it’s a case order issue:

func pow(x, y float64) float64 {
	switch {
	case y == 0 || x == 1: // <- In this case example breaks
		return 1
	case y == 1:
		return x
	case IsNaN(x) || IsNaN(y): // <- Seems like correct example case
		return NaN()

	// ...

Why it’s not a issue for Go developers? It’s an edge case described in examples, but handled incorrectly. All of this case couldn’t handled at the begin of the function?

1 Like

From NaN - Wikipedia

The 2008 version of the IEEE 754 standard says that pow(1, qNaN) and pow(qNaN, 0) should both return 1 since they return 1 whatever else is used instead of quiet NaN.

Go is not often used for numerical computing.


julia> NaN ^ 0

julia> 1 ^ NaN

But I’m still confused. If we base on the standard (math package has references to it), then why result of the pow differs from the required value?

Okay, but I don’t think that’s the reason. It still seems that the Go developers could have moved edge cases like this from switch-case to if statement at the beginning of the function.

1 Like

You might want to open an issue in the repo. This is slightly outside the realm of my expertise but the docs state this:

Special cases are (in order):

Pow(NaN, y) = NaN
Pow(x, NaN) = NaN

Which, if I’m reading that right, would mean that both of your examples above would return NaN. But the source for Pow clearly shows special handling for y == 0 || x ==1 as you’ve shown above. It could be a bug in an area of the stdlib that’s not exercised much, or there could be a rationale that we don’t have background on (reading about this in other languages will show you that it’s a hotly debated topic).

1 Like