~john-koepi/ubuntu/trusty/golang/default

« back to all changes in this revision

Viewing changes to src/pkg/big/int.go

  • Committer: Bazaar Package Importer
  • Author(s): Ondřej Surý
  • Date: 2011-04-20 17:36:48 UTC
  • Revision ID: james.westby@ubuntu.com-20110420173648-ifergoxyrm832trd
Tags: upstream-2011.03.07.1
Import upstream version 2011.03.07.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// 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
 
 
5
// This file implements signed multi-precision integers.
 
6
 
 
7
package big
 
8
 
 
9
import (
 
10
        "fmt"
 
11
        "rand"
 
12
)
 
13
 
 
14
// An Int represents a signed multi-precision integer.
 
15
// The zero value for an Int represents the value 0.
 
16
type Int struct {
 
17
        neg bool // sign
 
18
        abs nat  // absolute value of the integer
 
19
}
 
20
 
 
21
 
 
22
var intOne = &Int{false, natOne}
 
23
 
 
24
 
 
25
// Sign returns:
 
26
//
 
27
//      -1 if x <  0
 
28
//       0 if x == 0
 
29
//      +1 if x >  0
 
30
//
 
31
func (x *Int) Sign() int {
 
32
        if len(x.abs) == 0 {
 
33
                return 0
 
34
        }
 
35
        if x.neg {
 
36
                return -1
 
37
        }
 
38
        return 1
 
39
}
 
40
 
 
41
 
 
42
// SetInt64 sets z to x and returns z.
 
43
func (z *Int) SetInt64(x int64) *Int {
 
44
        neg := false
 
45
        if x < 0 {
 
46
                neg = true
 
47
                x = -x
 
48
        }
 
49
        z.abs = z.abs.setUint64(uint64(x))
 
50
        z.neg = neg
 
51
        return z
 
52
}
 
53
 
 
54
 
 
55
// NewInt allocates and returns a new Int set to x.
 
56
func NewInt(x int64) *Int {
 
57
        return new(Int).SetInt64(x)
 
58
}
 
59
 
 
60
 
 
61
// Set sets z to x and returns z.
 
62
func (z *Int) Set(x *Int) *Int {
 
63
        z.abs = z.abs.set(x.abs)
 
64
        z.neg = x.neg
 
65
        return z
 
66
}
 
67
 
 
68
 
 
69
// Abs sets z to |x| (the absolute value of x) and returns z.
 
70
func (z *Int) Abs(x *Int) *Int {
 
71
        z.abs = z.abs.set(x.abs)
 
72
        z.neg = false
 
73
        return z
 
74
}
 
75
 
 
76
 
 
77
// Neg sets z to -x and returns z.
 
78
func (z *Int) Neg(x *Int) *Int {
 
79
        z.abs = z.abs.set(x.abs)
 
80
        z.neg = len(z.abs) > 0 && !x.neg // 0 has no sign
 
81
        return z
 
82
}
 
83
 
 
84
 
 
85
// Add sets z to the sum x+y and returns z.
 
86
func (z *Int) Add(x, y *Int) *Int {
 
87
        neg := x.neg
 
88
        if x.neg == y.neg {
 
89
                // x + y == x + y
 
90
                // (-x) + (-y) == -(x + y)
 
91
                z.abs = z.abs.add(x.abs, y.abs)
 
92
        } else {
 
93
                // x + (-y) == x - y == -(y - x)
 
94
                // (-x) + y == y - x == -(x - y)
 
95
                if x.abs.cmp(y.abs) >= 0 {
 
96
                        z.abs = z.abs.sub(x.abs, y.abs)
 
97
                } else {
 
98
                        neg = !neg
 
99
                        z.abs = z.abs.sub(y.abs, x.abs)
 
100
                }
 
101
        }
 
102
        z.neg = len(z.abs) > 0 && neg // 0 has no sign
 
103
        return z
 
104
}
 
105
 
 
106
 
 
107
// Sub sets z to the difference x-y and returns z.
 
108
func (z *Int) Sub(x, y *Int) *Int {
 
109
        neg := x.neg
 
110
        if x.neg != y.neg {
 
111
                // x - (-y) == x + y
 
112
                // (-x) - y == -(x + y)
 
113
                z.abs = z.abs.add(x.abs, y.abs)
 
114
        } else {
 
115
                // x - y == x - y == -(y - x)
 
116
                // (-x) - (-y) == y - x == -(x - y)
 
117
                if x.abs.cmp(y.abs) >= 0 {
 
118
                        z.abs = z.abs.sub(x.abs, y.abs)
 
119
                } else {
 
120
                        neg = !neg
 
121
                        z.abs = z.abs.sub(y.abs, x.abs)
 
122
                }
 
123
        }
 
124
        z.neg = len(z.abs) > 0 && neg // 0 has no sign
 
125
        return z
 
126
}
 
127
 
 
128
 
 
129
// Mul sets z to the product x*y and returns z.
 
130
func (z *Int) Mul(x, y *Int) *Int {
 
131
        // x * y == x * y
 
132
        // x * (-y) == -(x * y)
 
133
        // (-x) * y == -(x * y)
 
134
        // (-x) * (-y) == x * y
 
135
        z.abs = z.abs.mul(x.abs, y.abs)
 
136
        z.neg = len(z.abs) > 0 && x.neg != y.neg // 0 has no sign
 
137
        return z
 
138
}
 
139
 
 
140
 
 
141
// MulRange sets z to the product of all integers
 
142
// in the range [a, b] inclusively and returns z.
 
143
// If a > b (empty range), the result is 1.
 
144
func (z *Int) MulRange(a, b int64) *Int {
 
145
        switch {
 
146
        case a > b:
 
147
                return z.SetInt64(1) // empty range
 
148
        case a <= 0 && b >= 0:
 
149
                return z.SetInt64(0) // range includes 0
 
150
        }
 
151
        // a <= b && (b < 0 || a > 0)
 
152
 
 
153
        neg := false
 
154
        if a < 0 {
 
155
                neg = (b-a)&1 == 0
 
156
                a, b = -b, -a
 
157
        }
 
158
 
 
159
        z.abs = z.abs.mulRange(uint64(a), uint64(b))
 
160
        z.neg = neg
 
161
        return z
 
162
}
 
163
 
 
164
 
 
165
// Binomial sets z to the binomial coefficient of (n, k) and returns z.
 
166
func (z *Int) Binomial(n, k int64) *Int {
 
167
        var a, b Int
 
168
        a.MulRange(n-k+1, n)
 
169
        b.MulRange(1, k)
 
170
        return z.Quo(&a, &b)
 
171
}
 
172
 
 
173
 
 
174
// Quo sets z to the quotient x/y for y != 0 and returns z.
 
175
// If y == 0, a division-by-zero run-time panic occurs.
 
176
// See QuoRem for more details.
 
177
func (z *Int) Quo(x, y *Int) *Int {
 
178
        z.abs, _ = z.abs.div(nil, x.abs, y.abs)
 
179
        z.neg = len(z.abs) > 0 && x.neg != y.neg // 0 has no sign
 
180
        return z
 
181
}
 
182
 
 
183
 
 
184
// Rem sets z to the remainder x%y for y != 0 and returns z.
 
185
// If y == 0, a division-by-zero run-time panic occurs.
 
186
// See QuoRem for more details.
 
187
func (z *Int) Rem(x, y *Int) *Int {
 
188
        _, z.abs = nat(nil).div(z.abs, x.abs, y.abs)
 
189
        z.neg = len(z.abs) > 0 && x.neg // 0 has no sign
 
190
        return z
 
191
}
 
192
 
 
193
 
 
194
// QuoRem sets z to the quotient x/y and r to the remainder x%y
 
195
// and returns the pair (z, r) for y != 0.
 
196
// If y == 0, a division-by-zero run-time panic occurs.
 
197
//
 
198
// QuoRem implements T-division and modulus (like Go):
 
199
//
 
200
//      q = x/y      with the result truncated to zero
 
201
//      r = x - y*q
 
202
//
 
203
// (See Daan Leijen, ``Division and Modulus for Computer Scientists''.)
 
204
//
 
205
func (z *Int) QuoRem(x, y, r *Int) (*Int, *Int) {
 
206
        z.abs, r.abs = z.abs.div(r.abs, x.abs, y.abs)
 
207
        z.neg, r.neg = len(z.abs) > 0 && x.neg != y.neg, len(r.abs) > 0 && x.neg // 0 has no sign
 
208
        return z, r
 
209
}
 
210
 
 
211
 
 
212
// Div sets z to the quotient x/y for y != 0 and returns z.
 
213
// If y == 0, a division-by-zero run-time panic occurs.
 
214
// See DivMod for more details.
 
215
func (z *Int) Div(x, y *Int) *Int {
 
216
        y_neg := y.neg // z may be an alias for y
 
217
        var r Int
 
218
        z.QuoRem(x, y, &r)
 
219
        if r.neg {
 
220
                if y_neg {
 
221
                        z.Add(z, intOne)
 
222
                } else {
 
223
                        z.Sub(z, intOne)
 
224
                }
 
225
        }
 
226
        return z
 
227
}
 
228
 
 
229
 
 
230
// Mod sets z to the modulus x%y for y != 0 and returns z.
 
231
// If y == 0, a division-by-zero run-time panic occurs.
 
232
// See DivMod for more details.
 
233
func (z *Int) Mod(x, y *Int) *Int {
 
234
        y0 := y // save y
 
235
        if z == y || alias(z.abs, y.abs) {
 
236
                y0 = new(Int).Set(y)
 
237
        }
 
238
        var q Int
 
239
        q.QuoRem(x, y, z)
 
240
        if z.neg {
 
241
                if y0.neg {
 
242
                        z.Sub(z, y0)
 
243
                } else {
 
244
                        z.Add(z, y0)
 
245
                }
 
246
        }
 
247
        return z
 
248
}
 
249
 
 
250
 
 
251
// DivMod sets z to the quotient x div y and m to the modulus x mod y
 
252
// and returns the pair (z, m) for y != 0.
 
253
// If y == 0, a division-by-zero run-time panic occurs.
 
254
//
 
255
// DivMod implements Euclidean division and modulus (unlike Go):
 
256
//
 
257
//      q = x div y  such that
 
258
//      m = x - y*q  with 0 <= m < |q|
 
259
//
 
260
// (See Raymond T. Boute, ``The Euclidean definition of the functions
 
261
// div and mod''. ACM Transactions on Programming Languages and
 
262
// Systems (TOPLAS), 14(2):127-144, New York, NY, USA, 4/1992.
 
263
// ACM press.)
 
264
//
 
265
func (z *Int) DivMod(x, y, m *Int) (*Int, *Int) {
 
266
        y0 := y // save y
 
267
        if z == y || alias(z.abs, y.abs) {
 
268
                y0 = new(Int).Set(y)
 
269
        }
 
270
        z.QuoRem(x, y, m)
 
271
        if m.neg {
 
272
                if y0.neg {
 
273
                        z.Add(z, intOne)
 
274
                        m.Sub(m, y0)
 
275
                } else {
 
276
                        z.Sub(z, intOne)
 
277
                        m.Add(m, y0)
 
278
                }
 
279
        }
 
280
        return z, m
 
281
}
 
282
 
 
283
 
 
284
// Cmp compares x and y and returns:
 
285
//
 
286
//   -1 if x <  y
 
287
//    0 if x == y
 
288
//   +1 if x >  y
 
289
//
 
290
func (x *Int) Cmp(y *Int) (r int) {
 
291
        // x cmp y == x cmp y
 
292
        // x cmp (-y) == x
 
293
        // (-x) cmp y == y
 
294
        // (-x) cmp (-y) == -(x cmp y)
 
295
        switch {
 
296
        case x.neg == y.neg:
 
297
                r = x.abs.cmp(y.abs)
 
298
                if x.neg {
 
299
                        r = -r
 
300
                }
 
301
        case x.neg:
 
302
                r = -1
 
303
        default:
 
304
                r = 1
 
305
        }
 
306
        return
 
307
}
 
308
 
 
309
 
 
310
func (x *Int) String() string {
 
311
        s := ""
 
312
        if x.neg {
 
313
                s = "-"
 
314
        }
 
315
        return s + x.abs.string(10)
 
316
}
 
317
 
 
318
 
 
319
func fmtbase(ch int) int {
 
320
        switch ch {
 
321
        case 'b':
 
322
                return 2
 
323
        case 'o':
 
324
                return 8
 
325
        case 'd':
 
326
                return 10
 
327
        case 'x':
 
328
                return 16
 
329
        }
 
330
        return 10
 
331
}
 
332
 
 
333
 
 
334
// Format is a support routine for fmt.Formatter. It accepts
 
335
// the formats 'b' (binary), 'o' (octal), 'd' (decimal) and
 
336
// 'x' (hexadecimal).
 
337
//
 
338
func (x *Int) Format(s fmt.State, ch int) {
 
339
        if x.neg {
 
340
                fmt.Fprint(s, "-")
 
341
        }
 
342
        fmt.Fprint(s, x.abs.string(fmtbase(ch)))
 
343
}
 
344
 
 
345
 
 
346
// Int64 returns the int64 representation of z.
 
347
// If z cannot be represented in an int64, the result is undefined.
 
348
func (x *Int) Int64() int64 {
 
349
        if len(x.abs) == 0 {
 
350
                return 0
 
351
        }
 
352
        v := int64(x.abs[0])
 
353
        if _W == 32 && len(x.abs) > 1 {
 
354
                v |= int64(x.abs[1]) << 32
 
355
        }
 
356
        if x.neg {
 
357
                v = -v
 
358
        }
 
359
        return v
 
360
}
 
361
 
 
362
 
 
363
// SetString sets z to the value of s, interpreted in the given base,
 
364
// and returns z and a boolean indicating success. If SetString fails,
 
365
// the value of z is undefined.
 
366
//
 
367
// If the base argument is 0, the string prefix determines the actual
 
368
// conversion base. A prefix of ``0x'' or ``0X'' selects base 16; the
 
369
// ``0'' prefix selects base 8, and a ``0b'' or ``0B'' prefix selects
 
370
// base 2. Otherwise the selected base is 10.
 
371
//
 
372
func (z *Int) SetString(s string, base int) (*Int, bool) {
 
373
        if len(s) == 0 || base < 0 || base == 1 || 16 < base {
 
374
                return z, false
 
375
        }
 
376
 
 
377
        neg := s[0] == '-'
 
378
        if neg || s[0] == '+' {
 
379
                s = s[1:]
 
380
                if len(s) == 0 {
 
381
                        return z, false
 
382
                }
 
383
        }
 
384
 
 
385
        var scanned int
 
386
        z.abs, _, scanned = z.abs.scan(s, base)
 
387
        if scanned != len(s) {
 
388
                return z, false
 
389
        }
 
390
        z.neg = len(z.abs) > 0 && neg // 0 has no sign
 
391
 
 
392
        return z, true
 
393
}
 
394
 
 
395
 
 
396
// SetBytes interprets b as the bytes of a big-endian, unsigned integer and
 
397
// sets z to that value.
 
398
func (z *Int) SetBytes(b []byte) *Int {
 
399
        const s = _S
 
400
        z.abs = z.abs.make((len(b) + s - 1) / s)
 
401
 
 
402
        j := 0
 
403
        for len(b) >= s {
 
404
                var w Word
 
405
 
 
406
                for i := s; i > 0; i-- {
 
407
                        w <<= 8
 
408
                        w |= Word(b[len(b)-i])
 
409
                }
 
410
 
 
411
                z.abs[j] = w
 
412
                j++
 
413
                b = b[0 : len(b)-s]
 
414
        }
 
415
 
 
416
        if len(b) > 0 {
 
417
                var w Word
 
418
 
 
419
                for i := len(b); i > 0; i-- {
 
420
                        w <<= 8
 
421
                        w |= Word(b[len(b)-i])
 
422
                }
 
423
 
 
424
                z.abs[j] = w
 
425
        }
 
426
 
 
427
        z.abs = z.abs.norm()
 
428
        z.neg = false
 
429
        return z
 
430
}
 
431
 
 
432
 
 
433
// Bytes returns the absolute value of x as a big-endian byte array.
 
434
func (z *Int) Bytes() []byte {
 
435
        const s = _S
 
436
        b := make([]byte, len(z.abs)*s)
 
437
 
 
438
        for i, w := range z.abs {
 
439
                wordBytes := b[(len(z.abs)-i-1)*s : (len(z.abs)-i)*s]
 
440
                for j := s - 1; j >= 0; j-- {
 
441
                        wordBytes[j] = byte(w)
 
442
                        w >>= 8
 
443
                }
 
444
        }
 
445
 
 
446
        i := 0
 
447
        for i < len(b) && b[i] == 0 {
 
448
                i++
 
449
        }
 
450
 
 
451
        return b[i:]
 
452
}
 
453
 
 
454
 
 
455
// BitLen returns the length of the absolute value of z in bits.
 
456
// The bit length of 0 is 0.
 
457
func (z *Int) BitLen() int {
 
458
        return z.abs.bitLen()
 
459
}
 
460
 
 
461
 
 
462
// Exp sets z = x**y mod m. If m is nil, z = x**y.
 
463
// See Knuth, volume 2, section 4.6.3.
 
464
func (z *Int) Exp(x, y, m *Int) *Int {
 
465
        if y.neg || len(y.abs) == 0 {
 
466
                neg := x.neg
 
467
                z.SetInt64(1)
 
468
                z.neg = neg
 
469
                return z
 
470
        }
 
471
 
 
472
        var mWords nat
 
473
        if m != nil {
 
474
                mWords = m.abs
 
475
        }
 
476
 
 
477
        z.abs = z.abs.expNN(x.abs, y.abs, mWords)
 
478
        z.neg = len(z.abs) > 0 && x.neg && y.abs[0]&1 == 1 // 0 has no sign
 
479
        return z
 
480
}
 
481
 
 
482
 
 
483
// GcdInt sets d to the greatest common divisor of a and b, which must be
 
484
// positive numbers.
 
485
// If x and y are not nil, GcdInt sets x and y such that d = a*x + b*y.
 
486
// If either a or b is not positive, GcdInt sets d = x = y = 0.
 
487
func GcdInt(d, x, y, a, b *Int) {
 
488
        if a.neg || b.neg {
 
489
                d.SetInt64(0)
 
490
                if x != nil {
 
491
                        x.SetInt64(0)
 
492
                }
 
493
                if y != nil {
 
494
                        y.SetInt64(0)
 
495
                }
 
496
                return
 
497
        }
 
498
 
 
499
        A := new(Int).Set(a)
 
500
        B := new(Int).Set(b)
 
501
 
 
502
        X := new(Int)
 
503
        Y := new(Int).SetInt64(1)
 
504
 
 
505
        lastX := new(Int).SetInt64(1)
 
506
        lastY := new(Int)
 
507
 
 
508
        q := new(Int)
 
509
        temp := new(Int)
 
510
 
 
511
        for len(B.abs) > 0 {
 
512
                r := new(Int)
 
513
                q, r = q.QuoRem(A, B, r)
 
514
 
 
515
                A, B = B, r
 
516
 
 
517
                temp.Set(X)
 
518
                X.Mul(X, q)
 
519
                X.neg = !X.neg
 
520
                X.Add(X, lastX)
 
521
                lastX.Set(temp)
 
522
 
 
523
                temp.Set(Y)
 
524
                Y.Mul(Y, q)
 
525
                Y.neg = !Y.neg
 
526
                Y.Add(Y, lastY)
 
527
                lastY.Set(temp)
 
528
        }
 
529
 
 
530
        if x != nil {
 
531
                *x = *lastX
 
532
        }
 
533
 
 
534
        if y != nil {
 
535
                *y = *lastY
 
536
        }
 
537
 
 
538
        *d = *A
 
539
}
 
540
 
 
541
 
 
542
// ProbablyPrime performs n Miller-Rabin tests to check whether z is prime.
 
543
// If it returns true, z is prime with probability 1 - 1/4^n.
 
544
// If it returns false, z is not prime.
 
545
func ProbablyPrime(z *Int, n int) bool {
 
546
        return !z.neg && z.abs.probablyPrime(n)
 
547
}
 
548
 
 
549
 
 
550
// Rand sets z to a pseudo-random number in [0, n) and returns z. 
 
551
func (z *Int) Rand(rnd *rand.Rand, n *Int) *Int {
 
552
        z.neg = false
 
553
        if n.neg == true || len(n.abs) == 0 {
 
554
                z.abs = nil
 
555
                return z
 
556
        }
 
557
        z.abs = z.abs.random(rnd, n.abs, n.abs.bitLen())
 
558
        return z
 
559
}
 
560
 
 
561
 
 
562
// ModInverse sets z to the multiplicative inverse of g in the group ℤ/pℤ (where
 
563
// p is a prime) and returns z.
 
564
func (z *Int) ModInverse(g, p *Int) *Int {
 
565
        var d Int
 
566
        GcdInt(&d, z, nil, g, p)
 
567
        // x and y are such that g*x + p*y = d. Since p is prime, d = 1. Taking
 
568
        // that modulo p results in g*x = 1, therefore x is the inverse element.
 
569
        if z.neg {
 
570
                z.Add(z, p)
 
571
        }
 
572
        return z
 
573
}
 
574
 
 
575
 
 
576
// Lsh sets z = x << n and returns z.
 
577
func (z *Int) Lsh(x *Int, n uint) *Int {
 
578
        z.abs = z.abs.shl(x.abs, n)
 
579
        z.neg = x.neg
 
580
        return z
 
581
}
 
582
 
 
583
 
 
584
// Rsh sets z = x >> n and returns z.
 
585
func (z *Int) Rsh(x *Int, n uint) *Int {
 
586
        if x.neg {
 
587
                // (-x) >> s == ^(x-1) >> s == ^((x-1) >> s) == -(((x-1) >> s) + 1)
 
588
                t := z.abs.sub(x.abs, natOne) // no underflow because |x| > 0
 
589
                t = t.shr(t, n)
 
590
                z.abs = t.add(t, natOne)
 
591
                z.neg = true // z cannot be zero if x is negative
 
592
                return z
 
593
        }
 
594
 
 
595
        z.abs = z.abs.shr(x.abs, n)
 
596
        z.neg = false
 
597
        return z
 
598
}
 
599
 
 
600
 
 
601
// And sets z = x & y and returns z.
 
602
func (z *Int) And(x, y *Int) *Int {
 
603
        if x.neg == y.neg {
 
604
                if x.neg {
 
605
                        // (-x) & (-y) == ^(x-1) & ^(y-1) == ^((x-1) | (y-1)) == -(((x-1) | (y-1)) + 1)
 
606
                        x1 := nat{}.sub(x.abs, natOne)
 
607
                        y1 := nat{}.sub(y.abs, natOne)
 
608
                        z.abs = z.abs.add(z.abs.or(x1, y1), natOne)
 
609
                        z.neg = true // z cannot be zero if x and y are negative
 
610
                        return z
 
611
                }
 
612
 
 
613
                // x & y == x & y
 
614
                z.abs = z.abs.and(x.abs, y.abs)
 
615
                z.neg = false
 
616
                return z
 
617
        }
 
618
 
 
619
        // x.neg != y.neg
 
620
        if x.neg {
 
621
                x, y = y, x // & is symmetric
 
622
        }
 
623
 
 
624
        // x & (-y) == x & ^(y-1) == x &^ (y-1)
 
625
        y1 := nat{}.sub(y.abs, natOne)
 
626
        z.abs = z.abs.andNot(x.abs, y1)
 
627
        z.neg = false
 
628
        return z
 
629
}
 
630
 
 
631
 
 
632
// AndNot sets z = x &^ y and returns z.
 
633
func (z *Int) AndNot(x, y *Int) *Int {
 
634
        if x.neg == y.neg {
 
635
                if x.neg {
 
636
                        // (-x) &^ (-y) == ^(x-1) &^ ^(y-1) == ^(x-1) & (y-1) == (y-1) &^ (x-1)
 
637
                        x1 := nat{}.sub(x.abs, natOne)
 
638
                        y1 := nat{}.sub(y.abs, natOne)
 
639
                        z.abs = z.abs.andNot(y1, x1)
 
640
                        z.neg = false
 
641
                        return z
 
642
                }
 
643
 
 
644
                // x &^ y == x &^ y
 
645
                z.abs = z.abs.andNot(x.abs, y.abs)
 
646
                z.neg = false
 
647
                return z
 
648
        }
 
649
 
 
650
        if x.neg {
 
651
                // (-x) &^ y == ^(x-1) &^ y == ^(x-1) & ^y == ^((x-1) | y) == -(((x-1) | y) + 1)
 
652
                x1 := nat{}.sub(x.abs, natOne)
 
653
                z.abs = z.abs.add(z.abs.or(x1, y.abs), natOne)
 
654
                z.neg = true // z cannot be zero if x is negative and y is positive
 
655
                return z
 
656
        }
 
657
 
 
658
        // x &^ (-y) == x &^ ^(y-1) == x & (y-1)
 
659
        y1 := nat{}.add(y.abs, natOne)
 
660
        z.abs = z.abs.and(x.abs, y1)
 
661
        z.neg = false
 
662
        return z
 
663
}
 
664
 
 
665
 
 
666
// Or sets z = x | y and returns z.
 
667
func (z *Int) Or(x, y *Int) *Int {
 
668
        if x.neg == y.neg {
 
669
                if x.neg {
 
670
                        // (-x) | (-y) == ^(x-1) | ^(y-1) == ^((x-1) & (y-1)) == -(((x-1) & (y-1)) + 1)
 
671
                        x1 := nat{}.sub(x.abs, natOne)
 
672
                        y1 := nat{}.sub(y.abs, natOne)
 
673
                        z.abs = z.abs.add(z.abs.and(x1, y1), natOne)
 
674
                        z.neg = true // z cannot be zero if x and y are negative
 
675
                        return z
 
676
                }
 
677
 
 
678
                // x | y == x | y
 
679
                z.abs = z.abs.or(x.abs, y.abs)
 
680
                z.neg = false
 
681
                return z
 
682
        }
 
683
 
 
684
        // x.neg != y.neg
 
685
        if x.neg {
 
686
                x, y = y, x // | is symmetric
 
687
        }
 
688
 
 
689
        // x | (-y) == x | ^(y-1) == ^((y-1) &^ x) == -(^((y-1) &^ x) + 1)
 
690
        y1 := nat{}.sub(y.abs, natOne)
 
691
        z.abs = z.abs.add(z.abs.andNot(y1, x.abs), natOne)
 
692
        z.neg = true // z cannot be zero if one of x or y is negative
 
693
        return z
 
694
}
 
695
 
 
696
 
 
697
// Xor sets z = x ^ y and returns z.
 
698
func (z *Int) Xor(x, y *Int) *Int {
 
699
        if x.neg == y.neg {
 
700
                if x.neg {
 
701
                        // (-x) ^ (-y) == ^(x-1) ^ ^(y-1) == (x-1) ^ (y-1)
 
702
                        x1 := nat{}.sub(x.abs, natOne)
 
703
                        y1 := nat{}.sub(y.abs, natOne)
 
704
                        z.abs = z.abs.xor(x1, y1)
 
705
                        z.neg = false
 
706
                        return z
 
707
                }
 
708
 
 
709
                // x ^ y == x ^ y
 
710
                z.abs = z.abs.xor(x.abs, y.abs)
 
711
                z.neg = false
 
712
                return z
 
713
        }
 
714
 
 
715
        // x.neg != y.neg
 
716
        if x.neg {
 
717
                x, y = y, x // ^ is symmetric
 
718
        }
 
719
 
 
720
        // x ^ (-y) == x ^ ^(y-1) == ^(x ^ (y-1)) == -((x ^ (y-1)) + 1)
 
721
        y1 := nat{}.sub(y.abs, natOne)
 
722
        z.abs = z.abs.add(z.abs.xor(x.abs, y1), natOne)
 
723
        z.neg = true // z cannot be zero if only one of x or y is negative
 
724
        return z
 
725
}
 
726
 
 
727
 
 
728
// Not sets z = ^x and returns z.
 
729
func (z *Int) Not(x *Int) *Int {
 
730
        if x.neg {
 
731
                // ^(-x) == ^(^(x-1)) == x-1
 
732
                z.abs = z.abs.sub(x.abs, natOne)
 
733
                z.neg = false
 
734
                return z
 
735
        }
 
736
 
 
737
        // ^x == -x-1 == -(x+1)
 
738
        z.abs = z.abs.add(x.abs, natOne)
 
739
        z.neg = true // z cannot be zero if x is positive
 
740
        return z
 
741
}