예제 #1
0
파일: IntNum.cs 프로젝트: vic/ioke
 /** Add an IntNum and an int, yielding a new IntNum. */
 public static IntNum add(IntNum x, int y)
 {
     if (x.words == null)
         return IntNum.add (x.ival, y);
     IntNum result = new IntNum (0);
     result.setAdd (x, y);
     return result.canonicalize ();
 }
예제 #2
0
파일: RatNum.cs 프로젝트: vic/ioke-outdated
 public static RatNum make(IntNum num, IntNum den)
 {
     IntNum g = IntNum.gcd (num, den);
     if (den.isNegative ())
         g = IntNum.neg (g);
     if (! g.isOne ())
         {
             num = IntNum.quotient (num, g);
             den = IntNum.quotient (den, g);
         }
     return den.isOne () ? (RatNum)num : (RatNum)(new IntFraction (num, den));
 }
예제 #3
0
파일: IntNum.cs 프로젝트: vic/ioke
 /** Add two IntNums, yielding their sum as another IntNum. */
 public static IntNum add(IntNum x, IntNum y, int k)
 {
     if (x.words == null && y.words == null)
         return IntNum.make ((long) k * (long) y.ival + (long) x.ival);
     if (k != 1)
         {
             if (k == -1)
                 y = IntNum.neg (y);
             else
                 y = IntNum.times (y, IntNum.make (k));
         }
     if (x.words == null)
         return IntNum.add (y, x.ival);
     if (y.words == null)
         return IntNum.add (x, y.ival);
     // Both are big
     if (y.ival > x.ival)
         { // Swap so x is longer then y.
             IntNum tmp = x;  x = y;  y = tmp;
         }
     IntNum result = alloc (x.ival + 1);
     int i = y.ival;
     long carry = MPN.add_n (result.words, x.words, y.words, i);
     long y_ext = y.words[i-1] < 0 ? 0xffffffffL : 0;
     for (; i < x.ival;  i++)
         {
             carry += ((long) x.words[i] & 0xffffffffL) + y_ext;;
             result.words[i] = (int) carry;
             carry = (long)(((ulong)carry) >> 32);
         }
     if (x.words[i - 1] < 0)
         y_ext--;
     result.words[i] = (int) (carry + y_ext);
     result.ival = i+1;
     return result.canonicalize ();
 }
예제 #4
0
파일: IntNum.cs 프로젝트: vic/ioke
 void setShift(IntNum x, int count)
 {
     if (count > 0)
         setShiftLeft (x, count);
     else
         setShiftRight (x, -count);
 }
예제 #5
0
파일: Number.cs 프로젝트: nope/ioke
        public override void Init(IokeObject obj)
        {
            Runtime runtime = obj.runtime;
            IokeObject number = obj;

            obj.Kind = "Number";
            obj.Mimics(IokeObject.As(runtime.Mixins.GetCell(null, null, "Comparing"), obj), runtime.nul, runtime.nul);

            IokeObject real = new IokeObject(runtime, "A real number can be either a rational number or a decimal number", new Number());
            real.MimicsWithoutCheck(number);
            real.Kind = "Number Real";
            number.RegisterCell("Real", real);

            IokeObject rational = new IokeObject(runtime, "A rational number is either an integer or a ratio", new Number());
            rational.MimicsWithoutCheck(real);
            rational.Kind = "Number Rational";
            number.RegisterCell("Rational", rational);

            IokeObject integer = new IokeObject(runtime, "An integral number", new Number());
            integer.MimicsWithoutCheck(rational);
            integer.Kind = "Number Integer";
            number.RegisterCell("Integer", integer);
            runtime.Integer = integer;

            IokeObject ratio = new IokeObject(runtime, "A ratio of two integral numbers", new Number());
            ratio.MimicsWithoutCheck(rational);
            ratio.Kind = "Number Ratio";
            number.RegisterCell("Ratio", ratio);
            runtime.Ratio = ratio;

            IokeObject _decimal = new IokeObject(runtime, "An exact, unlimited representation of a decimal number", new Decimal(BigDecimal.ZERO));
            _decimal.MimicsWithoutCheck(real);
            _decimal.Init();
            number.RegisterCell("Decimal", _decimal);

            IokeObject infinity = new IokeObject(runtime, "A value representing infinity", new Number(RatNum.infinity(1)));
            infinity.MimicsWithoutCheck(ratio);
            infinity.Kind = "Number Infinity";
            number.RegisterCell("Infinity", infinity);
            runtime.Infinity = infinity;

            IokeObject infinity2 = new IokeObject(runtime, "A value representing infinity", new Number(RatNum.infinity(1)));
            infinity2.MimicsWithoutCheck(ratio);
            infinity2.Kind = "Number \u221E";
            number.RegisterCell("\u221E", infinity2);

            number.RegisterMethod(runtime.NewNativeMethod("returns a hash for the number",
                                                           new NativeMethod.WithNoArguments("hash", (method, context, message, on, outer) => {
                                                                   outer.ArgumentsDefinition.CheckArgumentCount(context, message, on);
                                                                   return context.runtime.NewNumber(Number.GetValue(on).GetHashCode());
                                                               })));

            number.RegisterMethod(runtime.NewNativeMethod("returns the square root of the receiver. this should return the same result as calling ** with 0.5",
                                                           new NativeMethod.WithNoArguments("sqrt", (method, context, message, on, outer) => {
                                                                   outer.ArgumentsDefinition.CheckArgumentCount(context, message, on);

                                                                   RatNum value = Number.GetValue(on);
                                                                   if(value is IntFraction) {
                                                                       IntNum num = value.numerator();
                                                                       IntNum den = value.denominator();
                                                                       BigDecimal nums = new BigSquareRoot().Get(num.AsBigDecimal());
                                                                       BigDecimal dens = new BigSquareRoot().Get(den.AsBigDecimal());
                                                                       try {
                                                                           num = IntNum.valueOf(nums.toBigIntegerExact().ToString());
                                                                           den = IntNum.valueOf(dens.toBigIntegerExact().ToString());
                                                                           return context.runtime.NewNumber(new IntFraction(num, den));
                                                                       } catch(ArithmeticException e) {
                                                                           // Ignore and fall through
                                                                       }
                                                                   }

                                                                   if(RatNum.compare(value, IntNum.zero()) < 1) {
                                                                       IokeObject condition = IokeObject.As(IokeObject.GetCellChain(context.runtime.Condition,
                                                                                                                                          message,
                                                                                                                                          context,
                                                                                                                                          "Error",
                                                                                                                                          "Arithmetic"), context).Mimic(message, context);
                                                                       condition.SetCell("message", message);
                                                                       condition.SetCell("context", context);
                                                                       condition.SetCell("receiver", on);

                                                                       context.runtime.ErrorCondition(condition);
                                                                   }
                                                                   return context.runtime.NewDecimal(new BigSquareRoot().Get(value.AsBigDecimal()));
                                                               })));

            number.RegisterMethod(runtime.NewNativeMethod("returns true if the left hand side number is equal to the right hand side number.",
                                                       new TypeCheckingNativeMethod("==", TypeCheckingArgumentsDefinition.builder()
                                                                                    .ReceiverMustMimic(runtime.Number)
                                                                                    .WithRequiredPositional("other")
                                                                                    .Arguments,
                                                                                    (method, on, args, keywords, context, message) => {
                                                                                        Number d = (Number)IokeObject.dataOf(on);
                                                                                        object other = args[0];

                                                                                        return ((other is IokeObject) &&
                                                                                                (IokeObject.dataOf(other) is Number)
                                                                                                && (((d.kind || ((Number)IokeObject.dataOf(other)).kind) ? on == other :
                                                                                                     d.value.Equals(((Number)IokeObject.dataOf(other)).value)))) ? context.runtime.True : context.runtime.False;
                                                                                    })));

            rational.RegisterMethod(runtime.NewNativeMethod("compares this number against the argument, returning -1, 0 or 1 based on which one is larger. if the argument is a decimal, the receiver will be converted into a form suitable for comparing against a decimal, and then compared - it's not specified whether this will actually call Decimal#<=> or not. if the argument is neither a Rational nor a Decimal, it tries to call asRational, and if that doesn't work it returns nil.",
                                                            new TypeCheckingNativeMethod("<=>", TypeCheckingArgumentsDefinition.builder()
                                                                                         .ReceiverMustMimic(rational)
                                                                                         .WithRequiredPositional("other")
                                                                                         .Arguments,
                                                                                         (method, on, args, keywords, context, message) => {
                                                                                             object arg = args[0];

                                                                                             IokeData data = IokeObject.dataOf(arg);

                                                                                             if(data is Decimal) {
                                                                                                 return context.runtime.NewNumber(new BigDecimal(Number.GetValue(on).longValue()).CompareTo(Decimal.GetValue(arg)));
                                                                                             } else {
                                                                                                 if(!(data is Number)) {
                                                                                                     arg = IokeObject.ConvertToRational(arg, message, context, false);
                                                                                                     if(!(IokeObject.dataOf(arg) is Number)) {
                                                                                                         // Can't compare, so bail out
                                                                                                         return context.runtime.nil;
                                                                                                     }
                                                                                                 }

                                                                                                 if(on == rational || arg == rational || on == integer || arg == integer || on == ratio || arg == ratio) {
                                                                                                     if(arg == on) {
                                                                                                         return context.runtime.NewNumber(0);
                                                                                                     }
                                                                                                     return context.runtime.nil;
                                                                                                 }

                                                                                                 return context.runtime.NewNumber(IntNum.compare(Number.GetValue(on),Number.GetValue(arg)));
                                                                                             }
                                                                                         })));

            number.RegisterMethod(runtime.NewNativeMethod("compares this against the argument. should be overridden - in this case only used to check for equivalent number kinds",
                                                          new NativeMethod("==", DefaultArgumentsDefinition.builder()
                                                                           .WithRequiredPositional("other")
                                                                           .Arguments,
                                                                           (method, context, message, on, outer) => {
                                                                               IList args = new SaneArrayList();
                                                                               outer.ArgumentsDefinition.GetEvaluatedArguments(context, message, on, args, new SaneDictionary<string, object>());
                                                                               object arg = args[0];
                                                                               if(on == arg) {
                                                                                   return context.runtime.True;
                                                                               } else {
                                                                                   return context.runtime.False;
                                                                               }
                                                                           })));

            rational.RegisterMethod(runtime.NewNativeMethod("compares this number against the argument, true if this number is the same, otherwise false",
                                                            new TypeCheckingNativeMethod("==", TypeCheckingArgumentsDefinition.builder()
                                                                                         .ReceiverMustMimic(number)
                                                                                         .WithRequiredPositional("other")
                                                                                         .Arguments,
                                                                                         (method, on, args, keywords, context, message) => {
                                                                                             object arg = args[0];
                                                                                             if(on == rational || arg == rational || on == integer || arg == integer || on == ratio || arg == ratio || on == infinity || arg == infinity || on == infinity2 || arg == infinity2) {
                                                                                                 if(arg == on) {
                                                                                                     return context.runtime.True;
                                                                                                 }
                                                                                                 return context.runtime.False;
                                                                                             }
                                                                                             if(IokeObject.dataOf(arg) is Decimal) {
                                                                                                 return (new BigDecimal(Number.GetValue(on).longValue()).CompareTo(Decimal.GetValue(arg)) == 0) ? context.runtime.True : context.runtime.False;
                                                                                             } else if(IokeObject.dataOf(arg) is Number) {
                                                                                                 return IntNum.compare(Number.GetValue(on),Number.GetValue(arg)) == 0 ? context.runtime.True : context.runtime.False;
                                                                                             } else {
                                                                                                 return context.runtime.False;
                                                                                             }
                                                                                         })));

            rational.RegisterMethod(runtime.NewNativeMethod("returns the difference between this number and the argument. if the argument is a decimal, the receiver will be converted into a form suitable for subtracting against a decimal, and then subtracted. if the argument is neither a Rational nor a Decimal, it tries to call asRational, and if that fails it signals a condition.",
                                                            new TypeCheckingNativeMethod("-", TypeCheckingArgumentsDefinition.builder()
                                                                                         .ReceiverMustMimic(number)
                                                                                         .WithRequiredPositional("subtrahend")
                                                                                         .Arguments,
                                                                                         (method, on, args, keywords, context, message) => {
                                                                                             object arg = args[0];
                                                                                             IokeData data = IokeObject.dataOf(arg);

                                                                                             if(data is Decimal) {
                                                                                                 return ((Message)IokeObject.dataOf(context.runtime.minusMessage)).SendTo(context.runtime.minusMessage, context, context.runtime.NewDecimal(((Number)IokeObject.dataOf(on))), arg);
                                                                                             } else {
                                                                                                 if(!(data is Number)) {
                                                                                                     arg = IokeObject.ConvertToRational(arg, message, context, true);
                                                                                                 }

                                                                                                 return context.runtime.NewNumber((RatNum)Number.GetValue(on).sub(Number.GetValue(arg)));
                                                                                             }
                                                                                         })));
            integer.RegisterMethod(runtime.NewNativeMethod("Returns the successor of this number", new TypeCheckingNativeMethod.WithNoArguments("succ", integer,
                                                                                                                                                (method, on, args, keywords, context, message) => {
                                                                                                                                                    return runtime.NewNumber(IntNum.add(Number.IntValue(on),IntNum.one()));
                                                                                                                                                })));

            integer.RegisterMethod(runtime.NewNativeMethod("Returns the predecessor of this number", new TypeCheckingNativeMethod.WithNoArguments("pred", integer,
                                                                                                                                                (method, on, args, keywords, context, message) => {
                                                                                                                                                    return runtime.NewNumber(IntNum.sub(Number.IntValue(on),IntNum.one()));
                                                                                                                                                })));

            infinity.RegisterMethod(runtime.NewNativeMethod("Returns a text inspection of the object",
                                                            new TypeCheckingNativeMethod.WithNoArguments("inspect", infinity,
                                                                                                         (method, on, args, keywords, context, message) => {
                                                                                                             return runtime.NewText("Infinity");
                                                                                                         })));

            infinity.RegisterMethod(runtime.NewNativeMethod("Returns a brief text inspection of the object",
                                                            new TypeCheckingNativeMethod.WithNoArguments("notice", infinity,
                                                                                                         (method, on, args, keywords, context, message) => {
                                                                                                             return runtime.NewText("Infinity");
                                                                                                         })));

            infinity2.RegisterMethod(runtime.NewNativeMethod("Returns a text inspection of the object",
                                                            new TypeCheckingNativeMethod.WithNoArguments("inspect", infinity2,
                                                                                                         (method, on, args, keywords, context, message) => {
                                                                                                             return runtime.NewText("\u221E");
                                                                                                         })));

            infinity2.RegisterMethod(runtime.NewNativeMethod("Returns a brief text inspection of the object",
                                                            new TypeCheckingNativeMethod.WithNoArguments("notice", infinity2,
                                                                                                         (method, on, args, keywords, context, message) => {
                                                                                                             return runtime.NewText("\u221E");
                                                                                                         })));

            rational.RegisterMethod(runtime.NewNativeMethod("returns the addition of this number and the argument. if the argument is a decimal, the receiver will be converted into a form suitable for addition against a decimal, and then added. if the argument is neither a Rational nor a Decimal, it tries to call asRational, and if that fails it signals a condition.",
                                                            new TypeCheckingNativeMethod("+", TypeCheckingArgumentsDefinition.builder()
                                                                                         .ReceiverMustMimic(number)
                                                                                         .WithRequiredPositional("addend")
                                                                                         .Arguments,
                                                                                         (method, on, args, keywords, context, message) => {
                                                                                             object arg = args[0];
                                                                                             IokeData data = IokeObject.dataOf(arg);

                                                                                             if(data is Decimal) {
                                                                                                 return ((Message)IokeObject.dataOf(context.runtime.plusMessage)).SendTo(context.runtime.plusMessage, context, context.runtime.NewDecimal(((Number)IokeObject.dataOf(on))), arg);
                                                                                             } else {
                                                                                                 if(!(data is Number)) {
                                                                                                     arg = IokeObject.ConvertToRational(arg, message, context, true);
                                                                                                 }

                                                                                                 return context.runtime.NewNumber(RatNum.add(Number.GetValue(on),Number.GetValue(arg),1));
                                                                                             }
                                                                                         })));

            rational.RegisterMethod(runtime.NewNativeMethod("returns the product of this number and the argument. if the argument is a decimal, the receiver will be converted into a form suitable for multiplying against a decimal, and then multiplied. if the argument is neither a Rational nor a Decimal, it tries to call asRational, and if that fails it signals a condition.",
                                                            new TypeCheckingNativeMethod("*", TypeCheckingArgumentsDefinition.builder()
                                                                                         .ReceiverMustMimic(number)
                                                                                         .WithRequiredPositional("multiplier")
                                                                                         .Arguments,
                                                                                         (method, on, args, keywords, context, message) => {
                                                                                             object arg = args[0];
                                                                                             IokeData data = IokeObject.dataOf(arg);

                                                                                             if(data is Decimal) {
                                                                                                 return ((Message)IokeObject.dataOf(context.runtime.multMessage)).SendTo(context.runtime.multMessage, context, context.runtime.NewDecimal(((Number)IokeObject.dataOf(on))), arg);
                                                                                             } else {
                                                                                                 if(!(data is Number)) {
                                                                                                     arg = IokeObject.ConvertToRational(arg, message, context, true);
                                                                                                 }

                                                                                                 return context.runtime.NewNumber(RatNum.times(Number.GetValue(on),Number.GetValue(arg)));
                                                                                             }
                                                                                         })));

            rational.RegisterMethod(runtime.NewNativeMethod("returns the quotient of this number and the argument. if the division is not exact, it will return a Ratio.",
                                                            new TypeCheckingNativeMethod("/", TypeCheckingArgumentsDefinition.builder()
                                                                                         .ReceiverMustMimic(number)
                                                                                         .WithRequiredPositional("dividend")
                                                                                         .Arguments,
                                                                                         (method, on, args, keywords, context, message) => {
                                                                                             object arg = args[0];
                                                                                             IokeData data = IokeObject.dataOf(arg);

                                                                                             if(data is Decimal) {
                                                                                                 return ((Message)IokeObject.dataOf(context.runtime.divMessage)).SendTo(context.runtime.divMessage, context, context.runtime.NewDecimal(((Number)IokeObject.dataOf(on))), arg);
                                                                                             } else {
                                                                                                 if(!(data is Number)) {
                                                                                                     arg = IokeObject.ConvertToRational(arg, message, context, true);
                                                                                                 }

                                                                                                 while(Number.GetValue(arg).isZero()) {
                                                                                                     IokeObject condition = IokeObject.As(IokeObject.GetCellChain(context.runtime.Condition,
                                                                                                                                                                  message,
                                                                                                                                                                  context,
                                                                                                                                                                  "Error",
                                                                                                                                                                  "Arithmetic",
                                                                                                                                                                  "DivisionByZero"), context).Mimic(message, context);
                                                                                                     condition.SetCell("message", message);
                                                                                                     condition.SetCell("context", context);
                                                                                                     condition.SetCell("receiver", on);

                                                                                                     object[] newCell = new object[]{arg};

                                                                                                     context.runtime.WithRestartReturningArguments(()=>{context.runtime.ErrorCondition(condition);},
                                                                                                                                                   context,
                                                                                                                                                   new IokeObject.UseValue("dividend", newCell));
                                                                                                     arg = newCell[0];
                                                                                                 }

                                                                                                 return context.runtime.NewNumber(RatNum.divide(Number.GetValue(on),Number.GetValue(arg)));
                                                                                             }
                                                                                         })));

            integer.RegisterMethod(runtime.NewNativeMethod("returns the modulo of this number and the argument",
                                                           new TypeCheckingNativeMethod("%", TypeCheckingArgumentsDefinition.builder()
                                                                                        .ReceiverMustMimic(integer)
                                                                                        .WithRequiredPositional("dividend")
                                                                                        .Arguments,
                                                                                         (method, on, args, keywords, context, message) => {
                                                                                             object arg = args[0];
                                                                                             IokeData data = IokeObject.dataOf(arg);
                                                                                             if(!(data is Number)) {
                                                                                                 arg = IokeObject.ConvertToRational(arg, message, context, true);
                                                                                             }

                                                                                             return context.runtime.NewNumber(IntNum.modulo(Number.IntValue(on),Number.IntValue(arg)));
                                                                                        })));

            integer.RegisterMethod(runtime.NewNativeMethod("returns how many times the first number can be divided by the second one",
                                                           new TypeCheckingNativeMethod("div", TypeCheckingArgumentsDefinition.builder()
                                                                                        .ReceiverMustMimic(integer)
                                                                                        .WithRequiredPositional("dividend")
                                                                                        .Arguments,
                                                                                         (method, on, args, keywords, context, message) => {
                                                                                             object arg = args[0];
                                                                                             while(Number.GetValue(arg).isZero()) {
                                                                                                 IokeObject condition = IokeObject.As(IokeObject.GetCellChain(context.runtime.Condition,
                                                                                                                                                              message,
                                                                                                                                                              context,
                                                                                                                                                              "Error",
                                                                                                                                                              "Arithmetic",
                                                                                                                                                              "DivisionByZero"), context).Mimic(message, context);
                                                                                                 condition.SetCell("message", message);
                                                                                                 condition.SetCell("context", context);
                                                                                                 condition.SetCell("receiver", on);

                                                                                                 object[] newCell = new object[]{arg};

                                                                                                 context.runtime.WithRestartReturningArguments(()=>{context.runtime.ErrorCondition(condition);},
                                                                                                                                               context,
                                                                                                                                               new IokeObject.UseValue("dividend", newCell));
                                                                                                 arg = newCell[0];
                                                                                             }
                                                                                             IokeData data = IokeObject.dataOf(arg);
                                                                                             return context.runtime.NewNumber(IntNum.quotient(Number.IntValue(on),Number.IntValue(arg), IntNum.TRUNCATE));
                                                                                        })));

            integer.RegisterMethod(runtime.NewNativeMethod("returns a tuple of how many times the first number can be divided by the second one, and the remainder",
                                                           new TypeCheckingNativeMethod("divmod", TypeCheckingArgumentsDefinition.builder()
                                                                                        .ReceiverMustMimic(integer)
                                                                                        .WithRequiredPositional("dividend")
                                                                                        .Arguments,
                                                                                         (method, on, args, keywords, context, message) => {
                                                                                             object arg = args[0];
                                                                                             while(Number.GetValue(arg).isZero()) {
                                                                                                 IokeObject condition = IokeObject.As(IokeObject.GetCellChain(context.runtime.Condition,
                                                                                                                                                              message,
                                                                                                                                                              context,
                                                                                                                                                              "Error",
                                                                                                                                                              "Arithmetic",
                                                                                                                                                              "DivisionByZero"), context).Mimic(message, context);
                                                                                                 condition.SetCell("message", message);
                                                                                                 condition.SetCell("context", context);
                                                                                                 condition.SetCell("receiver", on);

                                                                                                 object[] newCell = new object[]{arg};

                                                                                                 context.runtime.WithRestartReturningArguments(()=>{context.runtime.ErrorCondition(condition);},
                                                                                                                                               context,
                                                                                                                                               new IokeObject.UseValue("dividend", newCell));
                                                                                                 arg = newCell[0];
                                                                                             }
                                                                                             IokeData data = IokeObject.dataOf(arg);
                                                                                             IntNum q = new IntNum();
                                                                                             IntNum r = new IntNum();
                                                                                             IntNum.divide(Number.IntValue(on),Number.IntValue(arg), q, r, IntNum.TRUNCATE);
                                                                                             return context.runtime.NewTuple(context.runtime.NewNumber(q.canonicalize()), context.runtime.NewNumber(r.canonicalize()));
                                                                                        })));

            rational.RegisterMethod(runtime.NewNativeMethod("returns this number to the power of the argument",
                                                            new TypeCheckingNativeMethod("**", TypeCheckingArgumentsDefinition.builder()
                                                                                         .ReceiverMustMimic(rational)
                                                                                         .WithRequiredPositional("exponent")
                                                                                         .Arguments,
                                                                                         (method, on, args, keywords, context, message) => {
                                                                                             object arg = args[0];
                                                                                             IokeData data = IokeObject.dataOf(arg);

                                                                                             if(!(data is Number)) {
                                                                                                 if(data is Decimal) {
                                                                                                     return context.runtime.NewDecimal(((RealNum)(Complex.power(Number.GetValue(on), new DFloNum(Decimal.GetValue(arg).ToString())))).AsBigDecimal());
                                                                                                 } else {
                                                                                                     arg = IokeObject.ConvertToRational(arg, message, context, true);
                                                                                                 }
                                                                                             }

                                                                                             return context.runtime.NewNumber((RatNum)Number.GetValue(on).power(Number.IntValue(arg)));
                                                                                         })));

            integer.RegisterMethod(runtime.NewNativeMethod("returns this number bitwise and the argument",
                                                           new TypeCheckingNativeMethod("&", TypeCheckingArgumentsDefinition.builder()
                                                                                        .ReceiverMustMimic(integer)
                                                                                        .WithRequiredPositional("other")
                                                                                        .Arguments,
                                                                                         (method, on, args, keywords, context, message) => {
                                                                                             object arg = args[0];
                                                                                             IokeData data = IokeObject.dataOf(arg);

                                                                                             if(!(data is Number)) {
                                                                                                 arg = IokeObject.ConvertToRational(arg, message, context, true);
                                                                                             }

                                                                                             return context.runtime.NewNumber(BitOps.and(Number.IntValue(on), Number.IntValue(arg)));
                                                                                        })));

            integer.RegisterMethod(runtime.NewNativeMethod("returns this number bitwise or the argument",
                                                           new TypeCheckingNativeMethod("|", TypeCheckingArgumentsDefinition.builder()
                                                                                        .ReceiverMustMimic(integer)
                                                                                        .WithRequiredPositional("other")
                                                                                        .Arguments,
                                                                                         (method, on, args, keywords, context, message) => {
                                                                                             object arg = args[0];
                                                                                             IokeData data = IokeObject.dataOf(arg);

                                                                                             if(!(data is Number)) {
                                                                                                 arg = IokeObject.ConvertToRational(arg, message, context, true);
                                                                                             }

                                                                                             return context.runtime.NewNumber(BitOps.ior(Number.IntValue(on), Number.IntValue(arg)));
                                                                                        })));

            integer.RegisterMethod(runtime.NewNativeMethod("returns this number bitwise xor the argument",
                                                           new TypeCheckingNativeMethod("^", TypeCheckingArgumentsDefinition.builder()
                                                                                        .ReceiverMustMimic(integer)
                                                                                        .WithRequiredPositional("other")
                                                                                        .Arguments,
                                                                                         (method, on, args, keywords, context, message) => {
                                                                                             object arg = args[0];
                                                                                             IokeData data = IokeObject.dataOf(arg);

                                                                                             if(!(data is Number)) {
                                                                                                 arg = IokeObject.ConvertToRational(arg, message, context, true);
                                                                                             }

                                                                                             return context.runtime.NewNumber(BitOps.xor(Number.IntValue(on), Number.IntValue(arg)));
                                                                                        })));

            integer.RegisterMethod(runtime.NewNativeMethod("returns this number left shifted by the argument",
                                                           new TypeCheckingNativeMethod("<<", TypeCheckingArgumentsDefinition.builder()
                                                                                        .ReceiverMustMimic(integer)
                                                                                        .WithRequiredPositional("other")
                                                                                        .Arguments,
                                                                                         (method, on, args, keywords, context, message) => {
                                                                                             object arg = args[0];
                                                                                             IokeData data = IokeObject.dataOf(arg);

                                                                                             if(!(data is Number)) {
                                                                                                 arg = IokeObject.ConvertToRational(arg, message, context, true);
                                                                                             }

                                                                                             return context.runtime.NewNumber(IntNum.shift(Number.IntValue(on), Number.IntValue(arg).intValue()));
                                                                                        })));

            integer.RegisterMethod(runtime.NewNativeMethod("returns this number right shifted by the argument",
                                                           new TypeCheckingNativeMethod(">>", TypeCheckingArgumentsDefinition.builder()
                                                                                        .ReceiverMustMimic(integer)
                                                                                        .WithRequiredPositional("other")
                                                                                        .Arguments,
                                                                                         (method, on, args, keywords, context, message) => {
                                                                                             object arg = args[0];
                                                                                             IokeData data = IokeObject.dataOf(arg);

                                                                                             if(!(data is Number)) {
                                                                                                 arg = IokeObject.ConvertToRational(arg, message, context, true);
                                                                                             }

                                                                                             return context.runtime.NewNumber(IntNum.shift(Number.IntValue(on), -Number.IntValue(arg).intValue()));
                                                                                        })));

            rational.RegisterMethod(runtime.NewNativeMethod("Returns a text representation of the object",
                                                            new TypeCheckingNativeMethod.WithNoArguments("asText", number,
                                                                                             (method, on, args, keywords, context, message) => {
                                                                                                 return runtime.NewText(on.ToString());
                                                                                             })));

            rational.RegisterMethod(obj.runtime.NewNativeMethod("Returns a text inspection of the object",
                                                                new TypeCheckingNativeMethod.WithNoArguments("inspect", number,
                                                                                                             (method, on, args, keywords, context, message) => {
                                                                                                                 return method.runtime.NewText(Number.GetInspect(on));
                                                                                                             })));

            rational.RegisterMethod(obj.runtime.NewNativeMethod("Returns a brief text inspection of the object",
                                                                new TypeCheckingNativeMethod.WithNoArguments("notice", number,
                                                                                                             (method, on, args, keywords, context, message) => {
                                                                                                                 return method.runtime.NewText(Number.GetInspect(on));
                                                                                                             })));

            integer.RegisterMethod(runtime.NewNativeMethod("Expects one or two arguments. If one argument is given, executes it as many times as the value of the receiving number. If two arguments are given, the first will be an unevaluated name that will receive the current loop value on each repitition. the iteration length is limited to the positive maximum of a Java int",
                                                           new NativeMethod("times", DefaultArgumentsDefinition.builder()
                                                                            .WithRequiredPositionalUnevaluated("argumentNameOrCode")
                                                                            .WithOptionalPositionalUnevaluated("code")
                                                                            .Arguments,
                                                                            (method, context, message, on, outer) => {
                                                                                outer.ArgumentsDefinition.CheckArgumentCount(context, message, on);

                                                                                int num = Number.GetValue(context.runtime.Integer.ConvertToThis(on, message, context)).intValue();
                                                                                if(message.Arguments.Count == 0) {
                                                                                    return runtime.nil;
                                                                                } else if(message.Arguments.Count == 1) {
                                                                                    object result = runtime.nil;
                                                                                    while(num > 0) {
                                                                                        result = ((Message)IokeObject.dataOf(message)).GetEvaluatedArgument(message, 0, context);
                                                                                        num--;
                                                                                    }
                                                                                    return result;
                                                                                } else {
                                                                                    int ix = 0;
                                                                                    string name = ((IokeObject)Message.GetArguments(message)[0]).Name;
                                                                                    object result = runtime.nil;
                                                                                    while(ix<num) {
                                                                                        context.SetCell(name, runtime.NewNumber(IntNum.make(ix)));
                                                                                        result = ((Message)IokeObject.dataOf(message)).GetEvaluatedArgument(message, 1, context);
                                                                                        ix++;
                                                                                    }
                                                                                    return result;
                                                                                }
                                                                            })));

            integer.RegisterMethod(runtime.NewNativeMethod("Returns a Text that represents the character with the same character code of this number",
                                                           new TypeCheckingNativeMethod.WithNoArguments("char", integer,
                                                                                                        (method, on, args, keywords, context, message) => {
                                                                                                            return runtime.NewText(Convert.ToString((char)Number.IntValue(on).intValue()));
                                                                                                        })));
        }
예제 #6
0
파일: IntNum.cs 프로젝트: vic/ioke
 public static IntNum times(IntNum x, IntNum y)
 {
     if (y.words == null)
         return times(x, y.ival);
     if (x.words == null)
         return times(y, x.ival);
     bool negative = false;
     int[] xwords;
     int[] ywords;
     int xlen = x.ival;
     int ylen = y.ival;
     if (x.isNegative ())
         {
             negative = true;
             xwords = new int[xlen];
             negate(xwords, x.words, xlen);
         }
     else
         {
             negative = false;
             xwords = x.words;
         }
     if (y.isNegative ())
         {
             negative = !negative;
             ywords = new int[ylen];
             negate(ywords, y.words, ylen);
         }
     else
         ywords = y.words;
     // Swap if x is shorter then y.
     if (xlen < ylen)
         {
             int[] twords = xwords;  xwords = ywords;  ywords = twords;
             int tlen = xlen;  xlen = ylen;  ylen = tlen;
         }
     IntNum result = IntNum.alloc (xlen+ylen);
     MPN.mul (result.words, xwords, xlen, ywords, ylen);
     result.ival = xlen+ylen;
     if (negative)
         result.setNegative ();
     return result.canonicalize ();
 }
예제 #7
0
파일: IntNum.cs 프로젝트: vic/ioke
 /** Subtract two IntNums, yielding their sum as another IntNum. */
 public static IntNum sub(IntNum x, IntNum y)
 {
     return add(x, y, -1);
 }
예제 #8
0
파일: IntNum.cs 프로젝트: vic/ioke
 public static IntNum remainder(IntNum x, IntNum y)
 {
     if (y.isZero())
         return x;
     IntNum rem = new IntNum ();
     divide (x, y, null, rem, TRUNCATE);
     return rem.canonicalize ();
 }
예제 #9
0
파일: IntNum.cs 프로젝트: vic/ioke
 /* Assumes x and y are both canonicalized. */
 public static bool equals(IntNum x, IntNum y)
 {
     if (x.words == null && y.words == null)
         return x.ival == y.ival;
     if (x.words == null || y.words == null || x.ival != y.ival)
         return false;
     for (int i = x.ival; --i >= 0; )
         {
             if (x.words[i] != y.words[i])
                 return false;
         }
     return true;
 }
예제 #10
0
파일: IntNum.cs 프로젝트: vic/ioke
 public static IntNum abs(IntNum x)
 {
     return x.isNegative () ? neg (x) : x;
 }
예제 #11
0
파일: IntNum.cs 프로젝트: vic/ioke
        /** Divide two integers, yielding quotient and remainder.
         * @param x the numerator in the division
         * @param y the denominator in the division
         * @param quotient is set to the quotient of the result (iff quotient!=null)
         * @param remainder is set to the remainder of the result
         *  (iff remainder!=null)
         * @param rounding_mode one of FLOOR, CEILING, TRUNCATE, or ROUND.
         */
        public static void divide(IntNum x, IntNum y,
                                   IntNum quotient, IntNum remainder,
                                   int rounding_mode)
        {
            if ((x.words == null || x.ival <= 2)
                && (y.words == null || y.ival <= 2))
                {
                    long x_l = x.longValue ();
                    long y_l = y.longValue ();
                    if (x_l != long.MinValue && y_l != long.MinValue)
                        {
                            divide (x_l, y_l, quotient, remainder, rounding_mode);
                            return;
                        }
                }

            bool xNegative = x.isNegative ();
            bool yNegative = y.isNegative ();
            bool qNegative = xNegative ^ yNegative;

            int ylen = y.words == null ? 1 : y.ival;
            int[] ywords = new int[ylen];
            y.getAbsolute (ywords);
            while (ylen > 1 && ywords[ylen-1] == 0)  ylen--;

            int xlen = x.words == null ? 1 : x.ival;
            int[] xwords = new int[xlen+2];
            x.getAbsolute (xwords);
            while (xlen > 1 && xwords[xlen-1] == 0)  xlen--;

            int qlen, rlen;

            int cmpval = MPN.cmp (xwords, xlen, ywords, ylen);
            if (cmpval < 0)  // abs(x) < abs(y)
                { // quotient = 0;  remainder = num.
                    int[] rwords = xwords;  xwords = ywords;  ywords = rwords;
                    rlen = xlen;  qlen = 1;  xwords[0] = 0;
                }
            else if (cmpval == 0)  // abs(x) == abs(y)
                {
                    xwords[0] = 1;  qlen = 1;  // quotient = 1
                    ywords[0] = 0;  rlen = 1;  // remainder = 0;
                }
            else if (ylen == 1)
                {
                    qlen = xlen;
                    rlen = 1;
                    ywords[0] = MPN.divmod_1 (xwords, xwords, xlen, ywords[0]);
                }
            else  // abs(x) > abs(y)
                {
                    // Normalize the denominator, i.e. make its most significant bit set by
                    // shifting it normalization_steps bits to the left.  Also shift the
                    // numerator the same number of steps (to keep the quotient the same!).

                    int nshift = MPN.count_leading_zeros (ywords[ylen-1]);
                    if (nshift != 0)
                        {
                            // Shift up the denominator setting the most significant bit of
                            // the most significant word.
                            MPN.lshift (ywords, 0, ywords, ylen, nshift);

                            // Shift up the numerator, possibly introducing a new most
                            // significant word.
                            int x_high = MPN.lshift (xwords, 0, xwords, xlen, nshift);
                            xwords[xlen++] = x_high;
                        }

                    if (xlen == ylen)
                        xwords[xlen++] = 0;
                    MPN.divide (xwords, xlen, ywords, ylen);
                    rlen = ylen;
                    MPN.rshift0 (ywords, xwords, 0, rlen, nshift);

                    qlen = xlen + 1 - ylen;
                    if (quotient != null)
                        {
                            for (int i = 0;  i < qlen;  i++)
                                xwords[i] = xwords[i+ylen];
                        }
                }

            while (rlen > 1 && ywords[rlen-1] == 0)
                rlen--;
            if (ywords[rlen-1] < 0)
                {
                    ywords[rlen] = 0;
                    rlen++;
                }

            // Now the quotient is in xwords, and the remainder is in ywords.

            bool add_one = false;
            if (rlen > 1 || ywords[0] != 0)
                { // Non-zero remainder i.e. in-exact quotient.
                    switch (rounding_mode)
                        {
                        case TRUNCATE:
                            break;
                        case CEILING:
                            if (qNegative == (rounding_mode == FLOOR))
                                add_one = true;
                            break;
                        case FLOOR:
                            if (qNegative == (rounding_mode == FLOOR))
                                add_one = true;
                            break;
                        case ROUND:
                            // int cmp = compare (remainder<<1, abs(y));
                            IntNum tmp = remainder == null ? new IntNum() : remainder;
                            tmp.set (ywords, rlen);
                            tmp = shift (tmp, 1);
                            if (yNegative)
                                tmp.setNegative();
                            int cmp = compare (tmp, y);
                            // Now cmp == compare(sign(y)*(remainder<<1), y)
                            if (yNegative)
                                cmp = -cmp;
                            add_one = (cmp == 1) || (cmp == 0 && (xwords[0]&1) != 0);
                            break;
                        }
                }
            if (quotient != null)
                {
                    if (xwords[qlen-1] < 0)
                        {
                            xwords[qlen] = 0;
                            qlen++;
                        }
                    quotient.set (xwords, qlen);
                    if (qNegative)
                        {
                            if (add_one)  // -(quotient + 1) == ~(quotient)
                                quotient.setInvert ();
                            else
                                quotient.setNegative ();
                        }
                    else if (add_one)
                        quotient.setAdd (1);
                }
            if (remainder != null)
                {
                    // The remainder is by definition: X-Q*Y
                    remainder.set (ywords, rlen);
                    if (add_one)
                        {
                            // Subtract the remainder from Y:
                            // abs(R) = abs(Y) - abs(orig_rem) = -(abs(orig_rem) - abs(Y)).
                            IntNum tmp;
                            if (y.words == null)
                                {
                                    tmp = remainder;
                                    tmp.set(yNegative ? ywords[0] + y.ival : ywords[0] - y.ival);
                                }
                            else
                                tmp = IntNum.add(remainder, y, yNegative ? 1 : -1);
                            // Now tmp <= 0.
                            // In this case, abs(Q) = 1 + floor(abs(X)/abs(Y)).
                            // Hence, abs(Q*Y) > abs(X).
                            // So sign(remainder) = -sign(X).
                            if (xNegative)
                                remainder.setNegative(tmp);
                            else
                                remainder.set(tmp);
                        }
                    else
                        {
                            // If !add_one, then: abs(Q*Y) <= abs(X).
                            // So sign(remainder) = sign(X).
                            if (xNegative)
                                remainder.setNegative ();
                        }
                }
        }
예제 #12
0
파일: IntNum.cs 프로젝트: vic/ioke
 static IntNum()
 {
     for (int i = numFixNum;  --i >= 0; )
         smallFixNums[i] = new IntNum(i + minFixNum);
 }
예제 #13
0
파일: IntNum.cs 프로젝트: vic/ioke
        public static void divide(long x, long y,
                                   IntNum quotient, IntNum remainder,
                                   int rounding_mode)
        {
            bool xNegative, yNegative;
            if (x < 0)
                {
                    xNegative = true;
                    if (x == long.MinValue)
                        {
                            divide (IntNum.make (x), IntNum.make (y),
                                    quotient, remainder, rounding_mode);
                            return;
                        }
                    x = -x;
                }
            else
                xNegative = false;

            if (y < 0)
                {
                    yNegative = true;
                    if (y == long.MinValue)
                        {
                            if (rounding_mode == TRUNCATE)
                                { // x != Long.Min_VALUE implies abs(x) < abs(y)
                                    if (quotient != null)
                                        quotient.set (0);
                                    if (remainder != null)
                                        remainder.set (x);
                                }
                            else
                                divide (IntNum.make (x), IntNum.make (y),
                                        quotient, remainder, rounding_mode);
                            return;
                        }
                    y = -y;
                }
            else
                yNegative = false;

            long q = x / y;
            long r = x % y;
            bool qNegative = xNegative ^ yNegative;

            bool add_one = false;
            if (r != 0)
                {
                    switch (rounding_mode)
                        {
                        case TRUNCATE:
                            break;
                        case CEILING:
                        case FLOOR:
                            if (qNegative == (rounding_mode == FLOOR))
                                add_one = true;
                            break;
                        case ROUND:
                            add_one = r > ((y - (q & 1)) >> 1);
                            break;
                        }
                }
            if (quotient != null)
                {
                    if (add_one)
                        q++;
                    if (qNegative)
                        q = -q;
                    quotient.set (q);
                }
            if (remainder != null)
                {
                    // The remainder is by definition: X-Q*Y
                    if (add_one)
                        {
                            // Subtract the remainder from Y.
                            r = y - r;
                            // In this case, abs(Q*Y) > abs(X).
                            // So sign(remainder) = -sign(X).
                            xNegative = ! xNegative;
                        }
                    else
                        {
                            // If !add_one, then: abs(Q*Y) <= abs(X).
                            // So sign(remainder) = sign(X).
                        }
                    if (xNegative)
                        r = -r;
                    remainder.set (r);
                }
        }
예제 #14
0
파일: IntNum.cs 프로젝트: vic/ioke
 void setShiftRight(IntNum x, int count)
 {
     if (x.words == null)
         set (count < 32 ? x.ival >> count : x.ival < 0 ? -1 : 0);
     else if (count == 0)
         set (x);
     else
         {
             bool neg = x.isNegative ();
             int word_count = count >> 5;
             count &= 31;
             int d_len = x.ival - word_count;
             if (d_len <= 0)
                 set (neg ? -1 : 0);
             else
                 {
                     if (words == null || words.Length < d_len)
                         realloc (d_len);
                     MPN.rshift0 (words, x.words, word_count, d_len, count);
                     ival = d_len;
                     if (neg)
                         words[d_len-1] |= -2 << (31 - count);
                 }
         }
 }
예제 #15
0
파일: IntNum.cs 프로젝트: vic/ioke
 void setShiftLeft(IntNum x, int count)
 {
     int[] xwords;
     int xlen;
     if (x.words == null)
         {
             if (count < 32)
                 {
                     set ((long) x.ival << count);
                     return;
                 }
             xwords = new int[1];
             xwords[0] = x.ival;
             xlen = 1;
         }
     else
         {
             xwords = x.words;
             xlen = x.ival;
         }
     int word_count = count >> 5;
     count &= 31;
     int new_len = xlen + word_count;
     if (count == 0)
         {
             realloc (new_len);
             for (int i = xlen;  --i >= 0; )
                 words[i+word_count] = xwords[i];
         }
     else
         {
             new_len++;
             realloc (new_len);
             int shift_out = MPN.lshift (words, word_count, xwords, xlen, count);
             count = 32 - count;
             words[new_len-1] = (shift_out << count) >> count;  // sign-extend.
         }
     ival = new_len;
     for (int i = word_count;  --i >= 0; )
         words[i] = 0;
 }
예제 #16
0
파일: IntNum.cs 프로젝트: vic/ioke
 /** Calculate the integral power of an IntNum.
  * @param x the value (base) to exponentiate
  * @param y the exponent (must be non-negative)
  */
 public static IntNum power(IntNum x, int y)
 {
     if (y <= 0)
         {
             if (y == 0)
                 return one ();
             else
                 throw new Exception ("negative exponent");
         }
     if (x.isZero ())
         return x;
     int plen = x.words == null ? 1 : x.ival;  // Length of pow2.
     int blen = ((x.intLength () * y) >> 5) + 2 * plen;
     bool negative = x.isNegative () && (y & 1) != 0;
     int[] pow2 = new int [blen];
     int[] rwords = new int [blen];
     int[] work = new int [blen];
     x.getAbsolute (pow2);	// pow2 = abs(x);
     int rlen = 1;
     rwords[0] = 1; // rwords = 1;
     for (;;)  // for (i = 0;  ; i++)
         {
             // pow2 == x**(2**i)
             // prod = x**(sum(j=0..i-1, (y>>j)&1))
             if ((y & 1) != 0)
                 { // r *= pow2
                     MPN.mul (work, pow2, plen, rwords, rlen);
                     int[] tempx = work;  work = rwords;  rwords = tempx;
                     rlen += plen;
                     while (rwords[rlen-1] == 0)  rlen--;
                 }
             y >>= 1;
             if (y == 0)
                 break;
             // pow2 *= pow2;
             MPN.mul (work, pow2, plen, pow2, plen);
             int[] temp = work;  work = pow2;  pow2 = temp;  // swap to avoid a copy
             plen *= 2;
             while (pow2[plen-1] == 0)  plen--;
         }
     if (rwords[rlen-1] < 0)
         rlen++;
     if (negative)
         negate (rwords, rwords, rlen);
     return IntNum.make (rwords, rlen);
 }
예제 #17
0
파일: IntNum.cs 프로젝트: vic/ioke
 public static IntNum quotient(IntNum x, IntNum y, int rounding_mode)
 {
     IntNum quotient = new IntNum ();
     divide (x, y, quotient, null, rounding_mode);
     return quotient.canonicalize ();
 }
예제 #18
0
파일: IntNum.cs 프로젝트: vic/ioke
 public static IntNum gcd(IntNum x, IntNum y)
 {
     int xval = x.ival;
     int yval = y.ival;
     if (x.words == null)
         {
             if (xval == 0)
                 return IntNum.abs(y);
             if (y.words == null
                 && xval != int.MinValue && yval != int.MinValue)
                 {
                     if (xval < 0)
                         xval = -xval;
                     if (yval < 0)
                         yval = -yval;
                     return IntNum.make (IntNum.gcd (xval, yval));
                 }
             xval = 1;
         }
     if (y.words == null)
         {
             if (yval == 0)
                 return IntNum.abs(x);
             yval = 1;
         }
     int len = (xval > yval ? xval : yval) + 1;
     int[] xwords = new int[len];
     int[] ywords = new int[len];
     x.getAbsolute (xwords);
     y.getAbsolute (ywords);
     len = MPN.gcd (xwords, ywords, len);
     IntNum result = new IntNum (0);
     result.ival = len;
     result.words = xwords;
     return result.canonicalize ();
 }
예제 #19
0
파일: IntNum.cs 프로젝트: vic/ioke
 public static IntNum quotient(IntNum x, IntNum y)
 {
     return quotient (x, y, TRUNCATE);
 }
예제 #20
0
파일: IntNum.cs 프로젝트: vic/ioke
 public static IntNum lcm(IntNum x, IntNum y)
 {
     if (x.isZero () || y.isZero ())
         return IntNum.zero ();
     x = IntNum.abs (x);
     y = IntNum.abs (y);
     IntNum quotient = new IntNum ();
     divide (times (x, y), gcd (x, y), quotient, null, TRUNCATE);
     return quotient.canonicalize ();
 }
예제 #21
0
파일: IntNum.cs 프로젝트: vic/ioke
 public static IntNum shift(IntNum x, int count)
 {
     if (x.words == null)
         {
             if (count <= 0)
                 return make (count > -32 ? x.ival >> (-count) : x.ival < 0 ? -1 : 0);
             if (count < 32)
                 return make ((long) x.ival << count);
         }
     if (count == 0)
         return x;
     IntNum result = new IntNum (0);
     result.setShift (x, count);
     return result.canonicalize ();
 }
예제 #22
0
파일: IntNum.cs 프로젝트: vic/ioke
 /** Make a canonicalized IntNum from an array of words.
  * The array may be reused (without copying). */
 public static IntNum make(int[] words, int len)
 {
     if (words == null)
         return make (len);
     len = IntNum.wordsNeeded (words, len);
     if (len <= 1)
         return len == 0 ? zero () : make (words[0]);
     IntNum num = new IntNum ();
     num.words = words;
     num.ival = len;
     return num;
 }
예제 #23
0
파일: IntNum.cs 프로젝트: vic/ioke
 public static IntNum times(IntNum x, int y)
 {
     if (y == 0)
         return zero();
     if (y == 1)
         return x;
     int[] xwords = x.words;
     int xlen = x.ival;
     if (xwords == null)
         return IntNum.make ((long) xlen * (long) y);
     bool negative;
     IntNum result = IntNum.alloc (xlen+1);
     if (xwords[xlen-1] < 0)
         {
             negative = true;
             negate(result.words, xwords, xlen);
             xwords = result.words;
         }
     else
         negative = false;
     if (y < 0)
         {
             negative = !negative;
             y = -y;
         }
     result.words[xlen] = MPN.mul_1 (result.words, xwords, xlen, y);
     result.ival = xlen+1;
     if (negative)
         result.setNegative ();
     return result.canonicalize ();
 }
예제 #24
0
파일: IntNum.cs 프로젝트: vic/ioke
 public static IntNum modulo(IntNum x, IntNum y)
 {
     if (y.isZero())
         return x;
     IntNum rem = new IntNum ();
     divide (x, y, null, rem, FLOOR);
     return rem.canonicalize ();
 }
예제 #25
0
파일: RatNum.cs 프로젝트: vic/ioke-outdated
 public override Numeric power(IntNum y)
 {
     //             bool inv;
     //             if (y.isNegative())
     //                 {
     //                     inv = true;
     //                     y = IntNum.neg(y);
     //                 }
     //             else
     //                 inv = false;
     //             if (y.words == null)
     //                 {
     //                     IntNum num = IntNum.power (numerator(), y.ival);
     //                     IntNum den = IntNum.power (denominator(), y.ival);
     //                     return inv ? RatNum.make (den, num) : RatNum.make (num, den);
     //                 }
     //             double d = doubleValue();
     //             bool neg = d < 0.0 && y.isOdd();
     //             d = Math.Pow (d, y.doubleValue());
     //             if (inv)
     //                 d = 1.0/d;
     return null;
 }
예제 #26
0
파일: IntNum.cs 프로젝트: vic/ioke
 public static IntNum neg(IntNum x)
 {
     if (x.words == null && x.ival != int.MinValue)
         return make (- x.ival);
     IntNum result = new IntNum (0);
     result.setNegative (x);
     return result.canonicalize ();
 }
예제 #27
0
파일: Runtime.cs 프로젝트: goking/ioke
 public IokeObject NewNumber(IntNum number)
 {
     if(numCache.ContainsKey(number))
         return numCache[number];
     IokeObject obj = this.Integer.AllocateCopy(null, null);
     obj.MimicsWithoutCheck(this.Integer);
     obj.Data = Ioke.Lang.Number.Integer(number);
     numCache[number] = obj;
     return obj;
 }
예제 #28
0
파일: IntNum.cs 프로젝트: vic/ioke
 /** Add two IntNums, yielding their sum as another IntNum. */
 public static IntNum add(IntNum x, IntNum y)
 {
     return add(x, y, 1);
 }
예제 #29
0
파일: Number.cs 프로젝트: nope/ioke
 public static Number Integer(IntNum val)
 {
     return new Number(val);
 }
예제 #30
0
파일: IntNum.cs 프로젝트: vic/ioke
 /** Return -1, 0, or 1, depending on which value is greater. */
 public static int compare(IntNum x, long y)
 {
     long x_word;
     if (x.words == null)
         x_word = x.ival;
     else
         {
             bool x_negative = x.isNegative ();
             bool y_negative = y < 0;
             if (x_negative != y_negative)
                 return x_negative ? -1 : 1;
             int x_len = x.words == null ? 1 : x.ival;
             if (x_len == 1)
                 x_word = x.words[0];
             else if (x_len == 2)
                 x_word = x.longValue();
             else // We assume x is canonicalized.
                 return x_negative ? -1 : 1;
         }
     return x_word < y ? -1 : x_word > y ? 1 : 0;
 }