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
5package runtime
6
7import "unsafe"
8
9func strmin(x, y string) string {
10	if y < x {
11		return y
12	}
13	return x
14}
15
16func strmax(x, y string) string {
17	if y > x {
18		return y
19	}
20	return x
21}
22
23func fmin32(x, y float32) float32 { return fmin(x, y) }
24func fmin64(x, y float64) float64 { return fmin(x, y) }
25func fmax32(x, y float32) float32 { return fmax(x, y) }
26func fmax64(x, y float64) float64 { return fmax(x, y) }
27
28type floaty interface{ ~float32 | ~float64 }
29
30func fmin[F floaty](x, y F) F {
31	if y != y || y < x {
32		return y
33	}
34	if x != x || x < y || x != 0 {
35		return x
36	}
37	// x and y are both ±0
38	// if either is -0, return -0; else return +0
39	return forbits(x, y)
40}
41
42func fmax[F floaty](x, y F) F {
43	if y != y || y > x {
44		return y
45	}
46	if x != x || x > y || x != 0 {
47		return x
48	}
49	// x and y are both ±0
50	// if both are -0, return -0; else return +0
51	return fandbits(x, y)
52}
53
54func forbits[F floaty](x, y F) F {
55	switch unsafe.Sizeof(x) {
56	case 4:
57		*(*uint32)(unsafe.Pointer(&x)) |= *(*uint32)(unsafe.Pointer(&y))
58	case 8:
59		*(*uint64)(unsafe.Pointer(&x)) |= *(*uint64)(unsafe.Pointer(&y))
60	}
61	return x
62}
63
64func fandbits[F floaty](x, y F) F {
65	switch unsafe.Sizeof(x) {
66	case 4:
67		*(*uint32)(unsafe.Pointer(&x)) &= *(*uint32)(unsafe.Pointer(&y))
68	case 8:
69		*(*uint64)(unsafe.Pointer(&x)) &= *(*uint64)(unsafe.Pointer(&y))
70	}
71	return x
72}
73