github.com/twelsh-aw/go/src@v0.0.0-20230516233729-a56fe86a7c81/math/compare.go (about)

     1  // Copyright 2023 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package math
     6  
     7  func sign[I int32 | int64](a, b I) int {
     8  	if a < b {
     9  		return -1
    10  	}
    11  	if a > b {
    12  		return 1
    13  	}
    14  	return 0
    15  }
    16  
    17  // Compare compares a and b such that
    18  // -NaN is ordered before any other value,
    19  // +NaN is ordered after any other value,
    20  // and -0 is ordered before +0.
    21  // In other words, it defines a total order over floats
    22  // (according to the total-ordering predicate in IEEE-754, section 5.10).
    23  // It returns 0 if a == b, -1 if a < b, and +1 if a > b.
    24  func Compare(a, b float64) int {
    25  	// Perform a bitwise comparison (a < b) by casting the float64s into an int64s.
    26  	x := int64(Float64bits(a))
    27  	y := int64(Float64bits(b))
    28  
    29  	// If a and b are both negative, flip the comparison so that we check a > b.
    30  	if x < 0 && y < 0 {
    31  		return sign(y, x)
    32  	}
    33  	return sign(x, y)
    34  }
    35  
    36  // Compare32 compares a and b such that
    37  // -NaN is ordered before any other value,
    38  // +NaN is ordered after any other value,
    39  // and -0 is ordered before +0.
    40  // In other words, it defines a total order over floats
    41  // (according to the total-ordering predicate in IEEE-754, section 5.10).
    42  // It returns 0 if a == b, -1 if a < b, and +1 if a > b.
    43  func Compare32(a, b float32) int {
    44  	// Perform a bitwise comparison (a < b) by casting the float32s into an int32s.
    45  	x := int32(Float32bits(a))
    46  	y := int32(Float32bits(b))
    47  
    48  	// If a and b are both negative, flip the comparison so that we check a > b.
    49  	if x < 0 && y < 0 {
    50  		return sign(y, x)
    51  	}
    52  	return sign(x, y)
    53  }