...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package apd
16
17 import (
18 "errors"
19 "fmt"
20 "strings"
21 )
22
23
24 type Condition uint32
25
26 const (
27
28 SystemOverflow Condition = 1 << iota
29
30 SystemUnderflow
31
32
33 Overflow
34
35 Underflow
36
37
38 Inexact
39
40
41 Subnormal
42
43
44 Rounded
45
46 DivisionUndefined
47
48 DivisionByZero
49
50
51 DivisionImpossible
52
53 InvalidOperation
54
55
56 Clamped
57 )
58
59
60 func (r Condition) Any() bool { return r != 0 }
61
62
63 func (r Condition) SystemOverflow() bool { return r&SystemOverflow != 0 }
64
65
66 func (r Condition) SystemUnderflow() bool { return r&SystemUnderflow != 0 }
67
68
69 func (r Condition) Overflow() bool { return r&Overflow != 0 }
70
71
72 func (r Condition) Underflow() bool { return r&Underflow != 0 }
73
74
75 func (r Condition) Inexact() bool { return r&Inexact != 0 }
76
77
78 func (r Condition) Subnormal() bool { return r&Subnormal != 0 }
79
80
81 func (r Condition) Rounded() bool { return r&Rounded != 0 }
82
83
84 func (r Condition) DivisionUndefined() bool { return r&DivisionUndefined != 0 }
85
86
87 func (r Condition) DivisionByZero() bool { return r&DivisionByZero != 0 }
88
89
90 func (r Condition) DivisionImpossible() bool { return r&DivisionImpossible != 0 }
91
92
93 func (r Condition) InvalidOperation() bool { return r&InvalidOperation != 0 }
94
95
96 func (r Condition) Clamped() bool { return r&Clamped != 0 }
97
98
99
100
101 func (r Condition) GoError(traps Condition) (Condition, error) {
102 const (
103 systemErrors = SystemOverflow | SystemUnderflow
104 )
105 var err error
106 if r&systemErrors != 0 {
107 err = errors.New(errExponentOutOfRangeStr)
108 } else if t := r & traps; t != 0 {
109 err = errors.New(t.String())
110 }
111 return r, err
112 }
113
114 func (r Condition) String() string {
115 var names []string
116 for i := Condition(1); r != 0; i <<= 1 {
117 if r&i == 0 {
118 continue
119 }
120 r ^= i
121 var s string
122 switch i {
123 case SystemOverflow, SystemUnderflow:
124 continue
125 case Overflow:
126 s = "overflow"
127 case Underflow:
128 s = "underflow"
129 case Inexact:
130 s = "inexact"
131 case Subnormal:
132 s = "subnormal"
133 case Rounded:
134 s = "rounded"
135 case DivisionUndefined:
136 s = "division undefined"
137 case DivisionByZero:
138 s = "division by zero"
139 case DivisionImpossible:
140 s = "division impossible"
141 case InvalidOperation:
142 s = "invalid operation"
143 case Clamped:
144 s = "clamped"
145 default:
146 panic(fmt.Errorf("unknown condition %d", i))
147 }
148 names = append(names, s)
149 }
150 return strings.Join(names, ", ")
151 }
152
153
154
155 func (r Condition) negateOverflowFlags() Condition {
156 if r.Overflow() {
157
158 r |= Underflow | Subnormal
159 r &= ^Overflow
160 }
161 if r.SystemOverflow() {
162 r |= SystemUnderflow
163 r &= ^SystemOverflow
164 }
165 return r
166 }
167
View as plain text