Source file src/pkg/cmd/compile/internal/gc/mpfloat.go
1
2
3
4
5 package gc
6
7 import (
8 "fmt"
9 "math"
10 "math/big"
11 )
12
13
14
15 const (
16
17
18 Mpprec = 512
19
20 Mpdebug = false
21 )
22
23
24 type Mpflt struct {
25 Val big.Float
26 }
27
28
29 type Mpcplx struct {
30 Real Mpflt
31 Imag Mpflt
32 }
33
34
35 func newMpflt() *Mpflt {
36 var a Mpflt
37 a.Val.SetPrec(Mpprec)
38 return &a
39 }
40
41
42 func newMpcmplx() *Mpcplx {
43 var a Mpcplx
44 a.Real = *newMpflt()
45 a.Imag = *newMpflt()
46 return &a
47 }
48
49 func (a *Mpflt) SetInt(b *Mpint) {
50 if b.checkOverflow(0) {
51
52 a.Val.SetInf(b.Val.Sign() < 0)
53 return
54 }
55 a.Val.SetInt(&b.Val)
56 }
57
58 func (a *Mpflt) Set(b *Mpflt) {
59 a.Val.Set(&b.Val)
60 }
61
62 func (a *Mpflt) Add(b *Mpflt) {
63 if Mpdebug {
64 fmt.Printf("\n%v + %v", a, b)
65 }
66
67 a.Val.Add(&a.Val, &b.Val)
68
69 if Mpdebug {
70 fmt.Printf(" = %v\n\n", a)
71 }
72 }
73
74 func (a *Mpflt) AddFloat64(c float64) {
75 var b Mpflt
76
77 b.SetFloat64(c)
78 a.Add(&b)
79 }
80
81 func (a *Mpflt) Sub(b *Mpflt) {
82 if Mpdebug {
83 fmt.Printf("\n%v - %v", a, b)
84 }
85
86 a.Val.Sub(&a.Val, &b.Val)
87
88 if Mpdebug {
89 fmt.Printf(" = %v\n\n", a)
90 }
91 }
92
93 func (a *Mpflt) Mul(b *Mpflt) {
94 if Mpdebug {
95 fmt.Printf("%v\n * %v\n", a, b)
96 }
97
98 a.Val.Mul(&a.Val, &b.Val)
99
100 if Mpdebug {
101 fmt.Printf(" = %v\n\n", a)
102 }
103 }
104
105 func (a *Mpflt) MulFloat64(c float64) {
106 var b Mpflt
107
108 b.SetFloat64(c)
109 a.Mul(&b)
110 }
111
112 func (a *Mpflt) Quo(b *Mpflt) {
113 if Mpdebug {
114 fmt.Printf("%v\n / %v\n", a, b)
115 }
116
117 a.Val.Quo(&a.Val, &b.Val)
118
119 if Mpdebug {
120 fmt.Printf(" = %v\n\n", a)
121 }
122 }
123
124 func (a *Mpflt) Cmp(b *Mpflt) int {
125 return a.Val.Cmp(&b.Val)
126 }
127
128 func (a *Mpflt) CmpFloat64(c float64) int {
129 if c == 0 {
130 return a.Val.Sign()
131 }
132 return a.Val.Cmp(big.NewFloat(c))
133 }
134
135 func (a *Mpflt) Float64() float64 {
136 x, _ := a.Val.Float64()
137
138
139 if math.IsInf(x, 0) && nsavederrors+nerrors == 0 {
140 Fatalf("ovf in Mpflt Float64")
141 }
142
143 return x + 0
144 }
145
146 func (a *Mpflt) Float32() float64 {
147 x32, _ := a.Val.Float32()
148 x := float64(x32)
149
150
151 if math.IsInf(x, 0) && nsavederrors+nerrors == 0 {
152 Fatalf("ovf in Mpflt Float32")
153 }
154
155 return x + 0
156 }
157
158 func (a *Mpflt) SetFloat64(c float64) {
159 if Mpdebug {
160 fmt.Printf("\nconst %g", c)
161 }
162
163
164 if c == 0 {
165 c = 0
166 }
167 a.Val.SetFloat64(c)
168
169 if Mpdebug {
170 fmt.Printf(" = %v\n", a)
171 }
172 }
173
174 func (a *Mpflt) Neg() {
175
176 if a.Val.Sign() != 0 {
177 a.Val.Neg(&a.Val)
178 }
179 }
180
181 func (a *Mpflt) SetString(as string) {
182
183 for len(as) > 0 && (as[0] == ' ' || as[0] == '\t') {
184 as = as[1:]
185 }
186
187 f, _, err := a.Val.Parse(as, 0)
188 if err != nil {
189 yyerror("malformed constant: %s (%v)", as, err)
190 a.Val.SetFloat64(0)
191 return
192 }
193
194 if f.IsInf() {
195 yyerror("constant too large: %s", as)
196 a.Val.SetFloat64(0)
197 return
198 }
199
200
201 if f.Sign() == 0 && f.Signbit() {
202 a.Val.SetFloat64(0)
203 }
204 }
205
206 func (f *Mpflt) String() string {
207 return f.Val.Text('b', 0)
208 }
209
210 func (fvp *Mpflt) GoString() string {
211
212 sign := ""
213 f := &fvp.Val
214 if f.Sign() < 0 {
215 sign = "-"
216 f = new(big.Float).Abs(f)
217 }
218
219
220 if f.IsInf() {
221 return sign + "Inf"
222 }
223
224
225
226 if x, _ := f.Float64(); f.Sign() == 0 == (x == 0) && !math.IsInf(x, 0) {
227 return fmt.Sprintf("%s%.6g", sign, x)
228 }
229
230
231
232
233
234 var mant big.Float
235 exp := f.MantExp(&mant)
236
237
238
239 m, _ := mant.Float64()
240 d := float64(exp) * (math.Ln2 / math.Ln10)
241
242
243 e := int64(d)
244 m *= math.Pow(10, d-float64(e))
245
246
247 switch {
248 case m < 1-0.5e-6:
249
250
251
252 m *= 10
253 e--
254 case m >= 10:
255 m /= 10
256 e++
257 }
258
259 return fmt.Sprintf("%s%.6ge%+d", sign, m, e)
260 }
261
262
263
264 func (v *Mpcplx) Mul(rv *Mpcplx) {
265 var ac, ad, bc, bd Mpflt
266
267 ac.Set(&v.Real)
268 ac.Mul(&rv.Real)
269
270 bd.Set(&v.Imag)
271 bd.Mul(&rv.Imag)
272
273 bc.Set(&v.Imag)
274 bc.Mul(&rv.Real)
275
276 ad.Set(&v.Real)
277 ad.Mul(&rv.Imag)
278
279 v.Real.Set(&ac)
280 v.Real.Sub(&bd)
281
282 v.Imag.Set(&bc)
283 v.Imag.Add(&ad)
284 }
285
286
287
288 func (v *Mpcplx) Div(rv *Mpcplx) bool {
289 if rv.Real.CmpFloat64(0) == 0 && rv.Imag.CmpFloat64(0) == 0 {
290 return false
291 }
292
293 var ac, ad, bc, bd, cc_plus_dd Mpflt
294
295 cc_plus_dd.Set(&rv.Real)
296 cc_plus_dd.Mul(&rv.Real)
297
298 ac.Set(&rv.Imag)
299 ac.Mul(&rv.Imag)
300 cc_plus_dd.Add(&ac)
301
302
303
304
305
306 if cc_plus_dd.CmpFloat64(0) == 0 {
307 return false
308 }
309
310 ac.Set(&v.Real)
311 ac.Mul(&rv.Real)
312
313 bd.Set(&v.Imag)
314 bd.Mul(&rv.Imag)
315
316 bc.Set(&v.Imag)
317 bc.Mul(&rv.Real)
318
319 ad.Set(&v.Real)
320 ad.Mul(&rv.Imag)
321
322 v.Real.Set(&ac)
323 v.Real.Add(&bd)
324 v.Real.Quo(&cc_plus_dd)
325
326 v.Imag.Set(&bc)
327 v.Imag.Sub(&ad)
328 v.Imag.Quo(&cc_plus_dd)
329
330 return true
331 }
332
333 func (v *Mpcplx) String() string {
334 return fmt.Sprintf("(%s+%si)", v.Real.String(), v.Imag.String())
335 }
336
337 func (v *Mpcplx) GoString() string {
338 var re string
339 sre := v.Real.CmpFloat64(0)
340 if sre != 0 {
341 re = v.Real.GoString()
342 }
343
344 var im string
345 sim := v.Imag.CmpFloat64(0)
346 if sim != 0 {
347 im = v.Imag.GoString()
348 }
349
350 switch {
351 case sre == 0 && sim == 0:
352 return "0"
353 case sre == 0:
354 return im + "i"
355 case sim == 0:
356 return re
357 case sim < 0:
358 return fmt.Sprintf("(%s%si)", re, im)
359 default:
360 return fmt.Sprintf("(%s+%si)", re, im)
361 }
362 }
363
View as plain text