]> Cypherpunks.ru repositories - gostls13.git/blob - src/math/compare.go
math: add Compare and Compare32
[gostls13.git] / src / math / compare.go
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 }