diff --git a/bignum/src/commonMain/kotlin/com/ionspin/kotlin/bignum/integer/BigInteger.kt b/bignum/src/commonMain/kotlin/com/ionspin/kotlin/bignum/integer/BigInteger.kt index 05ee6473..24eb9843 100644 --- a/bignum/src/commonMain/kotlin/com/ionspin/kotlin/bignum/integer/BigInteger.kt +++ b/bignum/src/commonMain/kotlin/com/ionspin/kotlin/bignum/integer/BigInteger.kt @@ -635,8 +635,15 @@ class BigInteger internal constructor(wordArray: WordArray, requestedSign: Sign) return BigInteger(arithmetic.and(this.magnitude, other.magnitude), sign) } + /** Returns a new BigInt with bits combining [this], [other] doing a bitwise `|`/`or` operation. Forces sign to positive. */ + // TODO Investigate what is expected behavior when one of the operand is negative. Is it considered to be two's complement? override infix fun or(other: BigInteger): BigInteger { - return BigInteger(arithmetic.or(this.magnitude, other.magnitude), sign) + val resultMagnitude = arithmetic.or(this.magnitude, other.magnitude) + val resultSign = when { + isResultZero(resultMagnitude) -> Sign.ZERO + else -> Sign.POSITIVE + } + return BigInteger(resultMagnitude, resultSign) } override infix fun xor(other: BigInteger): BigInteger { diff --git a/bignum/src/commonMain/kotlin/com/ionspin/kotlin/bignum/integer/base63/array/BigInteger63Arithmetic.kt b/bignum/src/commonMain/kotlin/com/ionspin/kotlin/bignum/integer/base63/array/BigInteger63Arithmetic.kt index 397710f0..450c39b9 100644 --- a/bignum/src/commonMain/kotlin/com/ionspin/kotlin/bignum/integer/base63/array/BigInteger63Arithmetic.kt +++ b/bignum/src/commonMain/kotlin/com/ionspin/kotlin/bignum/integer/base63/array/BigInteger63Arithmetic.kt @@ -1972,6 +1972,7 @@ internal object BigInteger63Arithmetic : BigIntegerArithmetic { } override fun or(operand: ULongArray, mask: ULongArray): ULongArray { + if (operand.size < mask.size) return or(mask, operand) return removeLeadingZeros( ULongArray(operand.size) { if (it < mask.size) { diff --git a/bignum/src/commonTest/kotlin/com/ionspin/kotlin/bignum/integer/integer/BigIntegerBitwiseOperations.kt b/bignum/src/commonTest/kotlin/com/ionspin/kotlin/bignum/integer/integer/BigIntegerBitwiseOperations.kt index 5c70ceff..c3603b49 100644 --- a/bignum/src/commonTest/kotlin/com/ionspin/kotlin/bignum/integer/integer/BigIntegerBitwiseOperations.kt +++ b/bignum/src/commonTest/kotlin/com/ionspin/kotlin/bignum/integer/integer/BigIntegerBitwiseOperations.kt @@ -27,6 +27,42 @@ import kotlin.test.assertEquals * on 01-Nov-2019 */ class BigIntegerBitwiseOperations { + @Test + fun andWithZero() { + val operand = BigInteger.parseString("11110000", 2) + val mask = BigInteger.ZERO + + assertEquals(mask, operand and mask) + assertEquals(mask, mask and operand) + } + + @Test + fun andBiggerThanLongMaxWithZero() { + val operand = BigInteger.parseString("9223372036854775808", 10) + val mask = BigInteger.ZERO + + assertEquals(mask, operand and mask) + assertEquals(mask, mask and operand) + } + + @Test + fun orWithZero() { + val operand = BigInteger.parseString("11110000", 2) + val mask = BigInteger.ZERO + + assertEquals(operand, operand or mask) + assertEquals(operand, mask or operand) + } + + @Test + fun orBiggerThanLongMaxWithZero() { + val operand = BigInteger.parseString("9223372036854775808", 10) + val mask = BigInteger.ZERO + + assertEquals(operand, operand or mask) + assertEquals(operand, mask or operand) + } + @Test fun xorWithZero() { val operand = BigInteger.parseString("11110000", 2) @@ -34,10 +70,8 @@ class BigIntegerBitwiseOperations { val xorResult = operand xor mask println("Xor result: ${xorResult.toString(2)}") - val expectedResult = operand - - assertEquals(expectedResult, xorResult) - assertEquals(expectedResult, mask xor operand) + assertEquals(operand, xorResult) + assertEquals(operand, mask xor operand) } @Test @@ -45,9 +79,7 @@ class BigIntegerBitwiseOperations { val operand = BigInteger.parseString("9223372036854775808", 10) val mask = BigInteger.ZERO - val expectedResult = operand - - assertEquals(expectedResult, operand xor mask) - assertEquals(expectedResult, mask xor operand) + assertEquals(operand, operand xor mask) + assertEquals(operand, mask xor operand) } }