/** Return the logical (bit-wise) "and" of two IntNums. */ public static IntNum and(IntNum x, IntNum y) { if (y.words == null) { return(and(x, y.ival)); } else if (x.words == null) { return(and(y, x.ival)); } if (x.ival < y.ival) { IntNum temp = x; x = y; y = temp; } int i; int len = y.isNegative() ? x.ival : y.ival; int[] words = new int[len]; for (i = 0; i < y.ival; i++) { words[i] = x.words[i] & y.words[i]; } for ( ; i < len; i++) { words[i] = x.words[i]; } return(IntNum.make(words, len)); }
/** Converts an integral double (such as a toInt result) to an IntNum. */ public static IntNum toExactInt(double value) { if (Double.IsInfinity(value) || Double.IsNaN(value)) { throw new ArithmeticException("cannot convert " + value + " to exact integer"); } long bits = BitConverter.DoubleToInt64Bits(value); bool neg = bits < 0; int exp = (int)(bits >> 52) & 0x7FF; bits &= 0xfffffffffffffL; if (exp == 0) { bits <<= 1; } else { bits |= 0x10000000000000L; } if (exp <= 1075) { int rshift = 1075 - exp; if (rshift > 53) { return(IntNum.zero()); } bits >>= rshift; return(IntNum.make(neg ? -bits : bits)); } return(IntNum.shift(IntNum.make(neg ? -bits : bits), exp - 1075)); }
/** Return the logical (bit-wise) "and" of an IntNum and an int. */ public static IntNum and(IntNum x, int y) { if (x.words == null) { return(IntNum.make(x.ival & y)); } if (y >= 0) { return(IntNum.make(x.words[0] & y)); } int len = x.ival; int[] words = new int[len]; words[0] = x.words[0] & y; while (--len > 0) { words[len] = x.words[len]; } return(IntNum.make(words, x.ival)); }
/** Extract a bit-field as an unsigned integer. */ public static IntNum extract(IntNum x, int startBit, int endBit) { //System.err.print("extract(["); if (x.words!=null) MPN.dprint(x.words); //System.err.println (","+x.ival+"], start:"+startBit+", end:"+endBit); if (endBit < 32) { int word0 = x.words == null ? x.ival : x.words[0]; return(IntNum.make((word0 & ~((-1) << endBit)) >> startBit)); } int x_len; if (x.words == null) { if (x.ival >= 0) { return(IntNum.make(startBit >= 31 ? 0 : (x.ival >> startBit))); } x_len = 1; } else { x_len = x.ival; } bool neg = x.isNegative(); if (endBit > 32 * x_len) { endBit = 32 * x_len; if (!neg && startBit == 0) { return(x); } } else { x_len = (endBit + 31) >> 5; } int length = endBit - startBit; if (length < 64) { long l; if (x.words == null) { l = x.ival >> (startBit >= 32 ? 31 : startBit); } else { l = MPN.rshift_long(x.words, x_len, startBit); } return(IntNum.make(l & ~((-1L) << length))); } int startWord = startBit >> 5; // Allocate a work buffer, which has to be large enough for the result // AND large enough for all words we use from x (including possible // partial words at both ends). int buf_len = (endBit >> 5) + 1 - startWord; int[] buf = new int[buf_len]; if (x.words == null) // x < 0. { buf[0] = startBit >= 32 ? -1 : (x.ival >> startBit); } else { x_len -= startWord; startBit &= 31; MPN.rshift0(buf, x.words, startWord, x_len, startBit); } x_len = length >> 5; buf[x_len] &= ~((-1) << length); return(IntNum.make(buf, x_len + 1)); }
/** Return exact "rational" infinity. * @param sign either 1 or -1 for positive or negative infinity */ public static RatNum infinity(int sign) { return(new IntFraction(IntNum.make(sign), IntNum.zero())); }