blob: 80253dd85c845662edf01c116312875a07335e22 [file] [log] [blame]
Russ Cox8c195bd2015-02-13 14:40:36 -05001// Copyright 2009 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 gc
6
7//
8// return the significant
9// words of the argument
10//
Robert Griesemer888767f2015-03-18 14:10:22 -070011func mplen(a *Mpfix) int {
Russ Cox382b44e2015-02-23 16:07:24 -050012 n := -1
13 for i := 0; i < Mpprec; i++ {
Russ Cox8c195bd2015-02-13 14:40:36 -050014 if a.A[i] != 0 {
15 n = i
16 }
17 }
18
19 return n + 1
20}
21
22//
23// left shift mpint by one
24// ignores sign
25//
Robert Griesemer888767f2015-03-18 14:10:22 -070026func mplsh(a *Mpfix, quiet int) {
Russ Cox8c195bd2015-02-13 14:40:36 -050027 var x int
Russ Cox8c195bd2015-02-13 14:40:36 -050028
Russ Cox382b44e2015-02-23 16:07:24 -050029 c := 0
30 for i := 0; i < Mpprec; i++ {
Russ Cox8c195bd2015-02-13 14:40:36 -050031 x = (a.A[i] << 1) + c
32 c = 0
33 if x >= Mpbase {
34 x -= Mpbase
35 c = 1
36 }
37
38 a.A[i] = x
39 }
40
41 a.Ovf = uint8(c)
Russ Coxdc7b54b2015-02-17 22:13:49 -050042 if a.Ovf != 0 && quiet == 0 {
Russ Cox8c195bd2015-02-13 14:40:36 -050043 Yyerror("constant shift overflow")
44 }
45}
46
47//
48// left shift mpint by Mpscale
49// ignores sign
50//
Robert Griesemer888767f2015-03-18 14:10:22 -070051func mplshw(a *Mpfix, quiet int) {
Russ Cox382b44e2015-02-23 16:07:24 -050052 i := Mpprec - 1
Russ Cox8c195bd2015-02-13 14:40:36 -050053 if a.A[i] != 0 {
54 a.Ovf = 1
Russ Coxdc7b54b2015-02-17 22:13:49 -050055 if quiet == 0 {
Russ Cox8c195bd2015-02-13 14:40:36 -050056 Yyerror("constant shift overflow")
57 }
58 }
59
60 for ; i > 0; i-- {
61 a.A[i] = a.A[i-1]
62 }
63 a.A[i] = 0
64}
65
66//
67// right shift mpint by one
68// ignores sign and overflow
69//
Robert Griesemer888767f2015-03-18 14:10:22 -070070func mprsh(a *Mpfix) {
Russ Cox8c195bd2015-02-13 14:40:36 -050071 var x int
Russ Cox8c195bd2015-02-13 14:40:36 -050072
Russ Cox382b44e2015-02-23 16:07:24 -050073 c := 0
74 lo := a.A[0] & 1
75 for i := Mpprec - 1; i >= 0; i-- {
Russ Cox8c195bd2015-02-13 14:40:36 -050076 x = a.A[i]
77 a.A[i] = (x + c) >> 1
78 c = 0
79 if x&1 != 0 {
80 c = Mpbase
81 }
82 }
83
84 if a.Neg != 0 && lo != 0 {
85 mpaddcfix(a, -1)
86 }
87}
88
89//
90// right shift mpint by Mpscale
91// ignores sign and overflow
92//
Robert Griesemer888767f2015-03-18 14:10:22 -070093func mprshw(a *Mpfix) {
Russ Cox8c195bd2015-02-13 14:40:36 -050094 var i int
95
Russ Cox382b44e2015-02-23 16:07:24 -050096 lo := a.A[0]
Russ Cox8c195bd2015-02-13 14:40:36 -050097 for i = 0; i < Mpprec-1; i++ {
98 a.A[i] = a.A[i+1]
99 }
100
101 a.A[i] = 0
102 if a.Neg != 0 && lo != 0 {
103 mpaddcfix(a, -1)
104 }
105}
106
107//
108// return the sign of (abs(a)-abs(b))
109//
Robert Griesemer888767f2015-03-18 14:10:22 -0700110func mpcmp(a *Mpfix, b *Mpfix) int {
Russ Cox8c195bd2015-02-13 14:40:36 -0500111 if a.Ovf != 0 || b.Ovf != 0 {
112 if nsavederrors+nerrors == 0 {
113 Yyerror("ovf in cmp")
114 }
115 return 0
116 }
117
Russ Cox382b44e2015-02-23 16:07:24 -0500118 var x int
119 for i := Mpprec - 1; i >= 0; i-- {
Russ Cox8c195bd2015-02-13 14:40:36 -0500120 x = a.A[i] - b.A[i]
121 if x > 0 {
122 return +1
123 }
124 if x < 0 {
125 return -1
126 }
127 }
128
129 return 0
130}
131
132//
133// negate a
134// ignore sign and ovf
135//
Robert Griesemer888767f2015-03-18 14:10:22 -0700136func mpneg(a *Mpfix) {
Russ Cox8c195bd2015-02-13 14:40:36 -0500137 var x int
Russ Cox8c195bd2015-02-13 14:40:36 -0500138
Russ Cox382b44e2015-02-23 16:07:24 -0500139 c := 0
140 for i := 0; i < Mpprec; i++ {
Russ Cox8c195bd2015-02-13 14:40:36 -0500141 x = -a.A[i] - c
142 c = 0
143 if x < 0 {
144 x += Mpbase
145 c = 1
146 }
147
148 a.A[i] = x
149 }
150}
151
Russ Cox8c195bd2015-02-13 14:40:36 -0500152func Mpshiftfix(a *Mpint, s int) {
Robert Griesemer888767f2015-03-18 14:10:22 -0700153 switch {
154 case s > 0:
155 if mptestovf(a, s) {
156 Yyerror("constant shift overflow")
157 return
158 }
159 a.Val.Lsh(&a.Val, uint(s))
160 case s < 0:
161 a.Val.Rsh(&a.Val, uint(-s))
162 }
163}
164
165// shift left by s (or right by -s)
166func _Mpshiftfix(a *Mpfix, s int) {
Russ Cox8c195bd2015-02-13 14:40:36 -0500167 if s >= 0 {
168 for s >= Mpscale {
169 mplshw(a, 0)
170 s -= Mpscale
171 }
172
173 for s > 0 {
174 mplsh(a, 0)
175 s--
176 }
177 } else {
178 s = -s
179 for s >= Mpscale {
180 mprshw(a)
181 s -= Mpscale
182 }
183
184 for s > 0 {
185 mprsh(a)
186 s--
187 }
188 }
189}
190
Robert Griesemer888767f2015-03-18 14:10:22 -0700191/// implements fix arithmetic
Russ Cox8c195bd2015-02-13 14:40:36 -0500192
Robert Griesemer888767f2015-03-18 14:10:22 -0700193func mpsetovf(a *Mpint) {
194 a.Val.SetUint64(0)
195 a.Ovf = true
196}
197
198func mptestovf(a *Mpint, extra int) bool {
199 // We don't need to be precise here, any reasonable upper limit would do.
200 // For now, use existing limit so we pass all the tests unchanged.
201 const limit = Mpscale * Mpprec
202 if a.Val.BitLen()+extra > limit {
203 mpsetovf(a)
204 }
205 return a.Ovf
206}
207
208func mpaddfixfix(a, b *Mpint, quiet int) {
209 if a.Ovf || b.Ovf {
210 if nsavederrors+nerrors == 0 {
211 Yyerror("ovf in mpaddxx")
212 }
213 mpsetovf(a)
214 return
215 }
216
217 a.Val.Add(&a.Val, &b.Val)
218
219 if mptestovf(a, 0) && quiet == 0 {
220 Yyerror("constant addition overflow")
221 }
222}
223
224func _mpaddfixfix(a *Mpfix, b *Mpfix, quiet int) {
Russ Cox8c195bd2015-02-13 14:40:36 -0500225 if a.Ovf != 0 || b.Ovf != 0 {
226 if nsavederrors+nerrors == 0 {
227 Yyerror("ovf in mpaddxx")
228 }
229 a.Ovf = 1
230 return
231 }
232
Russ Cox382b44e2015-02-23 16:07:24 -0500233 c := 0
Russ Cox8c195bd2015-02-13 14:40:36 -0500234 if a.Neg != b.Neg {
Russ Cox79f727a2015-03-02 12:35:15 -0500235 // perform a-b
236 switch mpcmp(a, b) {
237 case 0:
Robert Griesemer888767f2015-03-18 14:10:22 -0700238 _Mpmovecfix(a, 0)
Russ Cox79f727a2015-03-02 12:35:15 -0500239
240 case 1:
241 var x int
242 for i := 0; i < Mpprec; i++ {
243 x = a.A[i] - b.A[i] - c
244 c = 0
245 if x < 0 {
246 x += Mpbase
247 c = 1
248 }
249
250 a.A[i] = x
251 }
252
253 case -1:
254 a.Neg ^= 1
255 var x int
256 for i := 0; i < Mpprec; i++ {
257 x = b.A[i] - a.A[i] - c
258 c = 0
259 if x < 0 {
260 x += Mpbase
261 c = 1
262 }
263
264 a.A[i] = x
265 }
266 }
267 return
Russ Cox8c195bd2015-02-13 14:40:36 -0500268 }
269
270 // perform a+b
Russ Cox79f727a2015-03-02 12:35:15 -0500271 var x int
Russ Cox382b44e2015-02-23 16:07:24 -0500272 for i := 0; i < Mpprec; i++ {
Russ Cox8c195bd2015-02-13 14:40:36 -0500273 x = a.A[i] + b.A[i] + c
274 c = 0
275 if x >= Mpbase {
276 x -= Mpbase
277 c = 1
278 }
279
280 a.A[i] = x
281 }
282
283 a.Ovf = uint8(c)
Russ Coxdc7b54b2015-02-17 22:13:49 -0500284 if a.Ovf != 0 && quiet == 0 {
Russ Cox8c195bd2015-02-13 14:40:36 -0500285 Yyerror("constant addition overflow")
286 }
287
288 return
Russ Cox8c195bd2015-02-13 14:40:36 -0500289}
290
Robert Griesemer888767f2015-03-18 14:10:22 -0700291func mpmulfixfix(a, b *Mpint) {
292 if a.Ovf || b.Ovf {
293 if nsavederrors+nerrors == 0 {
294 Yyerror("ovf in mpmulfixfix")
295 }
296 mpsetovf(a)
297 return
298 }
299
300 a.Val.Mul(&a.Val, &b.Val)
301
302 if mptestovf(a, 0) {
303 Yyerror("constant multiplication overflow")
304 }
305}
306
307func _mpmulfixfix(a *Mpfix, b *Mpfix) {
Russ Cox8c195bd2015-02-13 14:40:36 -0500308 if a.Ovf != 0 || b.Ovf != 0 {
309 if nsavederrors+nerrors == 0 {
310 Yyerror("ovf in mpmulfixfix")
311 }
312 a.Ovf = 1
313 return
314 }
315
316 // pick the smaller
317 // to test for bits
Russ Cox382b44e2015-02-23 16:07:24 -0500318 na := mplen(a)
Russ Cox8c195bd2015-02-13 14:40:36 -0500319
Russ Cox382b44e2015-02-23 16:07:24 -0500320 nb := mplen(b)
Robert Griesemer888767f2015-03-18 14:10:22 -0700321 var s Mpfix
322 var c *Mpfix
Russ Cox8c195bd2015-02-13 14:40:36 -0500323 if na > nb {
Robert Griesemer888767f2015-03-18 14:10:22 -0700324 _mpmovefixfix(&s, a)
Russ Cox8c195bd2015-02-13 14:40:36 -0500325 c = b
326 na = nb
327 } else {
Robert Griesemer888767f2015-03-18 14:10:22 -0700328 _mpmovefixfix(&s, b)
Russ Cox8c195bd2015-02-13 14:40:36 -0500329 c = a
330 }
331
332 s.Neg = 0
333
Robert Griesemer888767f2015-03-18 14:10:22 -0700334 var q Mpfix
335 _Mpmovecfix(&q, 0)
Russ Cox382b44e2015-02-23 16:07:24 -0500336 var j int
337 var x int
338 for i := 0; i < na; i++ {
Russ Cox8c195bd2015-02-13 14:40:36 -0500339 x = c.A[i]
340 for j = 0; j < Mpscale; j++ {
341 if x&1 != 0 {
342 if s.Ovf != 0 {
343 q.Ovf = 1
344 goto out
345 }
346
Robert Griesemer888767f2015-03-18 14:10:22 -0700347 _mpaddfixfix(&q, &s, 1)
Russ Cox8c195bd2015-02-13 14:40:36 -0500348 if q.Ovf != 0 {
349 goto out
350 }
351 }
352
353 mplsh(&s, 1)
354 x >>= 1
355 }
356 }
357
358out:
359 q.Neg = a.Neg ^ b.Neg
Robert Griesemer888767f2015-03-18 14:10:22 -0700360 _mpmovefixfix(a, &q)
Russ Cox8c195bd2015-02-13 14:40:36 -0500361 if a.Ovf != 0 {
362 Yyerror("constant multiplication overflow")
363 }
364}
365
Robert Griesemer888767f2015-03-18 14:10:22 -0700366func mpmulfract(a *Mpfix, b *Mpfix) {
Russ Cox8c195bd2015-02-13 14:40:36 -0500367 if a.Ovf != 0 || b.Ovf != 0 {
368 if nsavederrors+nerrors == 0 {
369 Yyerror("ovf in mpmulflt")
370 }
371 a.Ovf = 1
372 return
373 }
374
Robert Griesemer888767f2015-03-18 14:10:22 -0700375 var s Mpfix
376 _mpmovefixfix(&s, b)
Russ Cox8c195bd2015-02-13 14:40:36 -0500377 s.Neg = 0
Robert Griesemer888767f2015-03-18 14:10:22 -0700378 var q Mpfix
379 _Mpmovecfix(&q, 0)
Russ Cox8c195bd2015-02-13 14:40:36 -0500380
Russ Cox382b44e2015-02-23 16:07:24 -0500381 i := Mpprec - 1
382 x := a.A[i]
Russ Cox8c195bd2015-02-13 14:40:36 -0500383 if x != 0 {
384 Yyerror("mpmulfract not normal")
385 }
386
Russ Cox382b44e2015-02-23 16:07:24 -0500387 var j int
Russ Cox8c195bd2015-02-13 14:40:36 -0500388 for i--; i >= 0; i-- {
389 x = a.A[i]
390 if x == 0 {
391 mprshw(&s)
392 continue
393 }
394
395 for j = 0; j < Mpscale; j++ {
396 x <<= 1
397 if x&Mpbase != 0 {
Robert Griesemer888767f2015-03-18 14:10:22 -0700398 _mpaddfixfix(&q, &s, 1)
Russ Cox8c195bd2015-02-13 14:40:36 -0500399 }
400 mprsh(&s)
401 }
402 }
403
404 q.Neg = a.Neg ^ b.Neg
Robert Griesemer888767f2015-03-18 14:10:22 -0700405 _mpmovefixfix(a, &q)
Russ Cox8c195bd2015-02-13 14:40:36 -0500406 if a.Ovf != 0 {
407 Yyerror("constant multiplication overflow")
408 }
409}
410
Robert Griesemer888767f2015-03-18 14:10:22 -0700411func mporfixfix(a, b *Mpint) {
412 if a.Ovf || b.Ovf {
413 if nsavederrors+nerrors == 0 {
414 Yyerror("ovf in mporfixfix")
415 }
416 mpsetovf(a)
417 return
418 }
419
420 a.Val.Or(&a.Val, &b.Val)
421}
422
Robert Griesemer888767f2015-03-18 14:10:22 -0700423func mpandfixfix(a, b *Mpint) {
424 if a.Ovf || b.Ovf {
425 if nsavederrors+nerrors == 0 {
426 Yyerror("ovf in mpandfixfix")
427 }
428 mpsetovf(a)
429 return
430 }
431
432 a.Val.And(&a.Val, &b.Val)
433}
434
Robert Griesemer888767f2015-03-18 14:10:22 -0700435func mpandnotfixfix(a, b *Mpint) {
436 if a.Ovf || b.Ovf {
437 if nsavederrors+nerrors == 0 {
438 Yyerror("ovf in mpandnotfixfix")
439 }
440 mpsetovf(a)
441 return
442 }
443
444 a.Val.AndNot(&a.Val, &b.Val)
445}
446
Robert Griesemer888767f2015-03-18 14:10:22 -0700447func mpxorfixfix(a, b *Mpint) {
448 if a.Ovf || b.Ovf {
449 if nsavederrors+nerrors == 0 {
450 Yyerror("ovf in mpxorfixfix")
451 }
452 mpsetovf(a)
453 return
454 }
455
456 a.Val.Xor(&a.Val, &b.Val)
457}
458
Robert Griesemer888767f2015-03-18 14:10:22 -0700459func mplshfixfix(a, b *Mpint) {
460 if a.Ovf || b.Ovf {
Russ Cox8c195bd2015-02-13 14:40:36 -0500461 if nsavederrors+nerrors == 0 {
Robert Griesemer888767f2015-03-18 14:10:22 -0700462 Yyerror("ovf in mplshfixfix")
Russ Cox8c195bd2015-02-13 14:40:36 -0500463 }
Robert Griesemer888767f2015-03-18 14:10:22 -0700464 mpsetovf(a)
Russ Cox8c195bd2015-02-13 14:40:36 -0500465 return
466 }
467
Russ Cox382b44e2015-02-23 16:07:24 -0500468 s := Mpgetfix(b)
Russ Cox8c195bd2015-02-13 14:40:36 -0500469 if s < 0 || s >= Mpprec*Mpscale {
470 Yyerror("stupid shift: %d", s)
471 Mpmovecfix(a, 0)
472 return
473 }
474
475 Mpshiftfix(a, int(s))
476}
477
Robert Griesemer888767f2015-03-18 14:10:22 -0700478func mprshfixfix(a, b *Mpint) {
479 if a.Ovf || b.Ovf {
480 if nsavederrors+nerrors == 0 {
Russ Cox8c195bd2015-02-13 14:40:36 -0500481 Yyerror("ovf in mprshfixfix")
482 }
Robert Griesemer888767f2015-03-18 14:10:22 -0700483 mpsetovf(a)
Russ Cox8c195bd2015-02-13 14:40:36 -0500484 return
485 }
486
Russ Cox382b44e2015-02-23 16:07:24 -0500487 s := Mpgetfix(b)
Russ Cox8c195bd2015-02-13 14:40:36 -0500488 if s < 0 || s >= Mpprec*Mpscale {
489 Yyerror("stupid shift: %d", s)
Robert Griesemer888767f2015-03-18 14:10:22 -0700490 if a.Val.Sign() < 0 {
Russ Cox8c195bd2015-02-13 14:40:36 -0500491 Mpmovecfix(a, -1)
492 } else {
493 Mpmovecfix(a, 0)
494 }
495 return
496 }
497
498 Mpshiftfix(a, int(-s))
499}
500
501func mpnegfix(a *Mpint) {
Robert Griesemer888767f2015-03-18 14:10:22 -0700502 a.Val.Neg(&a.Val)
503}
504
505func _mpnegfix(a *Mpfix) {
Russ Cox8c195bd2015-02-13 14:40:36 -0500506 a.Neg ^= 1
507}
508
509func Mpgetfix(a *Mpint) int64 {
Robert Griesemer888767f2015-03-18 14:10:22 -0700510 if a.Ovf {
511 if nsavederrors+nerrors == 0 {
512 Yyerror("constant overflow")
513 }
514 return 0
515 }
516
517 return a.Val.Int64()
518}
519
520func _Mpgetfix(a *Mpfix) int64 {
Russ Cox8c195bd2015-02-13 14:40:36 -0500521 if a.Ovf != 0 {
522 if nsavederrors+nerrors == 0 {
523 Yyerror("constant overflow")
524 }
525 return 0
526 }
527
Russ Cox382b44e2015-02-23 16:07:24 -0500528 v := int64(uint64(a.A[0]))
Russ Cox8c195bd2015-02-13 14:40:36 -0500529 v |= int64(uint64(a.A[1]) << Mpscale)
530 v |= int64(uint64(a.A[2]) << (Mpscale + Mpscale))
531 if a.Neg != 0 {
532 v = int64(-uint64(v))
533 }
534 return v
535}
536
537func Mpmovecfix(a *Mpint, c int64) {
Robert Griesemer888767f2015-03-18 14:10:22 -0700538 a.Val.SetInt64(c)
539}
540
541func _Mpmovecfix(a *Mpfix, c int64) {
Russ Cox8c195bd2015-02-13 14:40:36 -0500542 a.Neg = 0
543 a.Ovf = 0
544
Russ Cox382b44e2015-02-23 16:07:24 -0500545 x := c
Russ Cox8c195bd2015-02-13 14:40:36 -0500546 if x < 0 {
547 a.Neg = 1
548 x = int64(-uint64(x))
549 }
550
Russ Cox382b44e2015-02-23 16:07:24 -0500551 for i := 0; i < Mpprec; i++ {
Russ Cox8c195bd2015-02-13 14:40:36 -0500552 a.A[i] = int(x & Mpmask)
553 x >>= Mpscale
554 }
555}
556
Robert Griesemer888767f2015-03-18 14:10:22 -0700557func mpdivmodfixfix(q *Mpfix, r *Mpfix, n *Mpfix, d *Mpfix) {
Russ Cox8c195bd2015-02-13 14:40:36 -0500558 var i int
Russ Cox8c195bd2015-02-13 14:40:36 -0500559
Russ Cox382b44e2015-02-23 16:07:24 -0500560 ns := int(n.Neg)
561 ds := int(d.Neg)
Russ Cox8c195bd2015-02-13 14:40:36 -0500562 n.Neg = 0
563 d.Neg = 0
564
Robert Griesemer888767f2015-03-18 14:10:22 -0700565 _mpmovefixfix(r, n)
566 _Mpmovecfix(q, 0)
Russ Cox8c195bd2015-02-13 14:40:36 -0500567
568 // shift denominator until it
569 // is larger than numerator
570 for i = 0; i < Mpprec*Mpscale; i++ {
571 if mpcmp(d, r) > 0 {
572 break
573 }
574 mplsh(d, 1)
575 }
576
577 // if it never happens
578 // denominator is probably zero
579 if i >= Mpprec*Mpscale {
580 q.Ovf = 1
581 r.Ovf = 1
582 n.Neg = uint8(ns)
583 d.Neg = uint8(ds)
584 Yyerror("constant division overflow")
585 return
586 }
587
588 // shift denominator back creating
589 // quotient a bit at a time
590 // when done the remaining numerator
591 // will be the remainder
592 for ; i > 0; i-- {
593 mplsh(q, 1)
594 mprsh(d)
595 if mpcmp(d, r) <= 0 {
596 mpaddcfix(q, 1)
Robert Griesemer888767f2015-03-18 14:10:22 -0700597 _mpsubfixfix(r, d)
Russ Cox8c195bd2015-02-13 14:40:36 -0500598 }
599 }
600
601 n.Neg = uint8(ns)
602 d.Neg = uint8(ds)
603 r.Neg = uint8(ns)
604 q.Neg = uint8(ns ^ ds)
605}
606
Robert Griesemer888767f2015-03-18 14:10:22 -0700607func mpiszero(a *Mpfix) bool {
Russ Cox382b44e2015-02-23 16:07:24 -0500608 for i := Mpprec - 1; i >= 0; i-- {
Russ Cox8c195bd2015-02-13 14:40:36 -0500609 if a.A[i] != 0 {
Russ Coxdc7b54b2015-02-17 22:13:49 -0500610 return false
Russ Cox8c195bd2015-02-13 14:40:36 -0500611 }
612 }
Russ Coxdc7b54b2015-02-17 22:13:49 -0500613 return true
Russ Cox8c195bd2015-02-13 14:40:36 -0500614}
615
Robert Griesemer888767f2015-03-18 14:10:22 -0700616func mpdivfract(a *Mpfix, b *Mpfix) {
617 var n Mpfix
618 var d Mpfix
Russ Cox8c195bd2015-02-13 14:40:36 -0500619 var j int
Russ Cox8c195bd2015-02-13 14:40:36 -0500620 var x int
621
Robert Griesemer888767f2015-03-18 14:10:22 -0700622 _mpmovefixfix(&n, a) // numerator
623 _mpmovefixfix(&d, b) // denominator
Russ Cox8c195bd2015-02-13 14:40:36 -0500624
Russ Cox382b44e2015-02-23 16:07:24 -0500625 neg := int(n.Neg) ^ int(d.Neg)
Russ Cox8c195bd2015-02-13 14:40:36 -0500626
627 n.Neg = 0
628 d.Neg = 0
Russ Cox382b44e2015-02-23 16:07:24 -0500629 for i := Mpprec - 1; i >= 0; i-- {
Russ Cox8c195bd2015-02-13 14:40:36 -0500630 x = 0
631 for j = 0; j < Mpscale; j++ {
632 x <<= 1
633 if mpcmp(&d, &n) <= 0 {
Russ Coxdc7b54b2015-02-17 22:13:49 -0500634 if !mpiszero(&d) {
Russ Cox8c195bd2015-02-13 14:40:36 -0500635 x |= 1
636 }
Robert Griesemer888767f2015-03-18 14:10:22 -0700637 _mpsubfixfix(&n, &d)
Russ Cox8c195bd2015-02-13 14:40:36 -0500638 }
639
640 mprsh(&d)
641 }
642
643 a.A[i] = x
644 }
645
646 a.Neg = uint8(neg)
647}
648
Robert Griesemer888767f2015-03-18 14:10:22 -0700649func mptestfix(a *Mpfix) int {
650 var b Mpfix
Russ Cox8c195bd2015-02-13 14:40:36 -0500651
Robert Griesemer888767f2015-03-18 14:10:22 -0700652 _Mpmovecfix(&b, 0)
Russ Cox382b44e2015-02-23 16:07:24 -0500653 r := mpcmp(a, &b)
Russ Cox8c195bd2015-02-13 14:40:36 -0500654 if a.Neg != 0 {
655 if r > 0 {
656 return -1
657 }
658 if r < 0 {
659 return +1
660 }
661 }
662
663 return r
664}