/** * Calculates addition and puts the result into the given object. This method * is static and not destructive (except the result object). * * @param left * left operand * @param right * right operand * @param result * object to receive the calculation result */ public static void add(SignedInt128 left, SignedInt128 right, SignedInt128 result) { result.update(left); result.addDestructive(right); }
/** * Performs division and puts the quotient into the given object. This method * is static and not destructive (except the result object). * * @param left * left operand * @param right * right operand * @param quotient * result object to receive the calculation result * @param remainder * result object to receive the calculation result */ public static void divide(SignedInt128 left, SignedInt128 right, SignedInt128 quotient, SignedInt128 remainder) { if (quotient == left || quotient == right) { throw new IllegalArgumentException( "result object cannot be left or right operand"); } quotient.update(left); quotient.divideDestructive(right, remainder); }
@Test public void testSubtractDestructive() { two.subtractDestructive(one); assertEquals(1L, one.longValue()); assertEquals(1L, one.longValue()); one.subtractDestructive(new SignedInt128(10L)); assertEquals(-9L, one.longValue()); SignedInt128 big = new SignedInt128((1L << 62) + (3L << 34) + 3L); big.shiftLeftDestructive(6); SignedInt128 tmp = new SignedInt128((1L << 61) + 5L); tmp.shiftLeftDestructive(6); big.subtractDestructive(tmp); big.subtractDestructive(tmp); assertEquals((3 << 6) - 2 * (5 << 6), big.getV0()); assertEquals((3 << 8) - 1, big.getV1()); assertEquals(0, big.getV2()); assertEquals(0, big.getV3()); }
/** * This version returns the result as a new object, not modifying the give * objects. * * @param left * left operand * @param result * object to receive the calculation result */ public static void abs(SignedInt128 left, SignedInt128 result) { result.update(left); result.absDestructive(); }
/** * This version returns the result as a new object, not modifying the give * objects. * * @param left * left operand * @param result * object to receive the calculation result */ public static void decrement(SignedInt128 left, SignedInt128 result) { result.update(left); result.decrementDestructive(); }
/** * This version returns the result as a new object, not modifying the give * objects. * * @param left * left operand * @param result * object to receive the calculation result * @param bits * the number of bits. must be positive */ public static void shiftLeft(SignedInt128 left, SignedInt128 result, int bits) { result.update(left); result.shiftLeftDestructive(bits); }
@Test public void testMultiplyDestructiveInt() { two.multiplyDestructive(1); assertEquals(2L, two.longValue()); assertEquals(1L, one.longValue()); two.multiplyDestructive(2); assertEquals(4L, two.longValue()); SignedInt128 five = new SignedInt128(5); five.multiplyDestructive(6432346); assertEquals(6432346 * 5, five.getV0()); assertEquals(0, five.getV1()); assertEquals(0, five.getV2()); assertEquals(0, five.getV3()); SignedInt128 big = new SignedInt128((1L << 62) + (3L << 34) + 3L); big.multiplyDestructive(96); assertEquals(3 * 96, big.getV0()); assertEquals(96 * (3 << 2), big.getV1()); assertEquals(96 / 4, big.getV2()); assertEquals(0, big.getV3()); SignedInt128 tmp = new SignedInt128(1); tmp.shiftLeftDestructive(126); try { tmp.multiplyDestructive(2); fail(); } catch (ArithmeticException ex) { // ok } }
@Test public void testAddDestructive() { one.addDestructive(two); assertEquals(3L, one.longValue()); assertEquals(2L, two.longValue()); SignedInt128 big = new SignedInt128((1L << 62) + 3L); SignedInt128 tmp = new SignedInt128(0L); for (int i = 0; i < 54; ++i) { tmp.addDestructive(big); } assertEquals(3 * 54, tmp.getV0()); assertEquals(0x80000000, tmp.getV1()); // (54 % 4) << 62 assertEquals(13, tmp.getV2()); // 54/4 assertEquals(0, tmp.getV3()); assertEquals((1L << 62) + 3L, big.longValue()); SignedInt128 huge = new SignedInt128(one); huge.shiftLeftDestructive(125); SignedInt128 huge2 = new SignedInt128(one); huge2.shiftLeftDestructive(125); try { huge2.addDestructive(huge); fail(); } catch (ArithmeticException ex) { // ok } }
@Test public void testShiftDestructive() { SignedInt128 big = new SignedInt128((1L << 62) + (23L << 32) + 89L); big.shiftLeftDestructive(2); assertEquals(89 * 4, big.getV0()); assertEquals(23 * 4, big.getV1()); assertEquals(1, big.getV2()); assertEquals(0, big.getV3()); big.shiftLeftDestructive(32); assertEquals(0, big.getV0()); assertEquals(89 * 4, big.getV1()); assertEquals(23 * 4, big.getV2()); assertEquals(1, big.getV3()); big.shiftRightDestructive(2, true); assertEquals(0, big.getV0()); assertEquals(89, big.getV1()); assertEquals(23 + (1 << 30), big.getV2()); assertEquals(0, big.getV3()); big.shiftRightDestructive(32, true); assertEquals(89, big.getV0()); assertEquals(23 + (1 << 30), big.getV1()); assertEquals(0, big.getV2()); assertEquals(0, big.getV3());
@Test public void testDivideDestructiveSignedInt128() { SignedInt128 remainder = new SignedInt128(); two.divideDestructive(one, remainder); assertEquals(1L, one.longValue()); assertEquals(2L, two.longValue()); assertEquals(zero, remainder); one.divideDestructive(two, remainder); assertEquals(0L, one.longValue()); assertEquals(2L, two.longValue()); assertEquals(new SignedInt128(1), remainder); SignedInt128 var1 = new SignedInt128(1234234662345L); var1.divideDestructive(new SignedInt128(642337), remainder); assertEquals(1234234662345L / 642337L, var1.longValue()); assertEquals(1234234662345L % 642337L, remainder.longValue()); SignedInt128 complicated1 = new SignedInt128(0xF9892FCA, 0x59D109AD, 0x0534AB4C, 0x42395ADC); SignedInt128 complicated2 = new SignedInt128(0xF09DC19A, 0x00001234, 0, 0); BigInteger bigInteger1 = complicated1.toBigIntegerSlow(); BigInteger bigInteger2 = complicated2.toBigIntegerSlow(); complicated1.divideDestructive(complicated2, remainder); BigInteger ans = bigInteger1.divide(bigInteger2); assertEquals(ans, complicated1.toBigIntegerSlow()); try { complicated1.divideDestructive(zero, remainder); fail(); } catch (ArithmeticException ex) { // ok } }
@Test public void testZeroClear() { assertFalse(one.isZero()); assertFalse(two.isZero()); assertTrue(0L != one.longValue()); assertTrue(0L != two.longValue()); two.zeroClear(); assertTrue(0L != one.longValue()); assertEquals(0L, two.longValue()); assertFalse(one.isZero()); assertTrue(two.isZero()); one.zeroClear(); assertEquals(0L, one.longValue()); assertEquals(0L, two.longValue()); assertTrue(one.isZero()); assertTrue(two.isZero()); }
/** * Calculates subtraction and puts the result into the given object. This * method is static and not destructive (except the result object). * * @param left * left operand * @param right * right operand * @param result * object to receive the calculation result */ public static void subtract(SignedInt128 left, SignedInt128 right, SignedInt128 result) { result.update(left); result.subtractDestructive(right); }
/** * This version returns the result as a new object, not modifying the give * objects. * * @param left * left operand * @param result * object to receive the calculation result * @param bits * the number of bits. must be positive * @param roundUp * whether to round up the most significant bit that was discarded */ public static void shiftRight(SignedInt128 left, SignedInt128 result, int bits, boolean roundUp) { result.update(left); result.shiftRightDestructive(bits, roundUp); }
/** * Calculates multiplication and puts the result into the given object. This * method is static and not destructive (except the result object). * * @param left * left operand * @param right * right operand * @param result * object to receive the calculation result */ public static void multiply(SignedInt128 left, SignedInt128 right, SignedInt128 result) { if (result == left || result == right) { throw new IllegalArgumentException( "result object cannot be left or right operand"); } result.update(left); result.multiplyDestructive(right); }
@Test public void testDivideDestructiveSignedInt128Again() { SignedInt128 complicated1 = new SignedInt128(0xF9892FCA, 0x59D109AD, 0, 0); SignedInt128 complicated2 = new SignedInt128(0xF09DC19A, 3, 0, 0); BigInteger bigInteger1 = complicated1.toBigIntegerSlow(); BigInteger bigInteger2 = complicated2.toBigIntegerSlow(); complicated1.divideDestructive(complicated2, new SignedInt128()); BigInteger ans = bigInteger1.divide(bigInteger2); assertEquals(ans, complicated1.toBigIntegerSlow()); } }
@Test public void testSignedInt128SignedInt128() { assertEquals(1L, new SignedInt128(one).longValue()); assertEquals(2L, new SignedInt128(two).longValue()); }
@Override public double doubleValue() { return longValue(); }
/** * Updates the value of this object from the given string with given offset * and length. * * @param str * string * @param offset * offset * @param length * length */ public void update(char[] str, int offset, int length) { if (length == 0) { this.zeroClear(); return; } this.negative = false; if (str[offset] == '-') { this.negative = true; ++offset; --length; } else if (str[offset] == '+') { ++offset; --length; } this.mag.update(str, offset, length); if (this.mag.isZero()) { this.negative = false; } }
@Test public void testMultiplyDestructiveSignedInt128() { two.multiplyDestructive(one); assertEquals(2L, two.longValue()); assertEquals(1L, one.longValue()); two.multiplyDestructive(two); assertEquals(4L, two.longValue()); SignedInt128 five = new SignedInt128(5); five.multiplyDestructive(new SignedInt128(6432346)); assertEquals(6432346 * 5, five.getV0()); assertEquals(0, five.getV1()); assertEquals(0, five.getV2()); assertEquals(0, five.getV3()); SignedInt128 big = new SignedInt128((1L << 62) + (3L << 34) + 3L); big.multiplyDestructive(new SignedInt128(96)); assertEquals(3 * 96, big.getV0()); assertEquals(96 * (3 << 2), big.getV1()); assertEquals(96 / 4, big.getV2()); assertEquals(0, big.getV3()); SignedInt128 tmp = new SignedInt128(1); tmp.shiftLeftDestructive(126); try { tmp.multiplyDestructive(new SignedInt128(2)); fail(); } catch (ArithmeticException ex) {
@Test public void testDivideDestructiveInt() { two.divideDestructive(1); assertEquals(1L, one.longValue()); assertEquals(2L, two.longValue()); one.divideDestructive(2); assertEquals(0L, one.longValue()); assertEquals(2L, two.longValue()); SignedInt128 var1 = new SignedInt128(1234234662345L); var1.divideDestructive(642337); assertEquals(1234234662345L / 642337L, var1.longValue()); SignedInt128 complicated1 = new SignedInt128(0xF9892FCA, 0x59D109AD, 0x0534AB4C, 0); BigInteger bigInteger1 = complicated1.toBigIntegerSlow(); complicated1.divideDestructive(1534223465); BigInteger bigInteger2 = BigInteger.valueOf(1534223465); BigInteger ans = bigInteger1.divide(bigInteger2); assertEquals(ans, complicated1.toBigIntegerSlow()); try { complicated1.divideDestructive(0); fail(); } catch (ArithmeticException ex) { // ok } }