PageRenderTime 57ms CodeModel.GetById 9ms app.highlight 41ms RepoModel.GetById 2ms app.codeStats 0ms

/IronPython_Main/Runtime/Microsoft.Dynamic/Math/BigIntegerV4.cs

#
C# | 612 lines | 455 code | 123 blank | 34 comment | 40 complexity | 5d23ff04580970a542ef6b57353999ce MD5 | raw file
  1/* ****************************************************************************
  2 *
  3 * Copyright (c) Microsoft Corporation. 
  4 *
  5 * This source code is subject to terms and conditions of the Apache License, Version 2.0. A 
  6 * copy of the license can be found in the License.html file at the root of this distribution. If 
  7 * you cannot locate the  Apache License, Version 2.0, please send an email to 
  8 * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound 
  9 * by the terms of the Apache License, Version 2.0.
 10 *
 11 * You must not remove this notice, or any other, from this software.
 12 *
 13 *
 14 * ***************************************************************************/
 15#if !CLR2
 16
 17using System;
 18using System.Collections.Generic;
 19using System.Diagnostics;
 20using System.Diagnostics.CodeAnalysis;
 21using System.Globalization;
 22using System.Text;
 23using Microsoft.Contracts;
 24using Microsoft.Scripting.Utils;
 25using BigInt = System.Numerics.BigInteger;
 26
 27namespace Microsoft.Scripting.Math {
 28    /// <summary>
 29    /// arbitrary precision integers
 30    /// </summary>
 31    [Serializable]
 32    public sealed class BigInteger : IFormattable, IComparable, IEquatable<BigInteger> {
 33        internal readonly BigInt Value;
 34
 35        [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
 36        public static readonly BigInteger Zero = new BigInteger((BigInt)0);
 37        [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")]
 38        public static readonly BigInteger One = new BigInteger((BigInt)1);
 39
 40        public BigInteger(BigInt value) {
 41            Value = value;
 42        }
 43
 44        [CLSCompliant(false)]
 45        public static BigInteger Create(ulong v) {
 46            return new BigInteger(new BigInt(v));
 47        }
 48
 49        [CLSCompliant(false)]
 50        public static BigInteger Create(uint v) {
 51            return new BigInteger(new BigInt(v));
 52        }
 53
 54        public static BigInteger Create(long v) {
 55            return new BigInteger(new BigInt(v));
 56        }
 57
 58        public static BigInteger Create(int v) {
 59            return new BigInteger(new BigInt(v));
 60        }
 61
 62        public static BigInteger Create(decimal v) {
 63            return new BigInteger(new BigInt(v));
 64        }
 65
 66        public static BigInteger Create(byte[] v) {
 67            return new BigInteger(v);
 68        }
 69
 70        public static BigInteger Create(double v) {
 71            return new BigInteger(new BigInt(v));
 72        }
 73
 74        public static implicit operator BigInteger(byte i) {
 75            return new BigInteger((BigInt)i);
 76        }
 77
 78        [CLSCompliant(false)]
 79        public static implicit operator BigInteger(sbyte i) {
 80            return new BigInteger((BigInt)i);
 81        }
 82
 83        public static implicit operator BigInteger(short i) {
 84            return new BigInteger((BigInt)i);
 85        }
 86
 87        [CLSCompliant(false)]
 88        public static implicit operator BigInteger(ushort i) {
 89            return new BigInteger((BigInt)i);
 90        }
 91
 92        [CLSCompliant(false)]
 93        public static implicit operator BigInteger(uint i) {
 94            return new BigInteger((BigInt)i);
 95        }
 96
 97        public static implicit operator BigInteger(int i) {
 98            return new BigInteger((BigInt)i);
 99        }
100
101        [CLSCompliant(false)]
102        public static implicit operator BigInteger(ulong i) {
103            return new BigInteger((BigInt)i);
104        }
105
106        public static implicit operator BigInteger(long i) {
107            return new BigInteger((BigInt)i);
108        }
109
110        public static implicit operator BigInteger(decimal self) {
111            return new BigInteger((BigInt)self);
112        }
113
114        public static explicit operator BigInteger(double self) {
115            return new BigInteger((BigInt)self);
116        }
117
118        public static explicit operator BigInteger(float self) {
119            return new BigInteger((BigInt)self);
120        }
121
122        public static explicit operator double(BigInteger self) {
123            return (double)self.Value;
124        }
125
126        public static explicit operator float(BigInteger self) {
127            return (float)self.Value;
128        }
129
130        public static explicit operator decimal(BigInteger self) {
131            return (decimal)self.Value;
132        }
133
134        public static explicit operator byte(BigInteger self) {
135            return (byte)self.Value;
136        }
137
138        [CLSCompliant(false)]
139        public static explicit operator sbyte(BigInteger self) {
140            return (sbyte)self.Value;
141        }
142
143        [CLSCompliant(false)]
144        public static explicit operator UInt16(BigInteger self) {
145            return (UInt16)self.Value;
146        }
147
148        public static explicit operator Int16(BigInteger self) {
149            return (Int16)self.Value;
150        }
151
152        [CLSCompliant(false)]
153        public static explicit operator UInt32(BigInteger self) {
154            return (UInt32)self.Value;
155        }
156
157        public static explicit operator Int32(BigInteger self) {
158            return (Int32)self.Value;
159        }
160
161        public static explicit operator Int64(BigInteger self) {
162            return (Int64)self.Value;
163        }
164
165        [CLSCompliant(false)]
166        public static explicit operator UInt64(BigInteger self) {
167            return (UInt64)self.Value;
168        }
169
170        public static implicit operator BigInteger(BigInt value) {
171            return new BigInteger(value);
172        }
173
174        public static implicit operator BigInt(BigInteger value) {
175            return value.Value;
176        }
177
178        public BigInteger(BigInteger copy) {
179            if (object.ReferenceEquals(copy, null)) {
180                throw new ArgumentNullException("copy");
181            }
182            Value = copy.Value;
183        }
184
185        public BigInteger(byte[] data) {
186            ContractUtils.RequiresNotNull(data, "data");
187
188            Value = new BigInt(data);
189        }
190
191        public BigInteger(int sign, byte[] data) {
192            ContractUtils.RequiresNotNull(data, "data");
193            ContractUtils.Requires(sign >= -1 && sign <= +1, "sign");
194
195            Value = new BigInt(data);
196            if (sign < 0) {
197                Value = -Value;
198            }
199        }
200        
201        [CLSCompliant(false)]
202        public BigInteger(int sign, uint[] data) {
203            ContractUtils.RequiresNotNull(data, "data");
204            ContractUtils.Requires(sign >= -1 && sign <= +1, "sign");
205            int length = GetLength(data);
206            ContractUtils.Requires(length == 0 || sign != 0, "sign");
207            if (length == 0) {
208                Value = 0;
209                return;
210            }
211
212            bool highest = (data[length - 1] & 0x80000000) != 0;
213            byte[] bytes = new byte[length * 4 + (highest ? 1 : 0)];
214            int j = 0;
215            for (int i = 0; i < length; i++) {
216                ulong w = data[i];
217                bytes[j++] = (byte)(w & 0xff);
218                bytes[j++] = (byte)((w >> 8) & 0xff);
219                bytes[j++] = (byte)((w >> 16) & 0xff);
220                bytes[j++] = (byte)((w >> 24) & 0xff);
221            }
222
223            Value = new BigInt(bytes);
224            if (sign < 0) {
225                Value = -Value;
226            }
227        }
228
229        [CLSCompliant(false)]
230        public uint[] GetWords() {
231            return Value.GetWords();
232        }
233
234        public int GetBitCount() {
235            return Value.GetBitCount();
236        }
237
238        public int GetWordCount() {
239            return Value.GetWordCount();
240        }
241
242        public int GetByteCount() {
243            return Value.GetByteCount();
244        }
245
246        /// <summary>
247        /// Return the sign of this BigInteger: -1, 0, or 1.
248        /// </summary>
249        public int Sign {
250            get {
251                return Value.Sign;
252            }
253        }
254
255        public bool AsInt64(out long ret) {
256            if (Value >= Int64.MinValue && Value <= Int64.MaxValue) {
257                ret = (long)Value;
258                return true;
259            }
260            ret = 0;
261            return false;
262        }
263
264        [CLSCompliant(false)]
265        public bool AsUInt32(out uint ret) {
266            if (Value >= UInt32.MinValue && Value <= UInt32.MaxValue) {
267                ret = (UInt32)Value;
268                return true;
269            }
270            ret = 0;
271            return false;
272        }
273
274        [CLSCompliant(false)]
275        public bool AsUInt64(out ulong ret) {
276            if (Value >= UInt64.MinValue && Value <= UInt64.MaxValue) {
277                ret = (UInt64)Value;
278                return true;
279            }
280            ret = 0;
281            return false;
282        }
283
284        public bool AsInt32(out int ret) {
285            if (Value >= Int32.MinValue && Value <= Int32.MaxValue) {
286                ret = (Int32)Value;
287                return true;
288            }
289            ret = 0;
290            return false;
291        }
292
293        [CLSCompliant(false)]
294        public uint ToUInt32() {
295            return (uint)Value;
296        }
297
298        public int ToInt32() {
299            return (int)Value;
300        }
301
302        public decimal ToDecimal() {
303            return (decimal)Value;
304        }
305
306        [CLSCompliant(false)]
307        public ulong ToUInt64() {
308            return (ulong)Value;
309        }
310
311        public long ToInt64() {
312            return (long)Value;
313        }
314
315        private static int GetLength(uint[] data) {
316            int ret = data.Length - 1;
317            while (ret >= 0 && data[ret] == 0) ret--;
318            return ret + 1;
319        }
320
321        public static int Compare(BigInteger x, BigInteger y) {
322            return BigInt.Compare(x.Value, y.Value);
323        }
324
325        public static bool operator ==(BigInteger x, int y) {
326            return x.Value == y;
327        }
328
329        public static bool operator !=(BigInteger x, int y) {
330            return x.Value != y;
331        }
332
333        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1065:DoNotRaiseExceptionsInUnexpectedLocations")] // TODO: fix
334        public static bool operator ==(BigInteger x, double y) {
335            if (object.ReferenceEquals(x, null)) {
336                throw new ArgumentNullException("x");
337            }
338
339            // we can hold all double values, but not all double values
340            // can hold BigInteger values, and we may lose precision.  Convert
341            // the double to a big int, then compare.
342
343            if ((y % 1) != 0) return false;  // not a whole number, can't be equal
344
345            return x.Value == (BigInt)y;
346        }
347
348        public static bool operator ==(double x, BigInteger y) {
349            return y == x;
350        }
351
352        public static bool operator !=(BigInteger x, double y) {
353            return !(x == y);
354        }
355
356        public static bool operator !=(double x, BigInteger y) {
357            return !(x == y);
358        }
359
360
361        public static bool operator ==(BigInteger x, BigInteger y) {
362            return Compare(x, y) == 0;
363        }
364
365        public static bool operator !=(BigInteger x, BigInteger y) {
366            return Compare(x, y) != 0;
367        }
368        public static bool operator <(BigInteger x, BigInteger y) {
369            return Compare(x, y) < 0;
370        }
371        public static bool operator <=(BigInteger x, BigInteger y) {
372            return Compare(x, y) <= 0;
373        }
374        public static bool operator >(BigInteger x, BigInteger y) {
375            return Compare(x, y) > 0;
376        }
377        public static bool operator >=(BigInteger x, BigInteger y) {
378            return Compare(x, y) >= 0;
379        }
380
381        public static BigInteger Add(BigInteger x, BigInteger y) {
382            return x + y;
383        }
384
385        public static BigInteger operator +(BigInteger x, BigInteger y) {
386            return new BigInteger(x.Value + y.Value);
387        }
388
389        public static BigInteger Subtract(BigInteger x, BigInteger y) {
390            return x - y;
391        }
392
393        public static BigInteger operator -(BigInteger x, BigInteger y) {
394            return new BigInteger(x.Value - y.Value);
395        }
396
397        public static BigInteger Multiply(BigInteger x, BigInteger y) {
398            return x * y;
399        }
400
401        public static BigInteger operator *(BigInteger x, BigInteger y) {
402            return new BigInteger(x.Value * y.Value);
403        }
404
405        public static BigInteger Divide(BigInteger x, BigInteger y) {
406            return x / y;
407        }
408
409        public static BigInteger operator /(BigInteger x, BigInteger y) {
410            BigInteger dummy;
411            return DivRem(x, y, out dummy);
412        }
413
414        public static BigInteger Mod(BigInteger x, BigInteger y) {
415            return x % y;
416        }
417
418        public static BigInteger operator %(BigInteger x, BigInteger y) {
419            BigInteger ret;
420            DivRem(x, y, out ret);
421            return ret;
422        }
423
424        public static BigInteger DivRem(BigInteger x, BigInteger y, out BigInteger remainder) {
425            BigInt rem;
426            BigInt result = BigInt.DivRem(x.Value, y.Value, out rem);
427            remainder = new BigInteger(rem);
428            return new BigInteger(result);
429        }
430
431        public static BigInteger BitwiseAnd(BigInteger x, BigInteger y) {
432            return x & y;
433        }
434
435        public static BigInteger operator &(BigInteger x, BigInteger y) {
436            return new BigInteger(x.Value & y.Value);
437        }
438
439        public static BigInteger BitwiseOr(BigInteger x, BigInteger y) {
440            return x | y;
441        }
442
443        public static BigInteger operator |(BigInteger x, BigInteger y) {
444            return new BigInteger(x.Value | y.Value);
445        }
446
447        public static BigInteger Xor(BigInteger x, BigInteger y) {
448            return x ^ y;
449        }
450
451        public static BigInteger operator ^(BigInteger x, BigInteger y) {
452            return new BigInteger(x.Value ^ y.Value);
453        }
454
455        public static BigInteger LeftShift(BigInteger x, int shift) {
456            return x << shift;
457        }
458
459        public static BigInteger operator <<(BigInteger x, int shift) {
460            return new BigInteger(x.Value << shift);
461        }
462
463        public static BigInteger RightShift(BigInteger x, int shift) {
464            return x >> shift;
465        }
466
467        public static BigInteger operator >>(BigInteger x, int shift) {
468            return new BigInteger(x.Value >> shift);
469        }
470
471        public static BigInteger Negate(BigInteger x) {
472            return -x;
473        }
474
475        public static BigInteger operator -(BigInteger x) {
476            return new BigInteger(-x.Value);
477        }
478
479        public BigInteger OnesComplement() {
480            return ~this;
481        }
482
483        public static BigInteger operator ~(BigInteger x) {
484            return new BigInteger(~x.Value);
485        }
486
487        public BigInteger Abs() {
488            return new BigInteger(BigInt.Abs(Value));
489        }
490
491        public BigInteger Power(int exp) {
492            return new BigInteger(BigInt.Pow(Value, exp));
493        }
494
495        public BigInteger ModPow(int power, BigInteger mod) {
496            return new BigInteger(BigInt.ModPow(Value, power, mod.Value));
497        }
498
499        public BigInteger ModPow(BigInteger power, BigInteger mod) {
500            return new BigInteger(BigInt.ModPow(Value, power.Value, mod.Value));
501        }
502
503        public BigInteger Square() {
504            return this * this;
505        }
506
507#if !SILVERLIGHT
508        public static BigInteger Parse(string str) {
509            return new BigInteger(BigInt.Parse(str));
510        }
511#endif
512
513        public override string ToString() {
514            return ToString(10);
515        }
516
517        public string ToString(int @base) {
518            return MathUtils.BigIntegerToString(GetWords(), Sign, @base);
519        }
520
521        public override int GetHashCode() {
522            return Value.GetHashCode();
523        }
524
525        public override bool Equals(object obj) {
526            return Equals(obj as BigInteger);
527        }
528
529        public bool Equals(BigInteger other) {
530            if (object.ReferenceEquals(other, null)) return false;
531            return this == other;
532        }
533
534        public bool IsNegative() {
535            return Value.Sign < 0;
536        }
537
538        public bool IsZero() {
539            return Value.Sign == 0;
540        }
541
542        public bool IsPositive() {
543            return Value.Sign > 0;
544        }
545
546        public bool IsEven {
547            get { return Value.IsEven; }
548        }
549
550        public bool IsPowerOfTwo {
551            get {
552                return Value.IsPowerOfTwo;
553            }
554        }
555
556        public double Log(Double newBase) {
557            return BigInt.Log(Value, newBase);
558        }
559
560        /// <summary>
561        /// Calculates the natural logarithm of the BigInteger.
562        /// </summary>
563        public double Log() {
564            return BigInt.Log(Value);
565        }
566
567        /// <summary>
568        /// Calculates log base 10 of a BigInteger.
569        /// </summary>
570        public double Log10() {
571            return BigInt.Log10(Value);
572        }
573
574        #region IComparable Members
575
576        public int CompareTo(object obj) {
577            if (obj == null) {
578                return 1;
579            }
580            BigInteger o = obj as BigInteger;
581            if (object.ReferenceEquals(o, null)) {
582                throw new ArgumentException("expected integer");
583            }
584            return Compare(this, o);
585        }
586
587        #endregion
588
589        /// <summary>
590        /// Return the value of this BigInteger as a little-endian twos-complement
591        /// byte array, using the fewest number of bytes possible. If the value is zero,
592        /// return an array of one byte whose element is 0x00.
593        /// </summary>
594        public byte[] ToByteArray() {
595            return Value.ToByteArray();
596        }
597
598        [Confined]
599        public string ToString(IFormatProvider provider) {
600            return Value.ToString(provider);
601        }
602
603        #region IFormattable Members
604
605        string IFormattable.ToString(string format, IFormatProvider formatProvider) {
606            return Value.ToString(format, formatProvider);
607        }
608
609        #endregion
610    }
611}
612#endif