-
Notifications
You must be signed in to change notification settings - Fork 0
/
float.go
135 lines (104 loc) · 3.9 KB
/
float.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
package g
import (
"cmp"
"encoding/binary"
"fmt"
"math"
"math/big"
"math/bits"
"strconv"
"github.com/enetx/g/pkg/constraints"
"github.com/enetx/g/pkg/minmax"
)
// NewFloat creates a new Float with the provided value.
func NewFloat[T constraints.Float | constraints.Integer](float T) Float { return Float(float) }
// Bytes returns the Float as a byte slice.
func (f Float) Bytes() Bytes {
buffer := make([]byte, 8)
binary.BigEndian.PutUint64(buffer, f.ToUInt64())
return buffer[bits.LeadingZeros64(f.ToUInt64())>>3:]
}
// Min returns the minimum of two Floats.
func (f Float) Min(b ...Float) Float { return minmax.Min(f, b...) }
// Max returns the maximum of two Floats.
func (f Float) Max(b ...Float) Float { return minmax.Max(f, b...) }
// Abs returns the absolute value of the Float.
func (f Float) Abs() Float { return Float(math.Abs(f.Std())) }
// Add adds two Floats and returns the result.
func (f Float) Add(b Float) Float { return f + b }
// ToBigFloat returns the Float as a *big.Float.
func (f Float) ToBigFloat() *big.Float { return big.NewFloat(f.Std()) }
// Compare compares two Floats and returns an Int.
func (f Float) Compare(b Float) Int { return Int(cmp.Compare(f, b)) }
// Div divides two Floats and returns the result.
func (f Float) Div(b Float) Float { return f / b }
// IsZero checks if the Float is 0.
func (f Float) IsZero() bool { return f.Eq(0) }
// Eq checks if two Floats are equal.
func (f Float) Eq(b Float) bool { return f.Compare(b).Eq(0) }
// Std returns the Float as a float64.
func (f Float) Std() float64 { return float64(f) }
// Gt checks if the Float is greater than the specified Float.
func (f Float) Gt(b Float) bool { return f.Compare(b).Gt(0) }
// ToInt returns the Float as an Int.
func (f Float) ToInt() Int { return Int(f) }
// ToString returns the Float as an String.
func (f Float) ToString() String { return String(strconv.FormatFloat(f.Std(), 'f', -1, 64)) }
// Lt checks if the Float is less than the specified Float.
func (f Float) Lt(b Float) bool { return f.Compare(b).Lt(0) }
// Mul multiplies two Floats and returns the result.
func (f Float) Mul(b Float) Float { return f * b }
// Ne checks if two Floats are not equal.
func (f Float) Ne(b Float) bool { return !f.Eq(b) }
// Round rounds the Float to the nearest integer and returns the result as an Int.
// func (f Float) Round() Int { return Int(math.Round(f.Std())) }
func (f Float) Round() Int {
if f >= 0 {
return Int(f + 0.5)
}
return Int(f - 0.5)
}
// RoundDecimal rounds the Float value to the specified number of decimal places.
//
// The function takes the number of decimal places (precision) as an argument and returns a new
// Float value rounded to that number of decimals. This is achieved by multiplying the Float
// value by a power of 10 equal to the desired precision, rounding the result, and then dividing
// the rounded result by the same power of 10.
//
// Parameters:
//
// - precision (int): The number of decimal places to round the Float value to.
//
// Returns:
//
// - Float: A new Float value rounded to the specified number of decimal places.
//
// Example usage:
//
// f := g.Float(3.14159)
// rounded := f.RoundDecimal(2) // rounded will be 3.14
func (f Float) RoundDecimal(precision int) Float {
if precision < 0 {
return f
}
mult := 1
for i := 0; i < precision; i++ {
mult *= 10
}
result := f * Float(mult)
if result >= 0 {
result += 0.5
} else {
result -= 0.5
}
return Float(int(result)) / Float(mult)
}
// Sub subtracts two Floats and returns the result.
func (f Float) Sub(b Float) Float { return f - b }
// ToUInt64 returns the Float as a uint64.
func (f Float) ToUInt64() uint64 { return math.Float64bits(f.Std()) }
// AsFloat32 returns the Float as a float32.
func (f Float) AsFloat32() float32 { return float32(f) }
// Print prints the value of the Float to the standard output (console)
// and returns the Float unchanged.
func (f Float) Print() Float { fmt.Println(f); return f }