寻找零以下的最大值

Finding Max Value Below Zero

我正在尝试从差异 n[i] - n[i-1] 时间序列中获取最大值。切片的第一个值始终为零,代码如下:

func MaxBelowZero(n ...float64) float64 {
var maxValue float64
if len(n) == 1 {
    return n[0]
} else if len(n) == 0 {
    return 0.
}
for i := range n {
    if i == 0 {
        maxValue = math.SmallestNonzeroFloat64
        continue
    }
    if maxValue < n[i] && n[i] < 0 {
        maxValue = n[i]
    }
}
return maxValue
}

var sliceTest = []float64{0, 1, 2, -1, -2, -10, 10, 20}
MaxBelowZero(sliceTest...)
Output: 5e-324

应该是-1。我究竟做错了什么?我会很感激一些帮助。 操场上的代码:link

func MaxBelowZero(n ...float64) float64 {
    maxValue := -math.MaxFloat64 // Initial value must be negative
    if len(n) == 1 {
        return n[0]
    } else if len(n) == 0 {
        return 0.
    }
    for i := 1; i < len(n); i++ {
        diff := n[i] - n[i-1] // Correct logic here
        if diff > maxValue && diff < 0 {
            maxValue = diff
        }
    }
    return maxValue
}

math.SmallestNonzeroFloat64是最接近0但不是0的数,不是离0最远的数。试试这个:

go playground

func MaxBelowZero(values ...float64) float64 {
    if len(values) == 0 {
        return 0
    } else if len(values) == 1 {
        return values[0]
    }
    max := -math.MaxFloat64
    for _, n := range values {
        if n >= 0 {
            continue
        }
        if n > max {
            max = n
        }
    }
    return max
}

您可以对切片进行反向排序,然后找到第一个负数:

package main
import "sort"

func main() {
   a := []float64{0, 1, 2, -1, -2, -10, 10, 20}
   sort.Slice(a, func(d, e int) bool {
      return a[e] < a[d]
   })
   n := sort.Search(len(a), func(n int) bool {
      return a[n] < 0
   })
   println(a[n] == -1)
}

或者先按符号排序,再按绝对值排序:

package main
import "math"

type sFunc func(a, b float64) bool

var sFuncs = []sFunc{
   func(a, b float64) bool {
      return math.Copysign(1, a) < math.Copysign(1, b)
   },
   func(a, b float64) bool {
      return math.Abs(a) < math.Abs(b)
   },
}

结果:

package main

import (
   "fmt"
   "sort"
)

func main() {
   floats := []float64{0, 1, 2, -1, -2, -10, 10, 20}
   sort.Slice(floats, func(a, b int) bool {
      fa, fb := floats[a], floats[b]
      for _, sf := range sFuncs {
         if sf(fa, fb) {
            return true
         }
         if sf(fb, fa) {
            break
         }
      }
      return false
   })
   fmt.Println(floats) // [-1 -2 -10 0 1 2 10 20]
}