forked from woodsbury/decimal128
/
payload.go
122 lines (111 loc) · 2.86 KB
/
payload.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
package decimal128
import "fmt"
const (
payloadOpCompose Payload = iota + 1
payloadOpFromFloat32
payloadOpFromFloat64
payloadOpMustParse
payloadOpNaN
payloadOpParse
payloadOpScan
payloadOpUnmarshalText
payloadOpAdd
payloadOpLog
payloadOpLog10
payloadOpLog2
payloadOpMul
payloadOpPow
payloadOpQuo
payloadOpQuoRem
payloadOpSqrt
payloadOpSub
)
const (
payloadValPosZero Payload = iota + 1
payloadValNegZero
payloadValPosFinite
payloadValNegFinite
payloadValPosInfinite
payloadValNegInfinite
)
// Payload returns the first 64 bits of the payload of a NaN. If the NaN was
// generated by an operation in this package, the contents of the payload
// provides information about what kind of operation was being performed that
// lead to the NaN being generated. Payload panics if d is not a NaN.
func (d Decimal) Payload() Payload {
if !d.IsNaN() {
panic("Decimal(!NaN).Payload()")
}
return Payload(d.lo)
}
// Payload represents the payload value of a NaN decimal. This value can
// contain additional information about the operation that caused the value to
// be set to NaN.
type Payload uint64
// String returns a string representation of the payload.
func (p Payload) String() string {
if p == 0 {
return "Payload(0)"
}
if p > 0x00ff_ffff {
return fmt.Sprintf("Payload(%d)", uint64(p))
}
switch p & 0xff {
case payloadOpCompose:
return "Compose()"
case payloadOpFromFloat32:
return "FromFloat32()"
case payloadOpFromFloat64:
return "FromFloat64()"
case payloadOpMustParse:
return "MustParse()"
case payloadOpNaN:
return "NaN()"
case payloadOpParse:
return "Parse()"
case payloadOpScan:
return "Scan()"
case payloadOpUnmarshalText:
return "UnmarshalText()"
case payloadOpAdd:
return "Add(" + p.argString(8) + ", " + p.argString(16) + ")"
case payloadOpLog:
return "Log(" + p.argString(8) + ")"
case payloadOpLog10:
return "Log10(" + p.argString(8) + ")"
case payloadOpLog2:
return "Log2(" + p.argString(8) + ")"
case payloadOpMul:
return "Mul(" + p.argString(8) + ", " + p.argString(16) + ")"
case payloadOpPow:
return "Pow(" + p.argString(8) + ", " + p.argString(16) + ")"
case payloadOpQuo:
return "Quo(" + p.argString(8) + ", " + p.argString(16) + ")"
case payloadOpQuoRem:
return "QuoRem(" + p.argString(8) + ", " + p.argString(16) + ")"
case payloadOpSqrt:
return "Sqrt(" + p.argString(8) + ")"
case payloadOpSub:
return "Sub(" + p.argString(8) + ", " + p.argString(16) + ")"
default:
return fmt.Sprintf("Payload(%d)", uint64(p))
}
}
func (p Payload) argString(offset int) string {
switch p >> offset & 0xff {
case payloadValPosZero:
return "Zero"
case payloadValNegZero:
return "-Zero"
case payloadValPosFinite:
return "Finite"
case payloadValNegFinite:
return "-Finite"
case payloadValPosInfinite:
return "Infinite"
case payloadValNegInfinite:
return "-Infinite"
default:
return "Unknown"
}
}