Repository: ionspin/kotlin-multiplatform-bignum
Pull request #24 (2019-04-22 19:13:15)

Modular integers
- Adding ModularBigInteger
- Reogranized class hierarchy, extracted BigNumber interface, Creator interface, common operation extensions helper
- Fixed several bugs
- Added GCD, modInverse
- Added integer reciprocal calucation based on D1Balanced algorithm (still slower than basecase because of slow multiplication)
- Several smaller issues


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0f5080e..61046cb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,20 @@
 ## Descriptive changelog
-(All dates are DD-MM-YYYY)
+(All dates are DD.MM.YYYY)
+
+##### 0.0.9-SNAPSHOT - 22.4.2019 Adding modular integer support, changing api
+- Added modular integers - ModularBigInteger
+- Added modInverse method to BigInteger
+- Extracted interfaces that model big numbers better (BigNumber<BigType> interface and accompanying interfaces)
+- Implemented integer reciprocal based on newton iteration (Based on paper by Yiping Cheng, Ze Lie : Refinement of a newton reciprocal algorithm for arbitrary precision numbers)
+- Implemented division by reciprocal multiplication. Not used by division at the moment as it is unoptimized and slower than basecase division in ealry benchmarks.
+- Fixed a bug in Int32 shift right when shift amount was an exact multiple of word size 
+- Added constructor overloads
+- Renamed invPrecise() bigInteger method to not()
+- Renamed numberOfDigits() to numberOfDecimalDigits()
+- Introduced BigNumber and BitwiseOperations interfaces 
+- Added iOS ARM 32bit support 
+
+
 ##### Minor update - 0.0.8 - 02.04.2019
 - Released ios (for X64 and arm) and macos X64 artifacts
 - No functional changes
diff --git a/README.md b/README.md
index cdc7e0e..e624181 100644
--- a/README.md
+++ b/README.md
@@ -213,6 +213,26 @@ println("Inv result: ${invResult.toString(2)}")
 Inv result: 1111
 ```
 
+#### Modular integers
+
+A `modInverse` function that is equivalent to java BigInteger `modInverse` is available. Note that this method will
+produce a **BigInteger** not a **ModularBigInteger**
+
+Big integers can be converted to modularIntegers with same modulo, and then `inverse()` method is available. This method 
+**will** return ModularBigInteger
+
+```kotlin
+val a = 100_002.toBigInteger()
+val modularA = a.toModularBigInteger(500.toBigInteger())
+println("ModularBigInteger: ${modularA.toStringWithModulo()}")
+----- Output -----
+ModularBigInteger: 2 mod 500
+```
+
+If you want to create more ModularBigIntegers with the same module, you can retrieve creator by calling `getCreator`
+
+More inforamtion about the ModularBigIntegers can be found in the third section
+
 ## Floating Point
 
 ### Creating
@@ -301,6 +321,7 @@ Standard arithmetic operations that are present:
 * Negate
 * Signum
 
+
 (Suspiciously missing is square root, both from BigInteger and BigDecimal, should be added soon™)
 
 Operations are executed with existing significands and then rounded down afterwards. Decimal mode parameter controls the precision and rounding mode
@@ -362,6 +383,29 @@ ROUND_HALF_TOWARDS_ZERO|Round towards nearest integer, using away from zero as t
 ROUND_HALF_CEILING|Round towards nearest integer, using towards infinity as tie breaker when significant digit being rounded is 5
 ROUND_HALF_FLOOR|Round towards nearest integer, using towards negative infinity as tie breaker when significant digit being rounded is 5
 
+### Modular Integers
+
+Modular arithmetic operations are supported only between integers with the same modulo. 
+
+## Creating Modular Integers
+
+First define the modulo you are going to use by getting an instance of the creator, and than 
+use that creator to create instances of modular integers
+
+```kotlin
+val creator = ModularBigInteger.creatorForModulo(100)
+val modularBigInteger = creator.fromLong(150)
+println("ModularBigInteger: ${modularBigInteger.toStringWithModulo()}")
+----- Output -----
+ModularBigInteger: 50 mod 100
+
+```
+
+Otherwise behavior is similar to normal integers
+
+
+### Sources
+
 For examples of rounding modes consult [Comparison of approaches for rounding to an integer](https://en.wikipedia.org/wiki/Rounding) 
 on Wikipedia
 
@@ -382,6 +426,14 @@ Second Edition
 Art of Computer Programming, Volume 2: Seminumerical Algorithms
 Donald E. Knuth
 3rd Edition
+```
+
+``
+Refinement of a newton reciprocal algorithm for arbitrary precision numbers
+Yiping Cheng,
+ Ze Liu
+
+
 ```
 And many other blogs and posts scattered over the internet.
 
diff --git a/bignum/src/commonMain/kotlin/com/ionspin/kotlin/bignum/BigNumber.kt b/bignum/src/commonMain/kotlin/com/ionspin/kotlin/bignum/BigNumber.kt
new file mode 100644
index 0000000..1408fd7
--- /dev/null
+++ b/bignum/src/commonMain/kotlin/com/ionspin/kotlin/bignum/BigNumber.kt
@@ -0,0 +1,239 @@
+/*
+ *    Copyright 2019 Ugljesa Jovanovic
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ *
+ */
+
+package com.ionspin.kotlin.bignum
+
+import com.ionspin.kotlin.bignum.integer.BigInteger
+
+
+/**
+ * Created by Ugljesa Jovanovic
+ * ugljesa.jovanovic@ionspin.com
+ * on 04-Apr-2019
+ */
+
+@ExperimentalUnsignedTypes
+interface BigNumber<BigType> where BigType : BigNumber<BigType> {
+
+    @ExperimentalUnsignedTypes
+    interface Creator<BigType> {
+        fun parseString(string: String, base: Int = 10): BigType
+        fun fromULong(uLong: ULong): BigType
+        fun fromUInt(uInt: UInt): BigType
+        fun fromUShort(uShort: UShort): BigType
+        fun fromUByte(uByte: UByte): BigType
+        fun fromLong(long: Long): BigType
+        fun fromInt(int: Int): BigType
+        fun fromShort(short: Short): BigType
+        fun fromByte(byte: Byte): BigType
+        fun fromBigInteger(bigInteger: BigInteger) : BigType
+    }
+    
+    interface Util<BigType> {
+        fun max(first: BigType, second: BigType): BigType
+        fun min(first: BigType, second: BigType): BigType
+    }
+
+    fun getCreator() : Creator<BigType>
+
+    fun add(other: BigType): BigType
+    fun subtract(other: BigType): BigType
+    fun multiply(other: BigType): BigType
+    fun divide(other: BigType): BigType
+
+    /**
+     * Remainder of integer division operation. Remainder has same sign as dividend.
+     */
+    fun remainder(other: BigType): BigType
+
+    /**
+     * Perform integer division and return quotient and remainder
+     */
+    fun divideAndRemainder(other: BigType): Pair<BigType, BigType>
+
+    fun isZero(): Boolean
+    /**
+     * Return additive inverse of this number
+     *
+     * i.e.
+     * ```  val a = 5.toBigInteger()
+     *      b = a.negate
+     *      b == -5.toBigInteger()
+     * ```
+     */
+    fun negate(): BigType
+
+    /**
+     * Return absolute value of this big integer
+     *
+     * i.e.
+     * ```  val a = -5.toBigInteger()
+     *      b = a.negate
+     *      b == -5.toBigInteger()
+     * ```
+     */
+    fun abs(): BigType
+
+    /**
+     * Return result of exponentiation of this number by supplied exponent
+     * i.e.
+     * ```  val a = 10.toBigInteger()
+     *      b = a.exp(2.toBigInteger())
+     *      b == 100.toBigInteger()
+     * ```
+     */
+    fun pow(exponent: BigType) : BigType
+    /**
+     * Return result of exponentiation of this number by supplied long exponent
+     * i.e.
+     * ```  val a = 10.toBigInteger()
+     *      b = a.exp(2L)
+     *      b == 100.toBigInteger()
+     * ```
+     */
+    fun pow(exponent: Long): BigType
+    /**
+     * Return result of exponentiation of this number by supplied integer exponent
+     * i.e.
+     * ```  val a = 10.toBigInteger()
+     *      b = a.exp(2)
+     *      b == 100.toBigInteger()
+     * ```
+     */
+    fun pow(exponent: Int): BigType
+    fun signum(): Int
+
+    /**
+     * Return the number of decimal digits representing this number
+     */
+    fun numberOfDecimalDigits() : Long
+
+
+
+    fun compareTo(other: Any): Int
+    override fun equals(other: Any?): Boolean
+
+    override fun toString(): String
+    fun toString(base: Int): String
+
+    operator fun unaryMinus(): BigType
+
+
+
+}
+
+@ExperimentalUnsignedTypes
+internal interface CommonBigNumberOperations<BigType> where BigType : BigNumber<BigType> {
+
+    fun getCreator() : BigNumber.Creator<BigType>
+
+    fun getInstance() : BigType
+
+    operator fun plus(other: BigType): BigType = getInstance().add(other)
+
+    operator fun minus(other: BigType): BigType = getInstance().subtract(other)
+
+    operator fun times(other: BigType): BigType = getInstance().multiply(other)
+
+    operator fun div(other: BigType): BigType = getInstance().divide(other)
+
+    /**
+     * Remainder of integer division operation. Returns the *least absolute remainder* (remainder has same sign as dividend)
+     */
+    operator fun rem(other: BigType): BigType = getInstance().remainder(other)
+
+    operator fun plus(int: Int): BigType = getInstance().add(getCreator().fromInt(int))
+
+    operator fun plus(long: Long): BigType = getInstance().add(getCreator().fromLong(long))
+
+    operator fun plus(short: Short): BigType = getInstance().add(getCreator().fromShort(short))
+
+    operator fun plus(byte: Byte): BigType = getInstance().add(getCreator().fromByte(byte))
+
+    operator fun times(int: Int): BigType = getInstance().multiply(getCreator().fromInt(int))
+
+    operator fun times(long: Long): BigType = getInstance().multiply(getCreator().fromLong(long))
+
+    operator fun times(short: Short): BigType = getInstance().multiply(getCreator().fromShort(short))
+
+    operator fun times(byte: Byte): BigType = getInstance().multiply(getCreator().fromByte(byte))
+
+    operator fun minus(int: Int): BigType = getInstance().subtract(getCreator().fromInt(int))
+
+    operator fun minus(long: Long): BigType = getInstance().subtract(getCreator().fromLong(long))
+
+    operator fun minus(short: Short): BigType = getInstance().subtract(getCreator().fromShort(short))
+
+    operator fun minus(byte: Byte): BigType = getInstance().subtract(getCreator().fromByte(byte))
+
+    operator fun div(int: Int): BigType = getInstance().divide(getCreator().fromInt(int))
+
+    operator fun div(long: Long): BigType = getInstance().divide(getCreator().fromLong(long))
+
+    operator fun div(short: Short): BigType = getInstance().divide(getCreator().fromShort(short))
+
+    operator fun div(byte: Byte): BigType = getInstance().divide(getCreator().fromByte(byte))
+
+    /**
+     * Remainder of integer division operation. Remainder has same sign as dividend
+     */
+    operator fun rem(int: Int): BigType = getInstance().remainder(getCreator().fromInt(int))
+
+    /**
+     * Remainder of integer division operation. Remainder has same sign as dividend
+     */
+    operator fun rem(long: Long): BigType = getInstance().remainder(getCreator().fromLong(long))
+
+    /**
+     * Remainder of integer division operation. Remainder has same sign as dividend
+     */
+    operator fun rem(short: Short): BigType = getInstance().remainder(getCreator().fromShort(short))
+
+    /**
+     * Remainder of integer division operation. Remainder has same sign as dividend.
+     */
+    operator fun rem(byte: Byte): BigType = getInstance().remainder(getCreator().fromByte(byte))
+
+}
+
+
+
+interface BitwiseCapable<BigType> {
+
+    infix fun shl(places: Int): BigType
+
+    infix fun shr(places: Int): BigType
+
+    infix fun and(other: BigType): BigType
+
+    infix fun or(other: BigType): BigType
+
+    infix fun xor(other: BigType): BigType
+
+    fun bitAt(position: Long): Boolean
+
+    fun setBitAt(position: Long, bit : Boolean) : BigType
+
+    /**
+     * Inverts only up to chosen [arithmetic] [BigTypeArithmetic.bitLength] bits.
+     * This is different from Java biginteger which returns inverse in two's complement.
+     *
+     * I.e.: If the number was "1100" binary, not returns "0011" => "11" => 4 decimal
+     */
+    fun not(): BigType
+
+}
\ No newline at end of file
diff --git a/bignum/src/commonMain/kotlin/com/ionspin/kotlin/bignum/QuotientAndRemainder.kt b/bignum/src/commonMain/kotlin/com/ionspin/kotlin/bignum/QuotientAndRemainder.kt
new file mode 100644
index 0000000..4522017
--- /dev/null
+++ b/bignum/src/commonMain/kotlin/com/ionspin/kotlin/bignum/QuotientAndRemainder.kt
@@ -0,0 +1,33 @@
+/*
+ *    Copyright 2019 Ugljesa Jovanovic
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ *
+ */
+
+package com.ionspin.kotlin.bignum
+
+import com.ionspin.kotlin.bignum.integer.BigInteger
+import com.ionspin.kotlin.bignum.modular.ModularBigInteger
+
+/**
+ * Created by Ugljesa Jovanovic
+ * ugljesa.jovanovic@ionspin.com
+ * on 04-Apr-2019
+ */
+
+@ExperimentalUnsignedTypes
+data class QuotientAndRemainder(val quotient: BigInteger, val remainder: BigInteger)
+
+@ExperimentalUnsignedTypes
+data class ModularQuotientAndRemainder(val quotient: ModularBigInteger, val remainder: ModularBigInteger)
\ No newline at end of file
diff --git a/bignum/src/commonMain/kotlin/com/ionspin/kotlin/bignum/decimal/BigDecimal.kt b/bignum/src/commonMain/kotlin/com/ionspin/kotlin/bignum/decimal/BigDecimal.kt
index af499fb..a42343f 100644
--- a/bignum/src/commonMain/kotlin/com/ionspin/kotlin/bignum/decimal/BigDecimal.kt
+++ b/bignum/src/commonMain/kotlin/com/ionspin/kotlin/bignum/decimal/BigDecimal.kt
@@ -17,9 +17,10 @@
 
 package com.ionspin.kotlin.bignum.decimal
 
+import com.ionspin.kotlin.bignum.BigNumber
+import com.ionspin.kotlin.bignum.CommonBigNumberOperations
 import com.ionspin.kotlin.bignum.integer.BigInteger
 import com.ionspin.kotlin.bignum.integer.BigInteger.Companion.TEN
-import com.ionspin.kotlin.bignum.integer.BigInteger.Companion.fromLong
 import com.ionspin.kotlin.bignum.integer.Sign
 import com.ionspin.kotlin.bignum.integer.toBigInteger
 import kotlin.math.max
@@ -43,11 +44,13 @@ class BigDecimal private constructor(
     val significand: BigInteger,
     val exponent: BigInteger = BigInteger.ZERO,
     val decimalMode: DecimalMode? = null
-) : Comparable<Any> {
+) : BigNumber<BigDecimal>,
+    CommonBigNumberOperations<BigDecimal>,
+    Comparable<Any> {
 
-    val precision = significand.numberOfDigits()
+    val precision = significand.numberOfDecimalDigits()
 
-    companion object {
+    companion object : BigNumber.Creator<BigDecimal> {
         val ZERO = BigDecimal(BigInteger.ZERO)
         val ONE = BigDecimal(BigInteger.ONE)
 
@@ -66,7 +69,7 @@ class BigDecimal private constructor(
             discarded: BigInteger,
             decimalMode: DecimalMode
         ): BigInteger {
-            val toDiscard = significand.numberOfDigits() - decimalMode.decimalPrecision
+            val toDiscard = significand.numberOfDecimalDigits() - decimalMode.decimalPrecision
             var result = if (toDiscard > 0) {
                 (significand divrem TEN.pow(toDiscard)).quotient
             } else {
@@ -78,9 +81,11 @@ class BigDecimal private constructor(
                 significand.sign
             }
             val significantRemainderDigit = if (toDiscard > 0) {
-                (discarded / (discarded.numberOfDigits())).abs() + (significand divrem TEN.pow(toDiscard)).remainder * TEN.pow(toDiscard)
+                (discarded / (discarded.numberOfDecimalDigits())).abs() + (significand divrem TEN.pow(toDiscard)).remainder * TEN.pow(
+                    toDiscard
+                )
             } else {
-                (discarded / (discarded.numberOfDigits())).abs()
+                (discarded / (discarded.numberOfDecimalDigits())).abs()
             }
             when (decimalMode.roundingMode) {
                 RoundingMode.AWAY_FROM_ZERO -> {
@@ -193,7 +198,7 @@ class BigDecimal private constructor(
             if (significand == BigInteger.ZERO) {
                 return BigDecimal(BigInteger.ZERO, exponent, decimalMode)
             }
-            val significandDigits = significand.numberOfDigits()
+            val significandDigits = significand.numberOfDecimalDigits()
             val desiredPrecision = decimalMode.decimalPrecision
             val newSignificand = when {
                 desiredPrecision > significandDigits -> {
@@ -216,6 +221,18 @@ class BigDecimal private constructor(
 
         }
 
+        /**
+         * Convert a Long into a BigDecimal.
+         *
+         * i.e. 7111 -> 7.111E+3
+         *
+         * @param long Long value to conver
+         * @return BigDecimal representing input
+         */
+        fun fromBigInteger(bigInteger: BigInteger, decimalMode: DecimalMode? = null): BigDecimal {
+            return BigDecimal(bigInteger, bigInteger.numberOfDecimalDigits().toBigInteger() - 1, decimalMode).round(decimalMode)
+        }
+
         /**
          * Convert a Long into a BigDecimal.
          *
@@ -226,7 +243,20 @@ class BigDecimal private constructor(
          */
         fun fromLong(long: Long, decimalMode: DecimalMode? = null): BigDecimal {
             val bigint = BigInteger.fromLong(long)
-            return BigDecimal(bigint, bigint.numberOfDigits().toBigInteger() - 1, decimalMode).round(decimalMode)
+            return BigDecimal(bigint, bigint.numberOfDecimalDigits().toBigInteger() - 1, decimalMode).round(decimalMode)
+        }
+
+        /**
+         * Convert a Long into a BigDecimal.
+         *
+         * i.e. 7111 -> 7.111E+3
+         *
+         * @param long Long value to conver
+         * @return BigDecimal representing input
+         */
+        fun fromULong(uLong: ULong, decimalMode: DecimalMode? = null): BigDecimal {
+            val bigint = BigInteger.fromULong(uLong)
+            return BigDecimal(bigint, bigint.numberOfDecimalDigits().toBigInteger() - 1, decimalMode).round(decimalMode)
         }
 
         /**
@@ -239,7 +269,33 @@ class BigDecimal private constructor(
          */
         fun fromInt(int: Int, decimalMode: DecimalMode? = null): BigDecimal {
             val bigint = BigInteger.fromInt(int)
-            return BigDecimal(bigint, bigint.numberOfDigits().toBigInteger() - 1, decimalMode).round(decimalMode)
+            return BigDecimal(bigint, bigint.numberOfDecimalDigits().toBigInteger() - 1, decimalMode).round(decimalMode)
+        }
+
+        /**
+         * Convert a Int into a BigDecimal.
+         *
+         * i.e. 7111 -> 7.111E+3
+         *
+         * @param int Int value to conver
+         * @return BigDecimal representing input
+         */
+        fun fromUInt(uInt: UInt, decimalMode: DecimalMode? = null): BigDecimal {
+            val bigint = BigInteger.fromUInt(uInt)
+            return BigDecimal(bigint, bigint.numberOfDecimalDigits().toBigInteger() - 1, decimalMode).round(decimalMode)
+        }
+
+        /**
+         * Convert a Short into a BigDecimal.
+         *
+         * i.e. 7111 -> 7.111E+3
+         *
+         * @param short Short value to conver
+         * @return BigDecimal representing input
+         */
+        fun fromUShort(uShort: UShort, decimalMode: DecimalMode? = null): BigDecimal {
+            val bigint = BigInteger.fromUShort(uShort)
+            return BigDecimal(bigint, bigint.numberOfDecimalDigits().toBigInteger() - 1, decimalMode).round(decimalMode)
         }
 
         /**
@@ -252,7 +308,20 @@ class BigDecimal private constructor(
          */
         fun fromShort(short: Short, decimalMode: DecimalMode? = null): BigDecimal {
             val bigint = BigInteger.fromShort(short)
-            return BigDecimal(bigint, bigint.numberOfDigits().toBigInteger() - 1, decimalMode).round(decimalMode)
+            return BigDecimal(bigint, bigint.numberOfDecimalDigits().toBigInteger() - 1, decimalMode).round(decimalMode)
+        }
+
+        /**
+         * Convert a Byte into a BigDecimal.
+         *
+         * i.e. 11 -> 1.1E+2
+         *
+         * @param byte Byte value to conver
+         * @return BigDecimal representing input
+         */
+        fun fromUByte(uByte: UByte, decimalMode: DecimalMode? = null): BigDecimal {
+            val bigint = BigInteger.fromUByte(uByte)
+            return BigDecimal(bigint, bigint.numberOfDecimalDigits().toBigInteger() - 1, decimalMode).round(decimalMode)
         }
 
         /**
@@ -265,7 +334,7 @@ class BigDecimal private constructor(
          */
         fun fromByte(byte: Byte, decimalMode: DecimalMode? = null): BigDecimal {
             val bigint = BigInteger.fromByte(byte)
-            return BigDecimal(bigint, bigint.numberOfDigits().toBigInteger() - 1, decimalMode).round(decimalMode)
+            return BigDecimal(bigint, bigint.numberOfDecimalDigits().toBigInteger() - 1, decimalMode).round(decimalMode)
         }
 
         /**
@@ -278,6 +347,7 @@ class BigDecimal private constructor(
          */
         fun fromLongAsSignificand(long: Long, decimalMode: DecimalMode? = null) =
             BigDecimal(BigInteger.fromLong(long), BigInteger.ZERO, decimalMode).round(decimalMode)
+
         /**
          * Convert a Int into a BigDecimal, but use supplied value directly as significant.
          *
@@ -320,8 +390,9 @@ class BigDecimal private constructor(
          * @return BigDecimal representing input
          */
         fun fromFloat(float: Float, decimalMode: DecimalMode? = null): BigDecimal {
-            return parseString(float.toString().dropLastWhile { it == '0' }, decimalMode)
+            return parseStringWithMode(float.toString().dropLastWhile { it == '0' }, decimalMode)
         }
+
         /**
          * Convert a Double into a BigDecimal
          *
@@ -331,7 +402,7 @@ class BigDecimal private constructor(
          * @return BigDecimal representing input
          */
         fun fromDouble(double: Double, decimalMode: DecimalMode? = null): BigDecimal {
-            return parseString(double.toString().dropLastWhile { it == '0' }, decimalMode)
+            return parseStringWithMode(double.toString().dropLastWhile { it == '0' }, decimalMode)
         }
 
         /**
@@ -340,10 +411,11 @@ class BigDecimal private constructor(
         fun fromBigIntegerWithExponent(
             bigInteger: BigInteger,
             exponent: BigInteger,
-            decimalMode: DecimalMode = DecimalMode()
+            decimalMode: DecimalMode? = null
         ): BigDecimal {
             return BigDecimal(bigInteger, exponent, decimalMode).round(decimalMode)
         }
+
         /**
          * Create BigDecimal from Long significand and BigInteger exponent
          */
@@ -355,6 +427,7 @@ class BigDecimal private constructor(
             val bigint = BigInteger.fromLong(long)
             return BigDecimal(bigint, exponent, decimalMode).round(decimalMode)
         }
+
         /**
          * Create BigDecimal from Int significand and BigInteger exponent
          */
@@ -362,6 +435,7 @@ class BigDecimal private constructor(
             val bigint = BigInteger.fromInt(int)
             return BigDecimal(bigint, exponent, decimalMode).round(decimalMode)
         }
+
         /**
          * Create BigDecimal from Short significand and BigInteger exponent
          */
@@ -373,6 +447,7 @@ class BigDecimal private constructor(
             val bigint = BigInteger.fromShort(short)
             return BigDecimal(bigint, exponent, decimalMode).round(decimalMode)
         }
+
         /**
          * Create BigDecimal from Short significand and BigInteger exponent
          */
@@ -384,27 +459,143 @@ class BigDecimal private constructor(
             val bigint = BigInteger.fromByte(byte)
             return BigDecimal(bigint, exponent, decimalMode).round(decimalMode)
         }
+
         /**
          * Create BigDecimal from Long significand and Int exponent
          */
         fun fromLongWithExponent(long: Long, exponent: Int, decimalMode: DecimalMode? = null): BigDecimal =
             fromLongWithExponent(long, exponent.toBigInteger(), decimalMode).round(decimalMode)
+
         /**
          * Create BigDecimal from Int significand and Int exponent
          */
         fun fromIntWithExponent(int: Int, exponent: Int, decimalMode: DecimalMode? = null): BigDecimal =
             fromIntWithExponent(int, exponent.toBigInteger()).round(decimalMode)
+
         /**
          * Create BigDecimal from Short significand and Int exponent
          */
         fun fromShortWithExponent(short: Short, exponent: Int, decimalMode: DecimalMode = DecimalMode()): BigDecimal =
             fromShortWithExponent(short, exponent.toBigInteger(), decimalMode).round(decimalMode)
+
         /**
          * Create BigDecimal from Byte significand and Int exponent
          */
         fun fromByteWithExponent(byte: Byte, exponent: Int, decimalMode: DecimalMode? = null): BigDecimal =
             fromByteWithExponent(byte, exponent.toBigInteger(), decimalMode).round(decimalMode)
 
+        /**
+         * Convert a BigInteger into a BigDecimal, but use supplied value directly as significant.
+         *
+         * i.e. 7111 -> 7.111E+0
+         *
+         * @param long Long value to conver
+         * @return BigDecimal representing input
+         */
+        override fun fromBigInteger(bigInteger: BigInteger): BigDecimal {
+            return fromBigInteger(bigInteger, null)
+        }
+
+        /**
+         * Convert a Long into a BigDecimal, but use supplied value directly as significant.
+         *
+         * i.e. 7111 -> 7.111E+0
+         *
+         * @param long Long value to conver
+         * @return BigDecimal representing input
+         */
+        override fun fromULong(uLong: ULong): BigDecimal {
+            return fromULong(uLong, null)
+        }
+
+        /**
+         * Convert a Int into a BigDecimal, but use supplied value directly as significant.
+         *
+         * i.e. 7111 -> 7.111E+0
+         *
+         * @param int Int value to conver
+         * @return BigDecimal representing input
+         */
+        override fun fromUInt(uInt: UInt): BigDecimal {
+            return fromUInt(uInt,null)
+        }
+
+        /**
+         * Convert a Short into a BigDecimal, but use supplied value directly as significant.
+         *
+         * i.e. 7111 -> 7.111E+0
+         *
+         * @param short Short value to conver
+         * @return BigDecimal representing input
+         */
+        override fun fromUShort(uShort: UShort): BigDecimal {
+            return fromUShort(uShort, null)
+        }
+
+        /**
+         * Convert a Short into a BigDecimal, but use supplied value directly as significant.
+         *
+         * i.e. 7111 -> 7.111E+0
+         *
+         * @param short Short value to conver
+         * @return BigDecimal representing input
+         */
+        override fun fromUByte(uByte: UByte): BigDecimal {
+            return fromUByte(uByte, null)
+        }
+
+        /**
+         * Convert a Long into a BigDecimal
+         *
+         * i.e. 7111 -> 7.111E+3
+         *
+         * @param long Long value to conver
+         * @return BigDecimal representing input
+         */
+        override fun fromLong(long: Long): BigDecimal {
+            return fromLong(long, null)
+        }
+
+        /**
+         * Convert a Int into a BigDecimal
+         *
+         * i.e. 7111 -> 7.111E+3
+         *
+         * @param int Int value to conver
+         * @return BigDecimal representing input
+         */
+        override fun fromInt(int: Int): BigDecimal {
+            return fromInt(int, null)
+        }
+
+        /**
+         * Convert a Short into a BigDecimal, but use supplied value directly as significant.
+         *
+         * i.e. 7111 -> 7.111E+3
+         *
+         * @param short Short value to conver
+         * @return BigDecimal representing input
+         */
+        override fun fromShort(short: Short): BigDecimal {
+            return fromShort(short, null)
+        }
+
+        /**
+         * Convert a Short into a BigDecimal, but use supplied value directly as significant.
+         *
+         * i.e. 7111 -> 7.111E+0
+         *
+         * @param short Short value to conver
+         * @return BigDecimal representing input
+         */
+        override fun fromByte(byte: Byte): BigDecimal {
+            return fromByte(byte, null)
+        }
+
+        override fun parseString(string: String, base: Int): BigDecimal {
+            return parseStringWithMode(string, null)
+        }
+
         /**
          * Parse BigDecimal from a supplied string. The string can be in either of two different formats:
          *
@@ -417,7 +608,7 @@ class BigDecimal private constructor(
          * @return Parsed string
          * @throws ArithmeticException if parsing fails
          */
-        fun parseString(floatingPointString: String, decimalMode: DecimalMode? = null): BigDecimal {
+        fun parseStringWithMode(floatingPointString: String, decimalMode: DecimalMode? = null): BigDecimal {
             if (floatingPointString.isEmpty()) {
                 return ZERO
             }
@@ -546,17 +737,27 @@ class BigDecimal private constructor(
                     }
                 } else {
                     val significand = BigInteger.parseString(floatingPointString, 10)
-                    return BigDecimal(significand, BigInteger.fromLong(significand.numberOfDigits() - 1), decimalMode)
+                    return BigDecimal(
+                        significand,
+                        BigInteger.fromLong(significand.numberOfDecimalDigits() - 1),
+                        decimalMode
+                    )
                 }
             }
 
         }
 
-        private fun resolveDecimalMode(firstDecimalMode: DecimalMode?, secondDecimalMode : DecimalMode?, suppliedDecimalMode: DecimalMode?) : DecimalMode {
+        private fun resolveDecimalMode(
+            firstDecimalMode: DecimalMode?,
+            secondDecimalMode: DecimalMode?,
+            suppliedDecimalMode: DecimalMode?
+        ): DecimalMode {
             return if (suppliedDecimalMode != null) {
                 suppliedDecimalMode
             } else {
-                if (firstDecimalMode == null && secondDecimalMode == null) { return DecimalMode() }
+                if (firstDecimalMode == null && secondDecimalMode == null) {
+                    return DecimalMode()
+                }
                 if (firstDecimalMode == null && secondDecimalMode != null) {
                     return secondDecimalMode
                 }
@@ -576,25 +777,39 @@ class BigDecimal private constructor(
         }
     }
 
+    override fun getCreator(): BigNumber.Creator<BigDecimal> = BigDecimal
+    override fun getInstance(): BigDecimal = this
+
     val isExponentLong = exponent.numberOfWords == 0
     val longExponent = exponent.magnitude[0]
 
+
     /**
-     * Add two BigDecimal and return result in a new instance of BigDecimal
+     * Add two BigDecimal and return result in a new instance of BigDecimal. Default decimal mode will be used.
      *
      * @param other BigDecimal (addend)
      * @return BigDecimal containing result of the operation
      */
-    fun addition(other: BigDecimal, decimalMode: DecimalMode? = null): BigDecimal {
+    override fun add(other: BigDecimal): BigDecimal {
+        return add(other, null)
+    }
+
+    /**
+     * Add two BigDecimal and return result in a new instance of BigDecimal.
+     *
+     * @param other BigDecimal (addend)
+     * @return BigDecimal containing result of the operation
+     */
+    fun add(other: BigDecimal, decimalMode: DecimalMode? = null): BigDecimal {
         val resolvedDecimalMode = resolveDecimalMode(this.decimalMode, other.decimalMode, decimalMode)
         val (first, second, _) = bringSignificandToSameExponent(this, other)
         //Temporary way to detect a carry happened, proper solution is to add
         //methods that return information about carry in arithmetic classes, this way it's going
         //to be rather slow
-        val firstNumOfDigits = first.numberOfDigits()
-        val secondNumOfDigits = second.numberOfDigits()
+        val firstNumOfDigits = first.numberOfDecimalDigits()
+        val secondNumOfDigits = second.numberOfDecimalDigits()
         val newSignificand = first + second
-        val newSignificandNumOfDigit = newSignificand.numberOfDigits()
+        val newSignificandNumOfDigit = newSignificand.numberOfDecimalDigits()
         val largerOperand = if (firstNumOfDigits > secondNumOfDigits) {
             firstNumOfDigits
         } else {
@@ -605,22 +820,34 @@ class BigDecimal private constructor(
 
         return roundOrDont(newSignificand, newExponent, resolvedDecimalMode)
     }
+
+    /**
+     * Subtract two BigDecimal and return result in a new instance of BigDecimal.
+     * Default decimal mode will be used
+     *
+     * @param other BigDecimal (subtrahend)
+     * @return BigDecimal containing result of the operation
+     */
+    override fun subtract(other: BigDecimal): BigDecimal {
+        return subtract(other, null)
+    }
+
     /**
      * Subtract two BigDecimal and return result in a new instance of BigDecimal
      *
      * @param other BigDecimal (subtrahend)
      * @return BigDecimal containing result of the operation
      */
-    fun subtraction(other: BigDecimal, decimalMode: DecimalMode? = null): BigDecimal {
+    fun subtract(other: BigDecimal, decimalMode: DecimalMode? = null): BigDecimal {
         val resolvedDecimalMode = resolveDecimalMode(this.decimalMode, other.decimalMode, decimalMode)
         val (first, second, _) = bringSignificandToSameExponent(this, other)
 
-        val firstNumOfDigits = first.numberOfDigits()
-        val secondNumOfDigits = second.numberOfDigits()
+        val firstNumOfDigits = first.numberOfDecimalDigits()
+        val secondNumOfDigits = second.numberOfDecimalDigits()
 
         val newSignificand = first - second
 
-        val newSignificandNumOfDigit = newSignificand.numberOfDigits()
+        val newSignificandNumOfDigit = newSignificand.numberOfDecimalDigits()
 
         val largerOperand = if (firstNumOfDigits > secondNumOfDigits) {
             firstNumOfDigits
@@ -633,36 +860,51 @@ class BigDecimal private constructor(
         return roundOrDont(newSignificand, newExponent, resolvedDecimalMode)
     }
 
+    /**
+     * Multiply two BigDecimal and return result in a new instance of BigDecimal
+     * Default decimal mode will be used
+     * @param other BigDecimal (multiplicand)
+     * @return BigDecimal containing result of the operation
+     */
+    override fun multiply(other: BigDecimal): BigDecimal {
+        return multiply(other, null)
+    }
+
     /**
      * Multiply two BigDecimal and return result in a new instance of BigDecimal
      *
      * @param other BigDecimal (multiplicand)
      * @return BigDecimal containing result of the operation
      */
-    fun multiplication(other: BigDecimal, decimalMode: DecimalMode? = null): BigDecimal {
+    fun multiply(other: BigDecimal, decimalMode: DecimalMode? = null): BigDecimal {
         val resolvedDecimalMode = resolveDecimalMode(this.decimalMode, other.decimalMode, decimalMode)
         //Temporary way to detect a carry happened, proper solution is to add
         //methods that return information about carry in arithmetic classes, this way it's going
         //to be rather slow
-        val firstNumOfDigits = this.significand.numberOfDigits()
-        val secondNumOfDigits = other.significand.numberOfDigits()
+        val firstNumOfDigits = this.significand.numberOfDecimalDigits()
+        val secondNumOfDigits = other.significand.numberOfDecimalDigits()
 
         val newSignificand = this.significand * other.significand
 
-        val newSignificandNumOfDigit = newSignificand.numberOfDigits()
+        val newSignificandNumOfDigit = newSignificand.numberOfDecimalDigits()
         val moveExponent = newSignificandNumOfDigit - (firstNumOfDigits + secondNumOfDigits)
 
         val newExponent = this.exponent + other.exponent + moveExponent + 1
         return roundOrDont(newSignificand, newExponent, resolvedDecimalMode)
 
     }
+
+    override fun divide(other : BigDecimal) : BigDecimal {
+        return divide(other, null)
+    }
+
     /**
      * Divide two BigDecimal and return result in a new instance of BigDecimal
      *
      * @param other BigDecimal (divisor)
      * @return BigDecimal containing result of the operation
      */
-    fun div(other: BigDecimal, decimalMode: DecimalMode? = null): BigDecimal {
+    fun divide(other: BigDecimal, decimalMode: DecimalMode? = null): BigDecimal {
         val resolvedDecimalMode = resolveDecimalMode(this.decimalMode, other.decimalMode, decimalMode)
         var newExponent = this.exponent - other.exponent - 1
 
@@ -685,7 +927,7 @@ class BigDecimal private constructor(
         if (result == BigInteger.ZERO) {
             newExponent--
         }
-        val exponentModifier = result.numberOfDigits() - resolvedDecimalMode.decimalPrecision
+        val exponentModifier = result.numberOfDecimalDigits() - resolvedDecimalMode.decimalPrecision
         if (divRem.remainder != BigInteger.ZERO && resolvedDecimalMode.decimalPrecision == 0L && resolvedDecimalMode.roundingMode == RoundingMode.NONE) {
             throw ArithmeticException("Non-terminating result of division operation. Specify decimalPrecision")
         }
@@ -695,32 +937,48 @@ class BigDecimal private constructor(
             resolvedDecimalMode
         )
 
-//        var newExponent = this.exponent - other.exponent
-//
-//        var divRem = this.significand divrem other.significand
-//        var result = divRem.quotient
-//        if (result == BigInteger.ZERO) {
-//            newExponent--
-//        }
-//        var counter = 0
-//        while (divRem.remainder != BigInteger.ZERO) {
-//            divRem = (divRem.remainder * 10) divrem other.significand
-//            counter++
-//            //Until rounding and decimalPrecision is fully implemented
-//            if (counter == 100) {
-//                break
-//            }
-//            result = result * 10 + divRem.quotient
-//        }
-//        return roundOrDont(result, newExponent, decimalMode)
     }
 
+    override fun remainder(other: BigDecimal): BigDecimal {
+        TODO()
+    }
+
+    override fun divideAndRemainder(other: BigDecimal): Pair<BigDecimal, BigDecimal> {
+        TODO("not implemented yet")
+    }
+
+    override fun isZero(): Boolean {
+        return significand.isZero()
+    }
+
+    override fun pow(exponent: BigDecimal): BigDecimal {
+        TODO()
+    }
+
+    override fun pow(exponent: Int): BigDecimal {
+        TODO("not implemented yet")
+    }
 
+    /**
+     * Returns the number of digits representing this number
+     * i.e. 12.345 will return 5
+     */
+    override fun numberOfDecimalDigits(): Long {
+        return significand.numberOfDecimalDigits()
+    }
+
+
+    override fun toString(base: Int): String {
+        if (base != 10) {
+            throw RuntimeException("BigDecimal in base other than 10 is not supported yet")
+        }
+        return toString()
+    }
 
     //TODO
     private fun integerDiv(other: BigDecimal, decimalMode: DecimalMode? = null): BigDecimal {
         val resolvedDecimalMode = resolveDecimalMode(this.decimalMode, other.decimalMode, decimalMode)
-        val (first, second) = bringSignificandToSameExponent(this, other)
+//        val (first, second) = bringSignificandToSameExponent(this, other)
         val newExponent = this.exponent - other.exponent
         val newSignificand = this.significand / other.significand
         return roundOrDont(newSignificand, newExponent, resolvedDecimalMode)
@@ -728,7 +986,7 @@ class BigDecimal private constructor(
 
     private fun rem(other: BigDecimal, decimalMode: DecimalMode? = null): BigDecimal {
         val resolvedDecimalMode = resolveDecimalMode(this.decimalMode, other.decimalMode, decimalMode)
-        val (first, second) = bringSignificandToSameExponent(this, other)
+//        val (first, second) = bringSignificandToSameExponent(this, other)
         val newExponent = this.exponent - other.exponent
         val newSignificand = this.significand % other.significand
         return roundOrDont(newSignificand, newExponent, resolvedDecimalMode)
@@ -746,30 +1004,30 @@ class BigDecimal private constructor(
         )
     }
 
-    operator fun plus(other: BigDecimal): BigDecimal {
-        return this.addition(other, DecimalMode())
+    override operator fun plus(other: BigDecimal): BigDecimal {
+        return this.add(other, null)
     }
 
-    operator fun minus(other: BigDecimal): BigDecimal {
-        return this.subtraction(other, DecimalMode())
+    override operator fun minus(other: BigDecimal): BigDecimal {
+        return this.subtract(other, null)
     }
 
-    operator fun times(other: BigDecimal): BigDecimal {
-        return this.multiplication(other, DecimalMode())
+    override operator fun times(other: BigDecimal): BigDecimal {
+        return this.multiply(other, null)
     }
 
-    operator fun div(other: BigDecimal): BigDecimal {
-        return this.div(other, DecimalMode())
+    override operator fun div(other: BigDecimal): BigDecimal {
+        return this.divide(other, null)
     }
 
-    operator fun rem(other: BigDecimal): BigDecimal {
-        return this.rem(other, DecimalMode())
+    override operator fun rem(other: BigDecimal): BigDecimal {
+        return this.rem(other, null)
     }
 
     /**
      * Returns a new negated instance
      */
-    fun unaryMinus(): BigDecimal {
+    override fun unaryMinus(): BigDecimal {
         return BigDecimal(significand.negate(), exponent)
     }
 
@@ -790,29 +1048,29 @@ class BigDecimal private constructor(
     /**
      * Return Absolute value
      */
-    fun abs(): BigDecimal {
+    override fun abs(): BigDecimal {
         return BigDecimal(significand.abs(), exponent)
     }
 
     /**
      * Negate this BigDecimal
      */
-    fun negate(): BigDecimal {
+    override fun negate(): BigDecimal {
         return BigDecimal(significand.negate(), exponent)
     }
 
     /**
      * Exponentiate this BigDecimal by some exponent
      */
-    fun pow(powerExponent: Long): BigDecimal {
-        return BigDecimal(significand, exponent * powerExponent)
+    override fun pow(exponent: Long): BigDecimal {
+        return BigDecimal(significand, this.exponent * exponent)
     }
 
     /**
      * Signum function
      * @return Result of signum function for this BigDecimal (-1 negative, 0 zero, 1 positive)
      */
-    fun signum() : Int = significand.signum()
+    override fun signum(): Int = significand.signum()
 
     /**
      * Round using specific [DecimalMode] and return rounded instance
@@ -821,14 +1079,11 @@ class BigDecimal private constructor(
         if (decimalMode == null) {
             return this
         }
-        if (decimalMode == DecimalMode()) {
-            return this
-        }
         return Companion.round(this.significand, this.exponent, decimalMode)
     }
 
     private fun getRidOfRadix(bigDecimal: BigDecimal): BigDecimal {
-        val precision = bigDecimal.significand.numberOfDigits()
+        val precision = bigDecimal.significand.numberOfDecimalDigits()
         val newExponent = bigDecimal.exponent - precision + 1
         return BigDecimal(bigDecimal.significand, newExponent)
     }
@@ -892,43 +1147,10 @@ class BigDecimal private constructor(
         }
 
 
-//
-//
-//        val firstDigits = first.significand.numberOfDigits()
-//        val secondDigits = second.significand.numberOfDigits()
-//        val firstExponent = first.exponent
-//        val secondExponent = second.exponent
-//
-//        val firstMove = firstDigits  - 1
-//        val secondMove = secondDigits - 1
-//
-//        val firstFreeOfRadix =
-//
-//
-//        return when {
-//            firstExponent > secondExponent -> {
-//                val exponentDifference = firstExponent - secondExponent + secondMove - firstMove
-//
-//                val preparedFirst = first.significand * 10.toBigInteger().pow(exponentDifference)
-//                return Triple(preparedFirst, second.significand, firstExponent)
-//            }
-//            firstExponent < secondExponent -> {
-//                val exponentDifference = secondExponent - firstExponent + firstMove - secondMove
-//                val preparedSecond = second.significand * 10.toBigInteger().pow(exponentDifference)
-//                return Triple(first.significand, preparedSecond, secondExponent)
-//            }
-//            firstExponent == secondExponent -> {
-//                return Triple(first.significand, second.significand, firstExponent)
-//            }
-//            else -> {
-//                throw RuntimeException("Invalid comparison state BigInteger: $firstExponent, $secondExponent")
-//            }
-//        }
-
     }
 
     /**
-     * Compare to ther BigDecimal
+     * Compare to other BigDecimal
      */
     fun compare(other: BigDecimal): Int {
         if (exponent == other.exponent) {
@@ -962,6 +1184,10 @@ class BigDecimal private constructor(
         return comparison == 0
     }
 
+    override fun hashCode(): Int {
+        return significand.hashCode() + exponent.hashCode() + decimalMode.hashCode()
+    }
+
     /**
      * Return this BigDecimal in scientific notation
      * i.e. 1.23E+9
@@ -1008,7 +1234,7 @@ class BigDecimal private constructor(
      * i.e. 123000000 for 1.23E+9 or 0.00000000123 for 1.23E-9
      */
     fun toStringExpanded(): String {
-        val digits = significand.numberOfDigits()
+        val digits = significand.numberOfDecimalDigits()
         if (exponent > Int.MAX_VALUE) {
             throw RuntimeException("Invalid toStringExpanded request (exponent > Int.MAX_VALUE)")
         }
@@ -1018,7 +1244,6 @@ class BigDecimal private constructor(
         return when {
             exponent > 0 -> {
                 val diffBigInt = (exponent - digits + 1)
-                val diffInt = diffBigInt.magnitude[0].toInt()
 
                 if (diffBigInt > 0) {
                     val expandZeroes = diffBigInt * '0'
@@ -1059,122 +1284,4 @@ class BigDecimal private constructor(
 
     }
 
-
-//
-//
-// ----------------- Interop with basic types ----------------------
-//
-//
-
-
-// ------------- Addition -----------
-
-
-    operator fun plus(int: Int): BigDecimal {
-        return this.plus(BigDecimal.fromIntAsSignificand(int))
-    }
-
-
-    operator fun plus(long: Long): BigDecimal {
-        return this.plus(BigDecimal.fromLongAsSignificand(long))
-    }
-
-
-    operator fun plus(short: Short): BigDecimal {
-        return this.plus(BigDecimal.fromShortAsSignificand(short))
-    }
-
-
-    operator fun plus(byte: Byte): BigDecimal {
-        return this.plus(BigDecimal.fromByteAsSignificand(byte))
-    }
-
-// ------------- Multiplication -----------
-
-
-    operator fun times(int: Int): BigDecimal {
-        return this.multiplication(BigDecimal.fromIntAsSignificand(int))
-    }
-
-
-    operator fun times(long: Long): BigDecimal {
-        return this.multiplication(BigDecimal.fromLongAsSignificand(long))
-    }
-
-
-    operator fun times(short: Short): BigDecimal {
-        return this.multiplication(BigDecimal.fromShortAsSignificand(short))
-    }
-
-
-    operator fun times(byte: Byte): BigDecimal {
-        return this.multiplication(BigDecimal.fromByteAsSignificand(byte))
-    }
-
-
-// ------------- Subtraction -----------
-
-
-    operator fun minus(int: Int): BigDecimal {
-        return this.minus(BigDecimal.fromIntAsSignificand(int))
-    }
-
-
-    operator fun minus(long: Long): BigDecimal {
-        return this.minus(BigDecimal.fromLongAsSignificand(long))
-    }
-
-
-    operator fun minus(short: Short): BigDecimal {
-        return this.minus(BigDecimal.fromShortAsSignificand(short))
-    }
-
-
-    operator fun minus(byte: Byte): BigDecimal {
-        return this.minus(BigDecimal.fromByteAsSignificand(byte))
-    }
-
-// ------------- Division -----------
-
-
-    operator fun div(int: Int): BigDecimal {
-        return this.div(BigDecimal.fromIntAsSignificand(int))
-    }
-
-
-    operator fun div(long: Long): BigDecimal {
-        return this.div(BigDecimal.fromLongAsSignificand(long))
-    }
-
-
-    operator fun div(short: Short): BigDecimal {
-        return this.div(BigDecimal.fromShortAsSignificand(short))
-    }
-
-
-    operator fun div(byte: Byte): BigDecimal {
-        return this.div(BigDecimal.fromByteAsSignificand(byte))
-    }
-
-
-    operator fun rem(int: Int): BigDecimal {
-        return this.rem(BigDecimal.fromIntAsSignificand(int))
-    }
-
-
-    operator fun rem(long: Long): BigDecimal {
-        return this.rem(BigDecimal.fromLongAsSignificand(long))
-    }
-
-
-    operator fun rem(short: Short): BigDecimal {
-        return this.rem(BigDecimal.fromShortAsSignificand(short))
-    }
-
-
-    operator fun rem(byte: Byte): BigDecimal {
-        return this.rem(BigDecimal.fromByteAsSignificand(byte))
-    }
-
-
 }
\ No newline at end of file
diff --git a/bignum/src/commonMain/kotlin/com/ionspin/kotlin/bignum/decimal/BigDecimalExtensions.kt b/bignum/src/commonMain/kotlin/com/ionspin/kotlin/bignum/decimal/BigDecimalExtensions.kt
index 9bee0fc..ce0f6f5 100644
--- a/bignum/src/commonMain/kotlin/com/ionspin/kotlin/bignum/decimal/BigDecimalExtensions.kt
+++ b/bignum/src/commonMain/kotlin/com/ionspin/kotlin/bignum/decimal/BigDecimalExtensions.kt
@@ -49,7 +49,7 @@ fun Byte.toBigDecimal(decimalMode: DecimalMode? = null): BigDecimal {
 
 @ExperimentalUnsignedTypes
 fun String.toBigDecimal(decimalMode: DecimalMode? = null) : BigDecimal {
-    return BigDecimal.parseString(this, decimalMode)
+    return BigDecimal.parseStringWithMode(this, decimalMode)
 }
 
 @ExperimentalUnsignedTypes
diff --git a/bignum/src/commonMain/kotlin/com/ionspin/kotlin/bignum/decimal/DecimalMode.kt b/bignum/src/commonMain/kotlin/com/ionspin/kotlin/bignum/decimal/DecimalMode.kt
index 7f94711..47ed226 100644
--- a/bignum/src/commonMain/kotlin/com/ionspin/kotlin/bignum/decimal/DecimalMode.kt
+++ b/bignum/src/commonMain/kotlin/com/ionspin/kotlin/bignum/decimal/DecimalMode.kt
@@ -71,4 +71,11 @@ enum class RoundingMode {
 //    ROUND_HALF_TO_ODD
 }
 
-data class DecimalMode(val decimalPrecision : Long = 0, val roundingMode : RoundingMode = RoundingMode.NONE)
\ No newline at end of file
+data class DecimalMode(val decimalPrecision : Long = 0, val roundingMode : RoundingMode = RoundingMode.NONE) {
+    companion object {
+        /**
+         * Default decimal mode, infinite precision, no rounding
+         */
+        val DEFAULT = DecimalMode()
+    }
+}
\ No newline at end of file
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 032b012..ddff777 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
@@ -17,7 +17,12 @@
 
 package com.ionspin.kotlin.bignum.integer
 
+import com.ionspin.kotlin.bignum.BigNumber
+import com.ionspin.kotlin.bignum.BitwiseCapable
+import com.ionspin.kotlin.bignum.CommonBigNumberOperations
+import com.ionspin.kotlin.bignum.modular.ModularBigInteger
 import kotlin.math.ceil
+import kotlin.math.floor
 import kotlin.math.log10
 
 
@@ -53,17 +58,27 @@ enum class Sign {
  * Based on unsigned arrays, currently limited to [Int.MAX_VALUE] words.
  */
 @ExperimentalUnsignedTypes
-class BigInteger private constructor(wordArray: WordArray, val sign: Sign) : Comparable<Any> {
+class BigInteger internal constructor(wordArray: WordArray, val sign: Sign) : BigNumber<BigInteger>,
+    CommonBigNumberOperations<BigInteger>,
+    BitwiseCapable<BigInteger>, Comparable<Any> {
 
-    constructor(long : Long) : this(arithmetic.fromLong(long), determinSignFromNumber(long))
-    constructor(int : Int) : this(arithmetic.fromInt(int), determinSignFromNumber(int))
-    constructor(short : Short) : this(arithmetic.fromShort(short), determinSignFromNumber(short))
-    constructor(byte : Byte) : this(arithmetic.fromByte(byte), determinSignFromNumber(byte))
 
+    constructor(long: Long) : this(arithmetic.fromLong(long), determinSignFromNumber(long))
+    constructor(int: Int) : this(arithmetic.fromInt(int), determinSignFromNumber(int))
+    constructor(short: Short) : this(arithmetic.fromShort(short), determinSignFromNumber(short))
+    constructor(byte: Byte) : this(arithmetic.fromByte(byte), determinSignFromNumber(byte))
+
+    override fun getCreator(): BigNumber.Creator<BigInteger> {
+        return BigInteger
+    }
+
+    override fun getInstance(): BigInteger {
+        return this
+    }
 
     @ExperimentalUnsignedTypes
-    companion object {
-        private val arithmetic : BigIntegerArithmetic<WordArray, Word> = chosenArithmetic
+    companion object : BigNumber.Creator<BigInteger>, BigNumber.Util<BigInteger> {
+        private val arithmetic: BigIntegerArithmetic<WordArray, Word> = chosenArithmetic
 
         val ZERO = BigInteger(arithmetic.ZERO, Sign.ZERO)
         val ONE = BigInteger(arithmetic.ONE, Sign.POSITIVE)
@@ -71,7 +86,7 @@ class BigInteger private constructor(wordArray: WordArray, val sign: Sign) : Com
 
         val LOG_10_OF_2 = log10(2.0)
 
-        fun parseString(string: String, base: Int = 10): BigInteger {
+        override fun parseString(string: String, base: Int): BigInteger {
             val signed = (string[0] == '-' || string[0] == '+')
             return if (signed) {
                 if (string.length == 1) {
@@ -140,17 +155,18 @@ class BigInteger private constructor(wordArray: WordArray, val sign: Sign) : Com
             }
 
         }
-
-        fun fromULong(uLong: ULong) = BigInteger(arithmetic.fromULong(uLong), Sign.POSITIVE)
-        fun fromUInt(uInt: UInt) = BigInteger(arithmetic.fromUInt(uInt), Sign.POSITIVE)
-        fun fromUShort(uShort: UShort) = BigInteger(arithmetic.fromUShort(uShort), Sign.POSITIVE)
-        fun fromUByte(uByte: UByte) = BigInteger(arithmetic.fromUByte(uByte), Sign.POSITIVE)
-        fun fromLong(long: Long) = BigInteger(long)
-        fun fromInt(int: Int) = BigInteger(int)
-        fun fromShort(short: Short) = BigInteger(short)
-        fun fromByte(byte: Byte) = BigInteger(byte)
-
-        fun max(first: BigInteger, second: BigInteger): BigInteger {
+        //BigIntegers are immutable so this is pointless, but the rest of creator implementations use this.
+        override fun fromBigInteger(bigInteger: BigInteger): BigInteger { return bigInteger }
+        override fun fromULong(uLong: ULong) = BigInteger(arithmetic.fromULong(uLong), Sign.POSITIVE)
+        override fun fromUInt(uInt: UInt) = BigInteger(arithmetic.fromUInt(uInt), Sign.POSITIVE)
+        override fun fromUShort(uShort: UShort) = BigInteger(arithmetic.fromUShort(uShort), Sign.POSITIVE)
+        override fun fromUByte(uByte: UByte) = BigInteger(arithmetic.fromUByte(uByte), Sign.POSITIVE)
+        override fun fromLong(long: Long) = BigInteger(long)
+        override fun fromInt(int: Int) = BigInteger(int)
+        override fun fromShort(short: Short) = BigInteger(short)
+        override fun fromByte(byte: Byte) = BigInteger(byte)
+
+        override fun max(first: BigInteger, second: BigInteger): BigInteger {
             return if (first > second) {
                 first
             } else {
@@ -158,7 +174,7 @@ class BigInteger private constructor(wordArray: WordArray, val sign: Sign) : Com
             }
         }
 
-        fun min(first: BigInteger, second: BigInteger): BigInteger {
+        override fun min(first: BigInteger, second: BigInteger): BigInteger {
             return if (first < second) {
                 first
             } else {
@@ -175,9 +191,9 @@ class BigInteger private constructor(wordArray: WordArray, val sign: Sign) : Com
 
     val numberOfWords = magnitude.size
 
-    var stringRepresentation : String? = null
+    var stringRepresentation: String? = null
 
-    fun add(other: BigInteger): BigInteger {
+    override fun add(other: BigInteger): BigInteger {
         val comparison = arithmetic.compare(this.magnitude, other.magnitude)
         return if (other.sign == this.sign) {
             return BigInteger(arithmetic.add(this.magnitude, other.magnitude), sign)
@@ -197,10 +213,14 @@ class BigInteger private constructor(wordArray: WordArray, val sign: Sign) : Com
 
     }
 
-    fun subtract(other: BigInteger): BigInteger {
+    override fun subtract(other: BigInteger): BigInteger {
         val comparison = arithmetic.compare(this.magnitude, other.magnitude)
-        if (this == ZERO) { return other.negate()}
-        if (other == ZERO) { return this }
+        if (this == ZERO) {
+            return other.negate()
+        }
+        if (other == ZERO) {
+            return this
+        }
         return if (other.sign == this.sign) {
             when {
                 comparison > 0 -> {
@@ -218,7 +238,7 @@ class BigInteger private constructor(wordArray: WordArray, val sign: Sign) : Com
         }
     }
 
-    fun multiply(other: BigInteger): BigInteger {
+    override fun multiply(other: BigInteger): BigInteger {
         if (this.isZero() || other.isZero()) {
             return ZERO
         }
@@ -235,7 +255,7 @@ class BigInteger private constructor(wordArray: WordArray, val sign: Sign) : Com
         }
     }
 
-    fun divide(other: BigInteger): BigInteger {
+    override fun divide(other: BigInteger): BigInteger {
         if (other.isZero()) {
             throw ArithmeticException("Division by zero! $this / $other")
         }
@@ -255,20 +275,24 @@ class BigInteger private constructor(wordArray: WordArray, val sign: Sign) : Com
 
     }
 
-    fun remainder(other: BigInteger): BigInteger {
+    override fun remainder(other: BigInteger): BigInteger {
         if (other.isZero()) {
             throw ArithmeticException("Division by zero! $this / $other")
         }
-        val sign = if (this.sign != other.sign) {
+        var sign = if (this.sign != other.sign) {
             Sign.NEGATIVE
         } else {
             Sign.POSITIVE
         }
+        val result = arithmetic.divide(this.magnitude, other.magnitude).second
+        if (result == arithmetic.ZERO) {
+            sign = Sign.ZERO
+        }
 
-        return BigInteger(arithmetic.divide(this.magnitude, other.magnitude).second, sign)
+        return BigInteger(result, sign)
     }
 
-    fun divideAndRemainder(other: BigInteger): Pair<BigInteger, BigInteger> {
+    override fun divideAndRemainder(other: BigInteger): Pair<BigInteger, BigInteger> {
         if (other.isZero()) {
             throw ArithmeticException("Division by zero! $this / $other")
         }
@@ -294,6 +318,64 @@ class BigInteger private constructor(wordArray: WordArray, val sign: Sign) : Com
         )
     }
 
+
+    /**
+     * D1Balanced reciprocal
+     */
+    private fun d1reciprocalRecursive(): BigInteger {
+        return BigInteger(arithmetic.reciprocal(this.magnitude).first, sign)
+
+
+    }
+
+    fun sqrt(): SqareRootAndRemainder {
+        return naiveSqrtRem()
+    }
+
+    fun naiveSqrtRem() : SqareRootAndRemainder {
+        TODO()
+//        var l = floor((numberOfWords - 1).toDouble() / 4).toInt()
+//        if (l == 0) return
+    }
+
+//    fun basecaseSqrt() : SqareRootAndRemainder {
+//
+//    }
+
+    fun gcd(other: BigInteger) : BigInteger {
+        return naiveGcd(other)
+    }
+
+    private fun naiveGcd(other : BigInteger) : BigInteger {
+        var u = this
+        var v = other
+        while (v != ZERO) {
+            val tmpU = u
+            u = v
+            v = tmpU % v
+        }
+        return u
+    }
+
+    fun modInverse(modulo: BigInteger) : BigInteger {
+        if (gcd(modulo) != ONE) {
+            throw ArithmeticException("BigInteger is not invertible. This and modulo are not relatively prime (coprime)")
+        }
+        var u = ONE
+        var w = ZERO
+        var b = this
+        var c = modulo
+        while (c != ZERO) {
+            val (q,r) = b divrem c
+            b = c
+            c = r
+            val tmpU = u
+            u = w
+            w = tmpU - q*w
+        }
+        return u
+    }
+
     fun compare(other: BigInteger): Int {
         if (isZero() && other.isZero()) return 0
         if (other.isZero() && this.sign == Sign.POSITIVE) return 1
@@ -304,24 +386,24 @@ class BigInteger private constructor(wordArray: WordArray, val sign: Sign) : Com
         return arithmetic.compare(this.magnitude, other.magnitude)
     }
 
-    fun isZero(): Boolean = this.sign == Sign.ZERO
+    override fun isZero(): Boolean = this.sign == Sign.ZERO
 
-    fun negate(): BigInteger {
+    override fun negate(): BigInteger {
         return BigInteger(wordArray = this.magnitude.copyOf(), sign = sign.not())
     }
 
-    fun abs(): BigInteger {
+    override fun abs(): BigInteger {
         return BigInteger(wordArray = this.magnitude.copyOf(), sign = Sign.POSITIVE)
     }
 
-    fun pow(exponent: BigInteger) : BigInteger {
+    override fun pow(exponent: BigInteger): BigInteger {
         if (exponent <= Long.MAX_VALUE) {
             return pow(exponent.magnitude[0].toLong())
         }
         //TODO this is not efficient
         var counter = exponent
         var result = ONE
-        while(counter > 0) {
+        while (counter > 0) {
             counter--
             result *= this
         }
@@ -329,7 +411,7 @@ class BigInteger private constructor(wordArray: WordArray, val sign: Sign) : Com
         return result
     }
 
-    fun pow(exponent: Long): BigInteger {
+    override fun pow(exponent: Long): BigInteger {
         val sign = if (sign == Sign.NEGATIVE) {
             if (exponent % 2 == 0L) {
                 Sign.POSITIVE
@@ -342,25 +424,25 @@ class BigInteger private constructor(wordArray: WordArray, val sign: Sign) : Com
         return BigInteger(arithmetic.pow(magnitude, exponent), sign)
     }
 
-    fun pow(exponent: Int): BigInteger {
+    override fun pow(exponent: Int): BigInteger {
         return pow(exponent.toLong())
     }
 
-    fun signum(): Int = when (sign) {
+    override fun signum(): Int = when (sign) {
         Sign.POSITIVE -> 1
         Sign.NEGATIVE -> -1
         Sign.ZERO -> 0
     }
 
-    fun bitAt(position: Long): Boolean {
+    override fun bitAt(position: Long): Boolean {
         return arithmetic.bitAt(magnitude, position)
     }
 
-    fun setBitAt(position: Long, bit : Boolean) : BigInteger {
+    override fun setBitAt(position: Long, bit: Boolean): BigInteger {
         return BigInteger(arithmetic.setBitAt(magnitude, position, bit), sign)
     }
 
-    fun numberOfDigits() : Long {
+    override fun numberOfDecimalDigits(): Long {
         val bitLenght = arithmetic.bitLength(magnitude)
         val minDigit = ceil((bitLenght - 1) * LOG_10_OF_2)
 //        val maxDigit = floor(bitLenght * LOG_10_OF_2) + 1
@@ -375,7 +457,7 @@ class BigInteger private constructor(wordArray: WordArray, val sign: Sign) : Com
         var counter = 0L
         while (tmp.compareTo(0) != 0) {
             tmp /= 10
-            counter ++
+            counter++
         }
         return counter + minDigit.toInt()
 
@@ -383,44 +465,23 @@ class BigInteger private constructor(wordArray: WordArray, val sign: Sign) : Com
     }
 
 
-
-
-    infix fun shl(places: Int): BigInteger {
+    override infix fun shl(places: Int): BigInteger {
         return BigInteger(arithmetic.shiftLeft(this.magnitude, places), sign)
     }
 
-    infix fun shr(places: Int): BigInteger {
+    override infix fun shr(places: Int): BigInteger {
         return BigInteger(arithmetic.shiftRight(this.magnitude, places), sign)
     }
 
-    operator fun unaryMinus(): BigInteger = negate()
+    override operator fun unaryMinus(): BigInteger = negate()
 
-    operator fun plus(other: BigInteger): BigInteger {
-        return add(other)
-    }
-
-    operator fun minus(other: BigInteger): BigInteger {
-        return subtract(other)
-    }
-
-    operator fun times(other: BigInteger): BigInteger {
-        return multiply(other)
-    }
-
-    operator fun div(other: BigInteger): BigInteger {
-        return divide(other)
-    }
 
-    operator fun rem(other: BigInteger): BigInteger {
-        return remainder(other)
+    operator fun dec(): BigInteger {
+        return this - ONE
     }
 
-    operator fun dec() : BigInteger {
-        return this - 1
-    }
-
-    operator fun inc() : BigInteger {
-        return this + 1
+    operator fun inc(): BigInteger {
+        return this + ONE
     }
 
     infix fun divrem(other: BigInteger): QuotientAndRemainder {
@@ -428,15 +489,15 @@ class BigInteger private constructor(wordArray: WordArray, val sign: Sign) : Com
         return QuotientAndRemainder(result.first, result.second)
     }
 
-    infix fun and(other: BigInteger): BigInteger {
+    override infix fun and(other: BigInteger): BigInteger {
         return BigInteger(arithmetic.and(this.magnitude, other.magnitude), sign)
     }
 
-    infix fun or(other: BigInteger): BigInteger {
+    override infix fun or(other: BigInteger): BigInteger {
         return BigInteger(arithmetic.or(this.magnitude, other.magnitude), sign)
     }
 
-    infix fun xor(other: BigInteger): BigInteger {
+    override infix fun xor(other: BigInteger): BigInteger {
         return BigInteger(arithmetic.xor(this.magnitude, other.magnitude), sign)
     }
 
@@ -444,19 +505,19 @@ class BigInteger private constructor(wordArray: WordArray, val sign: Sign) : Com
      * Inverts only up to chosen [arithmetic] [BigIntegerArithmetic.bitLength] bits.
      * This is different from Java biginteger which returns inverse in two's complement.
      *
-     * I.e.: If the number was "1100" binary, invPrecise returns "0011" => "11" => 4 decimal
+     * I.e.: If the number was "1100" binary, not returns "0011" => "11" => 4 decimal
      */
-    fun invPrecise(): BigInteger {
-        return BigInteger(arithmetic.inv(this.magnitude), sign)
+    override fun not(): BigInteger {
+        return BigInteger(arithmetic.not(this.magnitude), sign)
     }
 
     override fun compareTo(other: Any): Int {
         return when (other) {
             is BigInteger -> compare(other)
-            is Long -> compare(BigInteger.fromLong(other))
-            is Int -> compare(BigInteger.fromInt(other))
-            is Short -> compare(BigInteger.fromShort(other))
-            is Byte -> compare(BigInteger.fromByte(other))
+            is Long -> compare(fromLong(other))
+            is Int -> compare(fromInt(other))
+            is Short -> compare(fromShort(other))
+            is Byte -> compare(fromByte(other))
             else -> throw RuntimeException("Invalid comparison type for BigInteger: ${other::class.simpleName}")
         }
 
@@ -465,15 +526,18 @@ class BigInteger private constructor(wordArray: WordArray, val sign: Sign) : Com
     override fun equals(other: Any?): Boolean {
         val comparison = when (other) {
             is BigInteger -> compare(other)
-            is Long -> compare(BigInteger.fromLong(other))
-            is Int -> compare(BigInteger.fromInt(other))
-            is Short -> compare(BigInteger.fromShort(other))
-            is Byte -> compare(BigInteger.fromByte(other))
+            is Long -> compare(fromLong(other))
+            is Int -> compare(fromInt(other))
+            is Short -> compare(fromShort(other))
+            is Byte -> compare(fromByte(other))
             else -> -1
         }
         return comparison == 0
     }
 
+    override fun hashCode(): Int {
+        return magnitude.contentHashCode() + sign.hashCode()
+    }
 
     override fun toString(): String {
         //TODO think about limiting the size of string, and offering a stream of characters instead of huge strings
@@ -486,7 +550,7 @@ class BigInteger private constructor(wordArray: WordArray, val sign: Sign) : Com
         return toString(10)
     }
 
-    fun toString(base: Int): String {
+    override fun toString(base: Int): String {
         val sign = if (sign == Sign.NEGATIVE) {
             "-"
         } else {
@@ -497,61 +561,10 @@ class BigInteger private constructor(wordArray: WordArray, val sign: Sign) : Com
 
     data class QuotientAndRemainder(val quotient: BigInteger, val remainder: BigInteger)
 
-    //
-    //
-    // ----------------- Interop with basic types ----------------------
-    //
-    //
-
-
-
-    // ------------- Addition -----------
-
-
-    operator fun plus(int: Int): BigInteger {
-        return this.plus(BigInteger.fromInt(int))
-    }
-
-
-    operator fun plus(long: Long): BigInteger {
-        return this.plus(BigInteger.fromLong(long))
-    }
-
-
-    operator fun plus(short: Short): BigInteger {
-        return this.plus(BigInteger.fromShort(short))
-    }
-
-
-    operator fun plus(byte: Byte): BigInteger {
-        return this.plus(BigInteger.fromByte(byte))
-    }
-
-    // ------------- Multiplication -----------
-
-
-    operator fun times(int: Int): BigInteger {
-        return this.multiply(BigInteger.fromInt(int))
-    }
-
-
-    operator fun times(long: Long): BigInteger {
-        return this.multiply(BigInteger.fromLong(long))
-    }
-
-
-    operator fun times(short: Short): BigInteger {
-        return this.multiply(BigInteger.fromShort(short))
-    }
-
-
-    operator fun times(byte: Byte): BigInteger {
-        return this.multiply(BigInteger.fromByte(byte))
-    }
-
+    data class SqareRootAndRemainder(val squareRoot: BigInteger, val remainder: BigInteger)
 
     //TODO eh
-    internal operator fun times(char: Char) : String {
+    operator fun times(char: Char): String {
         if (this < 0) {
             throw RuntimeException("Char cannot be multiplied with negative number")
         }
@@ -564,68 +577,14 @@ class BigInteger private constructor(wordArray: WordArray, val sign: Sign) : Com
         return stringBuilder.toString()
     }
 
-    // ------------- Subtraction -----------
-
-
-    operator fun minus(int: Int): BigInteger {
-        return this.minus(BigInteger.fromInt(int))
-    }
-
-
-    operator fun minus(long: Long): BigInteger {
-        return this.minus(BigInteger.fromLong(long))
-    }
-
-
-    operator fun minus(short: Short): BigInteger {
-        return this.minus(BigInteger.fromShort(short))
+    fun toModularBigInteger(modulo : BigInteger) : ModularBigInteger {
+        val creator = ModularBigInteger.creatorForModulo(modulo)
+        return creator.fromBigInteger(this)
     }
 
+//    fun modularInverse(modulo : BigInteger) : BigInteger {
+//
+//    }
 
-    operator fun minus(byte: Byte): BigInteger {
-        return this.minus(BigInteger.fromByte(byte))
-    }
-
-    // ------------- Division -----------
-
-
-    operator fun div(int: Int): BigInteger {
-        return this.div(BigInteger.fromInt(int))
-    }
-
-
-    operator fun div(long: Long): BigInteger {
-        return this.div(BigInteger.fromLong(long))
-    }
-
-
-    operator fun div(short: Short): BigInteger {
-        return this.div(BigInteger.fromShort(short))
-    }
-
-
-    operator fun div(byte: Byte): BigInteger {
-        return this.div(BigInteger.fromByte(byte))
-    }
-
-
-    operator fun rem(int: Int): BigInteger {
-        return this.rem(BigInteger.fromInt(int))
-    }
-
-
-    operator fun rem(long: Long): BigInteger {
-        return this.rem(BigInteger.fromLong(long))
-    }
-
-
-    operator fun rem(short: Short): BigInteger {
-        return this.rem(BigInteger.fromShort(short))
-    }
-
-
-    operator fun rem(byte: Byte): BigInteger {
-        return this.rem(BigInteger.fromByte(byte))
-    }
 
 }
\ No newline at end of file
diff --git a/bignum/src/commonMain/kotlin/com/ionspin/kotlin/bignum/integer/BigIntegerArithmetic.kt b/bignum/src/commonMain/kotlin/com/ionspin/kotlin/bignum/integer/BigIntegerArithmetic.kt
index c04dbc4..7307a20 100644
--- a/bignum/src/commonMain/kotlin/com/ionspin/kotlin/bignum/integer/BigIntegerArithmetic.kt
+++ b/bignum/src/commonMain/kotlin/com/ionspin/kotlin/bignum/integer/BigIntegerArithmetic.kt
@@ -64,19 +64,19 @@ interface BigIntegerArithmetic<BackingCollectionType, BackingWordType> {
 
     /**
      * Adds two big integers
-     * @return result of addition
+     * @return result of add
      */
     fun add(first: BackingCollectionType, second: BackingCollectionType): BackingCollectionType
 
     /**
      * Substracts two big integers
-     * @return result of subtraction
+     * @return result of subtract
      */
     fun substract(first: BackingCollectionType, second: BackingCollectionType): BackingCollectionType
 
     /**
      * Multiplies two big integers
-     * @return result of multiplication
+     * @return result of multiply
      */
     fun multiply(first: BackingCollectionType, second: BackingCollectionType): BackingCollectionType
 
@@ -86,6 +86,12 @@ interface BigIntegerArithmetic<BackingCollectionType, BackingWordType> {
      */
     fun divide(first: BackingCollectionType, second: BackingCollectionType): Pair<BackingCollectionType, BackingCollectionType>
 
+    /**
+     * Returns a integer reciprocal of this number such that 0 <= base ^ word - operand * reciprocal <= operand,
+     * and remainder such that 0 < reciprocal < operand
+     */
+    fun reciprocal(operand : BackingCollectionType) : Pair<BackingCollectionType, BackingCollectionType>
+
     /**
      * Exponentiation function
      * @return BigInteger result of exponentiation of number by exponent
@@ -102,6 +108,8 @@ interface BigIntegerArithmetic<BackingCollectionType, BackingWordType> {
      */
     fun toString(operand: BackingCollectionType, base : Int) : String
 
+    fun numberOfDecimalDigits(operand : BackingCollectionType): Long
+
     fun fromULong(uLong : ULong) : BackingCollectionType
     fun fromUInt(uInt : UInt) : BackingCollectionType
     fun fromUShort(uShort : UShort): BackingCollectionType
@@ -114,7 +122,7 @@ interface BigIntegerArithmetic<BackingCollectionType, BackingWordType> {
     fun or(operand: BackingCollectionType, mask: BackingCollectionType) : BackingCollectionType
     fun xor(operand: BackingCollectionType, mask: BackingCollectionType) : BackingCollectionType
     fun and(operand: BackingCollectionType, mask: BackingCollectionType) : BackingCollectionType
-    fun inv(operand: BackingCollectionType) : BackingCollectionType
+    fun not(operand: BackingCollectionType) : BackingCollectionType
 
     fun bitAt(operand : BackingCollectionType, position : Long) : Boolean
     fun setBitAt(operand : BackingCollectionType, position : Long, bit : Boolean) : BackingCollectionType
diff --git a/bignum/src/commonMain/kotlin/com/ionspin/kotlin/bignum/integer/PlatformBigIntegerArithmetic.kt b/bignum/src/commonMain/kotlin/com/ionspin/kotlin/bignum/integer/PlatformBigIntegerArithmetic.kt
index 136976b..0192ac4 100644
--- a/bignum/src/commonMain/kotlin/com/ionspin/kotlin/bignum/integer/PlatformBigIntegerArithmetic.kt
+++ b/bignum/src/commonMain/kotlin/com/ionspin/kotlin/bignum/integer/PlatformBigIntegerArithmetic.kt
@@ -22,4 +22,5 @@ package com.ionspin.kotlin.bignum.integer
  * ugljesa.jovanovic@ionspin.com
  * on 10-Mar-2019
  */
+@ExperimentalUnsignedTypes
 expect object PlatformBigIntegerArithmetic : BigIntegerArithmetic<IntArray, Int>
\ No newline at end of file
diff --git a/bignum/src/commonMain/kotlin/com/ionspin/kotlin/bignum/integer/base32/BigInteger32Arithmetic.kt b/bignum/src/commonMain/kotlin/com/ionspin/kotlin/bignum/integer/base32/BigInteger32Arithmetic.kt
index 8517298..3a6ad3a 100644
--- a/bignum/src/commonMain/kotlin/com/ionspin/kotlin/bignum/integer/base32/BigInteger32Arithmetic.kt
+++ b/bignum/src/commonMain/kotlin/com/ionspin/kotlin/bignum/integer/base32/BigInteger32Arithmetic.kt
@@ -17,10 +17,13 @@
 
 package com.ionspin.kotlin.bignum.integer.base32
 
+import com.ionspin.kotlin.bignum.integer.BigInteger
 import com.ionspin.kotlin.bignum.integer.BigIntegerArithmetic
 import com.ionspin.kotlin.bignum.integer.Quadruple
 import com.ionspin.kotlin.bignum.integer.util.toDigit
 import kotlin.math.absoluteValue
+import kotlin.math.ceil
+import kotlin.math.floor
 
 /**
  * Created by Ugljesa Jovanovic
@@ -30,17 +33,18 @@ import kotlin.math.absoluteValue
 @ExperimentalUnsignedTypes
 internal object BigInteger32Arithmetic : BigIntegerArithmetic<UIntArray, UInt> {
     val baseMask = 0xFFFFFFFFUL
+    val baseMaskInt = 0xFFFFFFFFU
     val overflowMask = 0x100000000U
     val lowerMask = 0xFFFFUL
     val base: UInt = 0xFFFFFFFFU
     override val basePowerOfTwo = 32
+    val wordSizeInBits = 32
 
     override val ZERO = UIntArray(0)
     override val ONE = UIntArray(1) { 1U }
     override val TEN = UIntArray(1) { 10U }
 
 
-
     /**
      * Hackers delight 5-11
      */
@@ -90,7 +94,7 @@ internal object BigInteger32Arithmetic : BigIntegerArithmetic<UIntArray, UInt> {
         )
     }
 
-    override fun trailingZeroBits(value : UIntArray) : Int {
+    override fun trailingZeroBits(value: UIntArray): Int {
         TODO()
     }
 
@@ -157,7 +161,7 @@ internal object BigInteger32Arithmetic : BigIntegerArithmetic<UIntArray, UInt> {
         }
 
         if (shiftBits == 0) {
-            operand.copyOfRange(operand.size - wordsToDiscard, operand.size)
+            return operand.copyOfRange(wordsToDiscard, operand.size)
         }
 
         if (operand.size > 1 && operand.size - wordsToDiscard == 1) {
@@ -387,6 +391,8 @@ internal object BigInteger32Arithmetic : BigIntegerArithmetic<UIntArray, UInt> {
     }
 
 
+
+
     /*
      * Based on Basecase DivRem algorithm from
      * Modern Computer Arithmetic, Richard Brent and Paul Zimmermann, Cambridge University Press, 2010.
@@ -482,18 +488,141 @@ internal object BigInteger32Arithmetic : BigIntegerArithmetic<UIntArray, UInt> {
         return Pair(removeLeadingZeroes(quotient), denormRemainder)
     }
 
-    fun baseReciprocal(unnormalized: UIntArray, precision: Int): UIntArray {
-        val (operand, _) = normalize(
-            unnormalized
-        )
-        val operandSize = operand.size
-        if (operandSize <= 2) {
-            return (((uintArrayOf(1U) shl (2 * basePowerOfTwo)) / operand) - 1U)
+    fun d1ReciprocalRecursiveWordVersion(a: UIntArray): Pair<UIntArray, UIntArray> {
+        val n = a.size - 1
+        if (n <= 2) {
+            val corrected = if (n == 0) {
+                1
+            } else {
+                n
+            }
+            val rhoPowered = ONE shl (corrected * 2 * wordSizeInBits)
+            val x = rhoPowered / a
+            val r = rhoPowered - (x * a)
+            return Pair(x, r)
+        }
+        val l = floor((n - 1).toDouble() / 2).toInt()
+        val h = n - l
+        val ah = a.copyOfRange(a.size - h - 1, a.size)
+        val al = a.copyOfRange(0, l)
+        var (xh, rh) = d1ReciprocalRecursiveWordVersion(ah)
+        val s = al * xh
+//        val rhoL = (ONE shl l)
+        val rhRhoL = rh shl (l * wordSizeInBits)
+        val t = if (rhRhoL >= s) {
+            rhRhoL - s
+        } else {
+            xh = xh - ONE
+            (rhRhoL + a) - s
+        }
+        val tm = t shr (h * wordSizeInBits)
+        val d = (xh * tm) shr (h * wordSizeInBits)
+        var x = (xh shl (l * wordSizeInBits)) + d
+        var r = (t shl (l * wordSizeInBits)) - a * d
+        if (r >= a) {
+            x = x + ONE
+            r = r - a
+            if (r >= a) {
+                x = x + ONE
+                r = r - a
+            }
         }
+        return Pair(x, r)
+    }
+
 
-        TODO("Soon")
+    fun reciprocalSingleWord(operand: UInt): Pair<UIntArray, Int> {
+        val bitLength = bitLength(operand)
+        val requiredPrecision = bitLength * 4
+        if (bitLength * 2 <= 63) {
+            val base =
+                1UL shl (requiredPrecision) //We are sure that precision is less or equal to 63, so inside int range
+            var result = base / operand
 
+            return checkReciprocal(uintArrayOf(operand), Pair(uintArrayOf(result.toUInt()), requiredPrecision))
+        } else {
+            val base = ONE.shl(requiredPrecision)
+            val result = base / operand
+            return checkReciprocal(uintArrayOf(operand), Pair(result, requiredPrecision))
+        }
+    }
 
+    private fun checkReciprocal(
+        operand: UIntArray,
+        reciprocal: Pair<UIntArray, Int>
+    ): Pair<UIntArray, Int> {
+        val product = (operand * reciprocal.first)
+        val check = product shr reciprocal.second
+        return if (check != ONE) {
+            Pair(reciprocal.first, reciprocal.second - 1)
+        } else {
+            Pair(reciprocal.first, reciprocal.second)
+        }
+    }
+
+    //TODO Does this work?
+    private fun reciprocal2(operand: UIntArray): Pair<UIntArray, Int> {
+        if (operand.size == 1) {
+            val reciprocal = reciprocalSingleWord(operand[0])
+            return Pair(reciprocal.first, reciprocal.second)
+
+        }
+        val low = floor(operand.size / 2.0).toInt()
+        val high = (operand.size - low).toInt()
+        val operandHigh = operand.copyOfRange(low, high + 1)
+        var (approximateReciprocal, reciprocalShiftAmount) = reciprocal2(operandHigh)
+        var shifted = (operand * approximateReciprocal) shr (reciprocalShiftAmount)
+        val basePowered = ONE shr (operand.size + high)
+        while (shifted > basePowered) {
+            approximateReciprocal = approximateReciprocal - ONE
+            shifted = shifted - operand
+        }
+        shifted = basePowered - shifted
+        val tm = shifted shr low
+        val u = tm * approximateReciprocal
+        val reciprocal = (approximateReciprocal shl low) + (u shl (low - 2 * high))
+        return Pair(reciprocal, bitLength(reciprocal))
+
+    }
+
+    override fun reciprocal(operand: UIntArray): Pair<UIntArray, UIntArray> {
+        return d1ReciprocalRecursiveWordVersion(operand)
+    }
+
+    internal fun reciprocalDivision(first: UIntArray, second: UIntArray): Pair<UIntArray, UIntArray> {
+        val reciprocalExtension = first.size - second.size
+        val precisionShift = (reciprocalExtension * 2 * wordSizeInBits)
+        val secondHighPrecision = second shl precisionShift
+
+        val secondReciprocalWithRemainder = d1ReciprocalRecursiveWordVersion(secondHighPrecision)
+
+        val secondReciprocal = secondReciprocalWithRemainder.first
+        var product = first * secondReciprocal
+        //TODO Proper rounding
+        if (product.compareTo(0U) == 0) {
+            return Pair(ZERO, first)
+        }
+        if (product.size == 1) {
+            if (product >= baseMaskInt - 1U) {
+                product = product + ONE
+            }
+        } else {
+            val importantWord = product[product.size - second.size]
+            if (importantWord >= baseMask) {
+                product = UIntArray(product.size) {
+                    when (it) {
+                        product.size - 1 -> product[product.size - 1] + 1U
+                        else -> 0U
+                    }
+                }
+            }
+        }
+
+        var numberOfWords = product.size - (secondReciprocal.size * 2) + reciprocalExtension * 2
+        if (numberOfWords == 0) { numberOfWords = 1 }
+        val result = product.copyOfRange(product.size - numberOfWords, product.size)
+        val remainder = first - (result * second)
+        return Pair(result, remainder)
     }
 
     override fun parseForBase(number: String, base: Int): UIntArray {
@@ -521,6 +650,26 @@ internal object BigInteger32Arithmetic : BigIntegerArithmetic<UIntArray, UInt> {
         return stringBuilder.toString().reversed()
     }
 
+    override fun numberOfDecimalDigits(operand: UIntArray): Long {
+        val bitLenght = bitLength(operand)
+        val minDigit = ceil((bitLenght - 1) * BigInteger.LOG_10_OF_2)
+//        val maxDigit = floor(bitLenght * LOG_10_OF_2) + 1
+//        val correct = this / 10.toBigInteger().pow(maxDigit.toInt())
+//        return when {
+//            correct == ZERO -> maxDigit.toInt() - 1
+//            correct > 0 && correct < 10 -> maxDigit.toInt()
+//            else -> -1
+//        }
+
+        var tmp = operand / pow(TEN, minDigit.toLong())
+        var counter = 0L
+        while (compare(tmp, ZERO) != 0) {
+            tmp /= TEN
+            counter++
+        }
+        return counter + minDigit.toInt()
+    }
+
     override fun and(operand: UIntArray, mask: UIntArray): UIntArray {
         return UIntArray(operand.size) {
             if (it < mask.size) {
@@ -551,7 +700,7 @@ internal object BigInteger32Arithmetic : BigIntegerArithmetic<UIntArray, UInt> {
         }
     }
 
-    override fun inv(operand: UIntArray): UIntArray {
+    override fun not(operand: UIntArray): UIntArray {
         return UIntArray(operand.size) {
             operand[it].inv()
         }
@@ -579,7 +728,7 @@ internal object BigInteger32Arithmetic : BigIntegerArithmetic<UIntArray, UInt> {
         return (word and (1U shl bitPosition.toInt()) == 1U)
     }
 
-    override fun setBitAt(operand: UIntArray, position: Long, bit : Boolean): UIntArray {
+    override fun setBitAt(operand: UIntArray, position: Long, bit: Boolean): UIntArray {
         if (position / 63 > Int.MAX_VALUE) {
             throw RuntimeException("Invalid bit index, too large, cannot access word (Word position > Int.MAX_VALUE")
         }
@@ -589,7 +738,6 @@ internal object BigInteger32Arithmetic : BigIntegerArithmetic<UIntArray, UInt> {
             throw IndexOutOfBoundsException("Invalid position, addressed word $wordPosition larger than number of words ${operand.size}")
         }
         val bitPosition = position % 63
-        val word = operand[wordPosition.toInt()]
         val setMask = 1U shl bitPosition.toInt()
         return UIntArray(operand.size) {
             if (it == wordPosition.toInt()) {
diff --git a/bignum/src/commonMain/kotlin/com/ionspin/kotlin/bignum/integer/base63/BigInteger63Arithmetic.kt b/bignum/src/commonMain/kotlin/com/ionspin/kotlin/bignum/integer/base63/BigInteger63Arithmetic.kt
index 5c57abd..a9ca4d9 100644
--- a/bignum/src/commonMain/kotlin/com/ionspin/kotlin/bignum/integer/base63/BigInteger63Arithmetic.kt
+++ b/bignum/src/commonMain/kotlin/com/ionspin/kotlin/bignum/integer/base63/BigInteger63Arithmetic.kt
@@ -22,8 +22,9 @@ import com.ionspin.kotlin.bignum.integer.BigIntegerArithmetic
 import com.ionspin.kotlin.bignum.integer.Quadruple
 import com.ionspin.kotlin.bignum.integer.base32.BigInteger32Arithmetic
 import com.ionspin.kotlin.bignum.integer.util.toDigit
-import kotlin.math.abs
 import kotlin.math.absoluteValue
+import kotlin.math.ceil
+import kotlin.math.floor
 
 /**
  * Created by Ugljesa Jovanovic
@@ -36,6 +37,7 @@ internal object BigInteger63Arithmetic : BigIntegerArithmetic<ULongArray, ULong>
     override val ONE: ULongArray = ulongArrayOf(1u)
     override val TEN: ULongArray = ulongArrayOf(10UL)
     override val basePowerOfTwo: Int = 63
+    val wordSizeInBits = 63
 
     val baseMask: ULong = 0x7FFFFFFFFFFFFFFFUL
 
@@ -92,11 +94,11 @@ internal object BigInteger63Arithmetic : BigIntegerArithmetic<ULongArray, ULong>
         return 63 - numberOfLeadingZeroes(value)
     }
 
-    fun trailingZeroBits(value : ULong) : Int {
+    fun trailingZeroBits(value: ULong): Int {
         return 63 - bitLength(value.inv() and baseMask)
     }
 
-    override fun trailingZeroBits(value : ULongArray) : Int {
+    override fun trailingZeroBits(value: ULongArray): Int {
         TODO()
     }
 
@@ -225,6 +227,28 @@ internal object BigInteger63Arithmetic : BigIntegerArithmetic<ULongArray, ULong>
         }
     }
 
+    override fun numberOfDecimalDigits(operand: ULongArray): Long {
+        val bitLenght = bitLength(operand)
+        val minDigit = ceil((bitLenght - 1) * BigInteger.LOG_10_OF_2)
+//        val maxDigit = floor(bitLenght * LOG_10_OF_2) + 1
+//        val correct = this / 10.toBigInteger().pow(maxDigit.toInt())
+//        return when {
+//            correct == ZERO -> maxDigit.toInt() - 1
+//            correct > 0 && correct < 10 -> maxDigit.toInt()
+//            else -> -1
+//        }
+
+        var tmp = operand / pow(TEN, minDigit.toLong())
+        var counter = 0L
+        while (compare(tmp, ZERO) != 0) {
+            tmp /= TEN
+            counter++
+        }
+        return counter + minDigit.toInt()
+
+
+    }
+
     override fun add(first: ULongArray, second: ULongArray): ULongArray {
         if (first.size == 1 && first[0] == 0UL) return second
         if (second.size == 1 && second[0] == 0UL) return first
@@ -283,7 +307,7 @@ internal object BigInteger63Arithmetic : BigIntegerArithmetic<ULongArray, ULong>
 
         // Lets throw this just to catch when we didn't prepare the operands correctly
         if (!firstIsLarger) {
-            throw RuntimeException("subtraction result less than zero")
+            throw RuntimeException("subtract result less than zero")
         }
         val (largerLength, smallerLength, largerData, smallerData) = if (firstIsLarger) {
             Quadruple(firstPrepared.size, secondPrepared.size, firstPrepared, secondPrepared)
@@ -415,18 +439,18 @@ internal object BigInteger63Arithmetic : BigIntegerArithmetic<ULongArray, ULong>
         return removeLeadingZeroes(ulongArrayOf(lowResult and baseMask, highResult))
     }
 
-    override fun pow(operand: ULongArray, exponent: Long): ULongArray {
+    override fun pow(base: ULongArray, exponent: Long): ULongArray {
         if (exponent == 0L) {
             return ONE
         }
         if (exponent == 1L) {
-            return operand
+            return base
         }
-        if (operand.size == 1 && operand[0] == 10UL && exponent < powersOf10.size) {
+        if (base.size == 1 && base[0] == 10UL && exponent < powersOf10.size) {
             return powersOf10[exponent.toInt()]
         }
         return (0 until exponent).fold(ONE) { acc, _ ->
-            acc * operand
+            acc * base
         }
     }
 
@@ -547,6 +571,121 @@ internal object BigInteger63Arithmetic : BigIntegerArithmetic<ULongArray, ULong>
         return Pair(removeLeadingZeroes(quotient), denormRemainder)
     }
 
+    override fun reciprocal(operand: ULongArray): Pair<ULongArray, ULongArray> {
+        return d1ReciprocalRecursiveWordVersion(operand)
+    }
+
+    fun d1ReciprocalRecursive(a: ULongArray): Pair<ULongArray, ULongArray> {
+        val fullBitLenght = bitLength(a)
+        val n = if (fullBitLenght > 63) {
+            fullBitLenght - 63
+        } else {
+            fullBitLenght
+        }
+        if (n <= 30) {
+            val rhoPowered = 1UL shl (n * 2)
+            val longA = a[0]
+            val x = rhoPowered / longA
+            val r = rhoPowered - x * longA
+            return Pair(ulongArrayOf(x), ulongArrayOf(r))
+        }
+        val l = floor((n - 1).toDouble() / 2).toInt()
+        val h = n - l
+        val mask = (ONE shl l) - ONE
+        val ah = a shr l
+        val al = and(a, mask)
+        var (xh, rh) = d1ReciprocalRecursive(ah)
+        val s = al * xh
+//        val rhoL = (ONE shl l)
+        val rhRhoL = rh shl l
+        val t = if (rhRhoL >= s) {
+            rhRhoL - s
+        } else {
+            xh = xh - ONE
+            (rhRhoL + a) - s
+        }
+        val tm = t shr h
+        val d = (xh * tm) shr h
+        var x = (xh shl l) + d
+        var r = (t shl l) - a * d
+        if (r >= a) {
+            x = x + ONE
+            r = r - a
+            if (r >= a) {
+                x = x + ONE
+                r = r - a
+            }
+        }
+        return Pair(x, r)
+    }
+
+    fun d1ReciprocalRecursiveWordVersion(a: ULongArray): Pair<ULongArray, ULongArray> {
+        val n = a.size - 1
+        if (n <= 2) {
+            val corrected = if (n == 0) {
+                1
+            } else {
+                n
+            }
+            val rhoPowered = ONE shl (corrected * 2 * wordSizeInBits)
+            val x = rhoPowered / a
+            val r = rhoPowered - (x * a)
+            return Pair(x, r)
+        }
+        val l = floor((n - 1).toDouble() / 2).toInt()
+        val h = n - l
+        val ah = a.copyOfRange(a.size - h - 1, a.size)
+        val al = a.copyOfRange(0, l)
+        var (xh, rh) = d1ReciprocalRecursiveWordVersion(ah)
+        val s = al * xh
+//        val rhoL = (ONE shl l)
+        val rhRhoL = rh shl (l * wordSizeInBits)
+        val t = if (rhRhoL >= s) {
+            rhRhoL - s
+        } else {
+            xh = xh - ONE
+            (rhRhoL + a) - s
+        }
+        val tm = t shr (h * wordSizeInBits)
+        val d = (xh * tm) shr (h * wordSizeInBits)
+        var x = (xh shl (l * wordSizeInBits)) + d
+        var r = (t shl (l * wordSizeInBits)) - a * d
+        if (r >= a) {
+            x = x + ONE
+            r = r - a
+            if (r >= a) {
+                x = x + ONE
+                r = r - a
+            }
+        }
+        return Pair(x, r)
+    }
+
+    private fun unbalancedReciprocal(a: ULongArray, diff: Int): Pair<ULongArray, ULongArray> {
+        val n = a.size - 1 - diff
+        val a0 = a.copyOfRange(n + 1, a.size)
+        val a1 = a.copyOfRange(0, n)
+        var (x, r) = d1ReciprocalRecursiveWordVersion(a0)
+        if (x == ONE shl (n * 63)) {
+            if (a1.compareTo(ZERO) == 0) {
+                r = ZERO
+            } else {
+                x = x - ONE
+                r = a - (a1 shl (n * 63))
+            }
+        } else {
+            val rRhoD = r shl diff
+            val a1x = a1 * x
+            if (rRhoD > a1x) {
+                r = rRhoD - a1x
+            } else {
+                x = x - ONE
+                r = rRhoD - (a1 * x)
+            }
+        }
+        return Pair(x, r)
+    }
+
     fun convertTo64BitRepresentation(operand: ULongArray): ULongArray {
         if (operand == ZERO) return ZERO
         val length = bitLength(operand)
@@ -631,12 +770,7 @@ internal object BigInteger63Arithmetic : BigIntegerArithmetic<ULongArray, ULong>
 
 
         }
-//        if (operand.size % 2 != 0) {
-//            val lastI = requiredLength - 1 + skipWordCount
-//            result[lastI] =
-//                (operand[(lastI * 2) - 1].toULong() shr (32 - lastI)) or (operand[(lastI * 2)].toULong() shl lastI)
-//        }
-//        result[requiredLength - 1] = (operand[operand.size - 1].toULong() shl ((operand.size - 1) / 2)) or (operand[operand.size - 2].toULong() shr (32 - (operand.size - 1)/2))
+
         return result
     }
 
@@ -644,6 +778,53 @@ internal object BigInteger63Arithmetic : BigIntegerArithmetic<ULongArray, ULong>
         return baseDivide(first, second)
     }
 
+    internal fun reciprocalDivision(first: ULongArray, second: ULongArray): Pair<ULongArray, ULongArray> {
+        if (first.size < second.size) {
+            throw RuntimeException("Invalid division: ${first.size} words / ${second.size} words")
+        }
+        val shift = if (second.size == 1) {
+            1
+        } else {
+            second.size - 1
+        }
+        val precisionExtension = (first.size - second.size + 1)
+        val secondHigherPrecision = ULongArray(second.size + precisionExtension) {
+            when {
+                it >= precisionExtension -> second[it - precisionExtension]
+                else -> 0UL
+            }
+        }
+
+        val secondReciprocalWithRemainder = d1ReciprocalRecursiveWordVersion(secondHigherPrecision)
+
+        val secondReciprocal = secondReciprocalWithRemainder.first
+        var product = first * secondReciprocal
+        //TODO Proper rounding
+        if (product.compareTo(0UL) == 0) {
+            return Pair(ZERO, first)
+        }
+        if (product.size == 1) {
+            if (product >= baseMask - 1UL) {
+                product = product + ONE
+            }
+        } else {
+            val importantWord = product[product.size - second.size]
+            if (importantWord >= baseMask) {
+                product = ULongArray(product.size) {
+                    when (it) {
+                        product.size - 1 -> product[product.size - 1] + 1UL
+                        else -> 0UL
+                    }
+                }
+            }
+        }
+
+        val result = product.copyOfRange(2 * shift + precisionExtension, product.size)
+        val remainder = first - (result * second)
+        return Pair(result, remainder)
+    }
+
+
     override fun parseForBase(number: String, base: Int): ULongArray {
         var parsed = ZERO
         number.toLowerCase().forEach { char ->
@@ -705,7 +886,7 @@ internal object BigInteger63Arithmetic : BigIntegerArithmetic<ULongArray, ULong>
         )
     }
 
-    override fun inv(operand: ULongArray): ULongArray {
+    override fun not(operand: ULongArray): ULongArray {
         val leadingZeroes = numberOfLeadingZeroes(operand[operand.size - 1])
         val cleanupMask = (((1UL shl leadingZeroes + 1) - 1U) shl (basePowerOfTwo - leadingZeroes)).inv()
         val inverted = ULongArray(operand.size) {
@@ -744,7 +925,7 @@ internal object BigInteger63Arithmetic : BigIntegerArithmetic<ULongArray, ULong>
         return (word and (1UL shl bitPosition.toInt()) == 1UL)
     }
 
-    override fun setBitAt(operand: ULongArray, position: Long, bit : Boolean): ULongArray {
+    override fun setBitAt(operand: ULongArray, position: Long, bit: Boolean): ULongArray {
         if (position / 63 > Int.MAX_VALUE) {
             throw RuntimeException("Invalid bit index, too large, cannot access word (Word position > Int.MAX_VALUE")
         }
@@ -754,8 +935,6 @@ internal object BigInteger63Arithmetic : BigIntegerArithmetic<ULongArray, ULong>
             throw IndexOutOfBoundsException("Invalid position, addressed word $wordPosition larger than number of words ${operand.size}")
         }
         val bitPosition = position % 63
-        val word = operand[wordPosition.toInt()]
-        val getMask = (word and (1UL shl bitPosition.toInt()) == 1UL)
         val setMask = 1UL shl bitPosition.toInt()
         return ULongArray(operand.size) {
             if (it == wordPosition.toInt()) {
@@ -798,23 +977,23 @@ internal object BigInteger63Arithmetic : BigIntegerArithmetic<ULongArray, ULong>
     }
 
     internal operator fun ULongArray.div(other: ULong): ULongArray {
-        return baseDivide(this, ulongArrayOf(other)).first
+        return divide(this, ulongArrayOf(other)).first
     }
 
     internal operator fun ULongArray.rem(other: ULong): ULongArray {
-        return baseDivide(this, ulongArrayOf(other)).second
+        return divide(this, ulongArrayOf(other)).second
     }
 
     internal operator fun ULongArray.div(other: ULongArray): ULongArray {
-        return baseDivide(this, other).first
+        return divide(this, other).first
     }
 
     internal operator fun ULongArray.rem(other: ULongArray): ULongArray {
-        return baseDivide(this, other).second
+        return divide(this, other).second
     }
 
     internal infix fun ULongArray.divrem(other: ULongArray): Pair<ULongArray, ULongArray> {
-        return baseDivide(this, other)
+        return divide(this, other)
     }
 
     internal operator fun ULongArray.compareTo(other: ULongArray): Int {
@@ -953,12 +1132,54 @@ internal object BigInteger63Arithmetic : BigIntegerArithmetic<ULongArray, ULong>
         ulongArrayOf(0UL, 4692406261390508032UL, 4125506992759596769UL, 3695050361890294256UL, 13817869688151111UL),
         ulongArrayOf(0UL, 807202429631201280UL, 4361581780176864463UL, 57015471483839332UL, 138178696881511114UL),
         ulongArrayOf(0UL, 8072024296312012800UL, 6722329654349541398UL, 570154714838393324UL, 1381786968815111140UL),
-        ulongArrayOf(0UL, 6933266668281921536UL, 2659692285511983332UL, 5701547148383933247UL, 4594497651296335592UL, 1UL),
-        ulongArrayOf(0UL, 4769062424835784704UL, 8150178781410281711UL, 1675239262710677624UL, 9051488365544252694UL, 14UL),
-        ulongArrayOf(0UL, 1573764064083968000UL, 7714811519264610651UL, 7529020590252000440UL, 7504535323749544669UL, 149UL),
-        ulongArrayOf(0UL, 6514268603984904192UL, 3361138897807900047UL, 1503229607681797944UL, 1258376942657240234UL, 1498UL),
-        ulongArrayOf(0UL, 579081781865611264UL, 5941272867514673053UL, 5808924039963203635UL, 3360397389717626533UL, 14981UL),
-        ulongArrayOf(0UL, 5790817818656112640UL, 4072496454018075682UL, 2749008178503381508UL, 5933857786611937912UL, 149813UL)
+        ulongArrayOf(
+            0UL,
+            6933266668281921536UL,
+            2659692285511983332UL,
+            5701547148383933247UL,
+            4594497651296335592UL,
+            1UL
+        ),
+        ulongArrayOf(
+            0UL,
+            4769062424835784704UL,
+            8150178781410281711UL,
+            1675239262710677624UL,
+            9051488365544252694UL,
+            14UL
+        ),
+        ulongArrayOf(
+            0UL,
+            1573764064083968000UL,
+            7714811519264610651UL,
+            7529020590252000440UL,
+            7504535323749544669UL,
+            149UL
+        ),
+        ulongArrayOf(
+            0UL,
+            6514268603984904192UL,
+            3361138897807900047UL,
+            1503229607681797944UL,
+            1258376942657240234UL,
+            1498UL
+        ),
+        ulongArrayOf(
+            0UL,
+            579081781865611264UL,
+            5941272867514673053UL,
+            5808924039963203635UL,
+            3360397389717626533UL,
+            14981UL
+        ),
+        ulongArrayOf(
+            0UL,
+            5790817818656112640UL,
+            4072496454018075682UL,
+            2749008178503381508UL,
+            5933857786611937912UL,
+            149813UL
+        )
     )
 
 
diff --git a/bignum/src/commonMain/kotlin/com/ionspin/kotlin/bignum/integer/base63/BigInteger63LinkedListArithmetic.kt b/bignum/src/commonMain/kotlin/com/ionspin/kotlin/bignum/integer/base63/BigInteger63LinkedListArithmetic.kt
index 46503c5..f277391 100644
--- a/bignum/src/commonMain/kotlin/com/ionspin/kotlin/bignum/integer/base63/BigInteger63LinkedListArithmetic.kt
+++ b/bignum/src/commonMain/kotlin/com/ionspin/kotlin/bignum/integer/base63/BigInteger63LinkedListArithmetic.kt
@@ -17,11 +17,13 @@
 
 package com.ionspin.kotlin.bignum.integer.base63
 
+import com.ionspin.kotlin.bignum.integer.BigInteger
 import com.ionspin.kotlin.bignum.integer.BigIntegerArithmetic
 import com.ionspin.kotlin.bignum.integer.Quadruple
 import com.ionspin.kotlin.bignum.integer.base32.BigInteger32Arithmetic
 import com.ionspin.kotlin.bignum.integer.util.toDigit
 import kotlin.math.absoluteValue
+import kotlin.math.ceil
 
 /**
  * Just to experiment and see if using immutable lists is better optimized than using arrays.
@@ -282,7 +284,7 @@ internal object BigInteger63LinkedListArithmetic : BigIntegerArithmetic<List<ULo
 
         // Lets throw this just to catch when we didn't prepare the operands correctly
         if (!firstIsLarger) {
-            throw RuntimeException("subtraction result less than zero")
+            throw RuntimeException("subtract result less than zero")
         }
         val (largerLength, smallerLength, largerData, smallerData) = if (firstIsLarger) {
             Quadruple(firstPrepared.size, secondPrepared.size, firstPrepared, secondPrepared)
@@ -414,18 +416,18 @@ internal object BigInteger63LinkedListArithmetic : BigIntegerArithmetic<List<ULo
         return removeLeadingZeroes(listOf(lowResult and baseMask, highResult))
     }
 
-    override fun pow(operand: List<ULong>, exponent: Long): List<ULong> {
+    override fun pow(base: List<ULong>, exponent: Long): List<ULong> {
         if (exponent == 0L) {
             return ONE
         }
         if (exponent == 1L) {
-            return operand
+            return base
         }
-        if (operand.size == 1 && operand[0] == 10UL && exponent < powersOf10.size) {
+        if (base.size == 1 && base[0] == 10UL && exponent < powersOf10.size) {
             return powersOf10[exponent.toInt()]
         }
         return (0 until exponent).fold(ONE) { acc, _ ->
-            acc * operand
+            acc * base
         }
     }
 
@@ -493,7 +495,7 @@ internal object BigInteger63LinkedListArithmetic : BigIntegerArithmetic<List<ULo
         )
         val dividendSize = dividend.size
         val divisorSize = divisor.size
-        var wordPrecision = dividendSize - divisorSize
+        val wordPrecision = dividendSize - divisorSize
 
 
         var qjhat: List<ULong>
@@ -643,6 +645,10 @@ internal object BigInteger63LinkedListArithmetic : BigIntegerArithmetic<List<ULo
         return baseDivide(first, second)
     }
 
+    override fun reciprocal(operand: List<ULong>): Pair<List<ULong>, List<ULong>> {
+        TODO("not implemented yet")
+    }
+
     override fun parseForBase(number: String, base: Int): List<ULong> {
         var parsed = ZERO
         number.toLowerCase().forEach { char ->
@@ -668,6 +674,28 @@ internal object BigInteger63LinkedListArithmetic : BigIntegerArithmetic<List<ULo
         return stringBuilder.toString().reversed()
     }
 
+    override fun numberOfDecimalDigits(operand : List<ULong>): Long {
+        val bitLenght = bitLength(operand)
+        val minDigit = ceil((bitLenght - 1) * BigInteger.LOG_10_OF_2)
+//        val maxDigit = floor(bitLenght * LOG_10_OF_2) + 1
+//        val correct = this / 10.toBigInteger().pow(maxDigit.toInt())
+//        return when {
+//            correct == ZERO -> maxDigit.toInt() - 1
+//            correct > 0 && correct < 10 -> maxDigit.toInt()
+//            else -> -1
+//        }
+
+        var tmp = operand / pow(TEN, minDigit.toLong())
+        var counter = 0L
+        while (compare(tmp, ZERO) != 0) {
+            tmp /= TEN
+            counter++
+        }
+        return counter + minDigit.toInt()
+
+
+    }
+
     override fun and(operand: List<ULong>, mask: List<ULong>): List<ULong> {
         return removeLeadingZeroes(
             List<ULong>(operand.size) {
@@ -704,7 +732,7 @@ internal object BigInteger63LinkedListArithmetic : BigIntegerArithmetic<List<ULo
         )
     }
 
-    override fun inv(operand: List<ULong>): List<ULong> {
+    override fun not(operand: List<ULong>): List<ULong> {
         val leadingZeroes = numberOfLeadingZeroes(operand[operand.size - 1])
         val cleanupMask = (((1UL shl leadingZeroes + 1) - 1U) shl (basePowerOfTwo - leadingZeroes)).inv()
         val inverted = List<ULong>(operand.size) {
@@ -753,7 +781,6 @@ internal object BigInteger63LinkedListArithmetic : BigIntegerArithmetic<List<ULo
             throw IndexOutOfBoundsException("Invalid position, addressed word $wordPosition larger than number of words ${operand.size}")
         }
         val bitPosition = position % 63
-        val word = operand[wordPosition.toInt()]
         val setMask = 1UL shl bitPosition.toInt()
         return List(operand.size) {
             if (it == wordPosition.toInt()) {
diff --git a/bignum/src/commonMain/kotlin/com/ionspin/kotlin/bignum/integer/concurrent/Placeholder.kt b/bignum/src/commonMain/kotlin/com/ionspin/kotlin/bignum/integer/concurrent/Placeholder.kt
index ea14319..c202366 100644
--- a/bignum/src/commonMain/kotlin/com/ionspin/kotlin/bignum/integer/concurrent/Placeholder.kt
+++ b/bignum/src/commonMain/kotlin/com/ionspin/kotlin/bignum/integer/concurrent/Placeholder.kt
@@ -26,7 +26,7 @@ suspend fun concurrentMultiply() {
 //    if (BigInteger32Arithmetic.useCoroutines) {
 //        val partialResults = second.mapIndexed { index, element ->
 //            GlobalScope.async {
-//                BigInteger32Arithmetic.multiplication(first, element) shl (index * BigInteger32Arithmetic.basePowerOfTwo)
+//                BigInteger32Arithmetic.multiply(first, element) shl (index * BigInteger32Arithmetic.basePowerOfTwo)
 //            }
 //        }
 //
diff --git a/bignum/src/commonMain/kotlin/com/ionspin/kotlin/bignum/integer/util/DigitUtil.kt b/bignum/src/commonMain/kotlin/com/ionspin/kotlin/bignum/integer/util/DigitUtil.kt
index 143f0c9..4826ee6 100644
--- a/bignum/src/commonMain/kotlin/com/ionspin/kotlin/bignum/integer/util/DigitUtil.kt
+++ b/bignum/src/commonMain/kotlin/com/ionspin/kotlin/bignum/integer/util/DigitUtil.kt
@@ -22,7 +22,7 @@ package com.ionspin.kotlin.bignum.integer.util
  * ugljesa.jovanovic@ionspin.com
  * on 18-Mar-2019
  */
-fun Char.toDigit(radix : Int) : Int {
+fun Char.toDigit() : Int {
     return when (this) {
         in '0' .. '9' -> (this - 48).toInt()
         in 'a' .. 'z' -> this - 'a' + 10
@@ -32,7 +32,3 @@ fun Char.toDigit(radix : Int) : Int {
         else -> throw NumberFormatException("Invalid digit for radix ")
     }
 }
-
-fun Char.toDigit() : Int {
-    return this.toDigit(10)
-}
\ No newline at end of file
diff --git a/bignum/src/commonMain/kotlin/com/ionspin/kotlin/bignum/modular/ModularBigInteger.kt b/bignum/src/commonMain/kotlin/com/ionspin/kotlin/bignum/modular/ModularBigInteger.kt
new file mode 100644
index 0000000..3738f8f
--- /dev/null
+++ b/bignum/src/commonMain/kotlin/com/ionspin/kotlin/bignum/modular/ModularBigInteger.kt
@@ -0,0 +1,268 @@
+/*
+ *    Copyright 2019 Ugljesa Jovanovic
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ *
+ */
+
+package com.ionspin.kotlin.bignum.modular
+
+import com.ionspin.kotlin.bignum.BigNumber
+import com.ionspin.kotlin.bignum.CommonBigNumberOperations
+import com.ionspin.kotlin.bignum.ModularQuotientAndRemainder
+import com.ionspin.kotlin.bignum.integer.BigInteger
+import com.ionspin.kotlin.bignum.integer.Sign
+
+/**
+ * Implementation of operations on modular integer
+ *
+ * Created by Ugljesa Jovanovic
+ * ugljesa.jovanovic@ionspin.com
+ * on 04-Apr-2019
+ */
+
+@ExperimentalUnsignedTypes
+class ModularBigInteger @ExperimentalUnsignedTypes constructor(
+    val residue : BigInteger,
+    val modulo : BigInteger,
+    private val creator: BigNumber.Creator<ModularBigInteger>) : BigNumber<ModularBigInteger>,
+        CommonBigNumberOperations<ModularBigInteger>
+{
+    companion object {
+        fun creatorForModulo(modulo: ULong) : BigNumber.Creator<ModularBigInteger> = creatorForModulo(BigInteger.fromULong(modulo))
+        fun creatorForModulo(modulo: UInt) : BigNumber.Creator<ModularBigInteger> = creatorForModulo(BigInteger.fromUInt(modulo))
+        fun creatorForModulo(modulo: UShort) : BigNumber.Creator<ModularBigInteger> = creatorForModulo(BigInteger.fromUShort(modulo))
+        fun creatorForModulo(modulo: UByte) : BigNumber.Creator<ModularBigInteger> = creatorForModulo(BigInteger.fromUByte(modulo))
+        fun creatorForModulo(modulo: Long) : BigNumber.Creator<ModularBigInteger> = creatorForModulo(BigInteger.fromLong(modulo))
+        fun creatorForModulo(modulo: Int) : BigNumber.Creator<ModularBigInteger> = creatorForModulo(BigInteger.fromInt(modulo))
+        fun creatorForModulo(modulo: Short) : BigNumber.Creator<ModularBigInteger> = creatorForModulo(BigInteger.fromShort(modulo))
+        fun creatorForModulo(modulo: Byte) : BigNumber.Creator<ModularBigInteger> = creatorForModulo(BigInteger.fromByte(modulo))
+
+
+        fun creatorForModulo(modulo: BigInteger) : BigNumber.Creator<ModularBigInteger> {
+            return object : BigNumber.Creator<ModularBigInteger> {
+                override fun fromBigInteger(bigInteger: BigInteger): ModularBigInteger {
+                    return ModularBigInteger(bigInteger.prep(), modulo, this)
+                }
+
+                override fun parseString(string: String, base: Int): ModularBigInteger {
+                    return ModularBigInteger(BigInteger.parseString(string, base).prep(), modulo, this)
+                }
+
+                override fun fromULong(uLong: ULong): ModularBigInteger {
+                    return ModularBigInteger(BigInteger.fromULong(uLong).prep(), modulo, this)
+                }
+
+                override fun fromUInt(uInt: UInt): ModularBigInteger {
+                    return ModularBigInteger(BigInteger.fromUInt(uInt).prep(), modulo, this)
+                }
+
+                override fun fromUShort(uShort: UShort): ModularBigInteger {
+                    return ModularBigInteger(BigInteger.fromUShort(uShort).prep(), modulo, this)
+                }
+
+                override fun fromUByte(uByte: UByte): ModularBigInteger {
+                    return ModularBigInteger(BigInteger.fromUByte(uByte).prep(), modulo, this)
+                }
+
+                override fun fromLong(long: Long): ModularBigInteger {
+                    return ModularBigInteger(BigInteger.fromLong(long).prep(), modulo, this)
+                }
+
+                override fun fromInt(int: Int): ModularBigInteger {
+                    return ModularBigInteger(BigInteger.fromInt(int).prep(), modulo, this)
+                }
+
+                override fun fromShort(short: Short): ModularBigInteger {
+                    return ModularBigInteger(BigInteger.fromShort(short).prep(), modulo, this)
+                }
+
+                override fun fromByte(byte: Byte): ModularBigInteger {
+                    return ModularBigInteger(BigInteger.fromByte(byte).prep(), modulo, this)
+                }
+
+                private fun BigInteger.prep() : BigInteger {
+                    val result = this % modulo
+                    return when (result.sign) {
+                        Sign.POSITIVE -> result
+                        Sign.NEGATIVE -> result + modulo
+                        Sign.ZERO -> BigInteger.ZERO
+                    }
+                }
+
+
+            }
+        }
+    }
+    override fun getCreator(): BigNumber.Creator<ModularBigInteger> {
+        return creator
+    }
+
+    override fun getInstance(): ModularBigInteger {
+        return this
+    }
+
+    private fun assertSameModulo(other : ModularBigInteger) {
+        if (this.modulo != other.modulo) {
+            throw RuntimeException("Different moduli! This $modulo\n Other ${other.modulo}")
+        }
+    }
+
+    override fun add(other: ModularBigInteger): ModularBigInteger {
+        assertSameModulo(other)
+        return ModularBigInteger((residue + other.residue) % modulo, modulo, creator)
+    }
+
+    override fun subtract(other: ModularBigInteger): ModularBigInteger {
+        assertSameModulo(other)
+        return ModularBigInteger((residue - other.residue) % modulo, modulo, creator)
+    }
+
+    override fun multiply(other: ModularBigInteger): ModularBigInteger {
+        assertSameModulo(other)
+        return ModularBigInteger((residue * other.residue) % modulo, modulo, creator)
+    }
+
+    override fun divide(other: ModularBigInteger): ModularBigInteger {
+        assertSameModulo(other)
+        val quotient = this.residue / other.residue
+        val result = quotient % modulo
+        return ModularBigInteger(result, modulo, creator)
+    }
+
+    override fun remainder(other: ModularBigInteger): ModularBigInteger {
+        assertSameModulo(other)
+        val remainder = this.residue % other.residue
+        val result = remainder % modulo
+        return ModularBigInteger(result, modulo, creator)
+    }
+
+    override fun divideAndRemainder(other: ModularBigInteger): Pair<ModularBigInteger, ModularBigInteger> {
+        assertSameModulo(other)
+        val quotientAndRemainder = this.residue divrem  other.residue
+        val quotient = quotientAndRemainder.quotient % modulo
+        val remainder = quotientAndRemainder.remainder % modulo
+        return Pair(ModularBigInteger(quotient, modulo, creator), ModularBigInteger(remainder, modulo, creator))
+    }
+
+    fun inverse() : ModularBigInteger {
+        val inverse = residue.modInverse(modulo)
+        return ModularBigInteger(inverse, modulo, creator)
+    }
+
+    fun compare(other: ModularBigInteger): Int {
+        assertSameModulo(other)
+        return this.residue.compareTo(other.residue)
+    }
+
+    override fun isZero(): Boolean {
+        return residue.isZero()
+    }
+
+    /**
+     *
+     */
+    // TODO Is this really a negation of a modular number? It's true that it will be congruent for the module, and it's
+    // also true that sign will be opposite, but still, all of our modular representations are 0 < a < modulo, so it doesn't
+    // really make sense
+    override fun negate(): ModularBigInteger {
+        return when (residue.sign) {
+            Sign.ZERO -> this
+            Sign.POSITIVE -> ModularBigInteger(residue - modulo, modulo, creator)
+            Sign.NEGATIVE -> ModularBigInteger(residue + modulo, modulo, creator)
+        }
+
+    }
+
+    override fun abs(): ModularBigInteger {
+        return this
+    }
+
+    override fun pow(exponent: ModularBigInteger): ModularBigInteger {
+        return ModularBigInteger(residue.pow(exponent.residue) % modulo, modulo, creator)
+    }
+
+    fun pow(exponent: BigInteger): ModularBigInteger {
+        return ModularBigInteger(residue.pow(exponent) % modulo, modulo, creator)
+    }
+
+    override fun pow(exponent: Long): ModularBigInteger {
+        return ModularBigInteger(residue.pow(exponent) % modulo, modulo, creator)
+    }
+
+    override fun pow(exponent: Int): ModularBigInteger {
+        return ModularBigInteger(residue.pow(exponent) % modulo, modulo, creator)
+    }
+
+    override fun signum(): Int {
+        return residue.signum()
+    }
+
+    override fun numberOfDecimalDigits(): Long {
+        return residue.numberOfDecimalDigits()
+    }
+
+    override fun unaryMinus(): ModularBigInteger {
+        return negate()
+    }
+
+    override fun rem(other: ModularBigInteger): ModularBigInteger {
+        return remainder(other)
+    }
+
+    override fun compareTo(other: Any): Int {
+        return when (other) {
+            is ModularBigInteger -> compare(other)
+            is BigInteger -> residue.compare(other)
+            is Long -> compare(creator.fromLong(other))
+            is Int -> compare(creator.fromInt(other))
+            is Short -> compare(creator.fromShort(other))
+            is Byte -> compare(creator.fromByte(other))
+            else -> throw RuntimeException("Invalid comparison type for BigInteger: ${other::class.simpleName}")
+        }
+    }
+
+    override fun equals(other: Any?): Boolean {
+        return if (other == null) {
+            false
+        } else {
+            compareTo(other) == 0
+        }
+
+    }
+
+    override fun toString(): String {
+        return residue.toString()
+    }
+
+    override fun toString(base: Int): String {
+        return residue.toString(base)
+    }
+
+    fun toStringWithModulo(base : Int = 10) : String {
+        return residue.toString(base) + " mod " + modulo.toString(base)
+    }
+
+    infix fun divrem(other: ModularBigInteger): ModularQuotientAndRemainder {
+        val result = divideAndRemainder(other)
+        return ModularQuotientAndRemainder(result.first, result.second)
+    }
+
+    fun toBigInteger() : BigInteger {
+        return residue
+    }
+
+
+
+
+}
\ No newline at end of file
diff --git a/bignum/src/jsMain/kotlin/com/ionspin/kotlin/bignum/integer/PlatformBigIntegerArithmetic.kt b/bignum/src/jsMain/kotlin/com/ionspin/kotlin/bignum/integer/PlatformBigIntegerArithmetic.kt
index 98e0307..204da92 100644
--- a/bignum/src/jsMain/kotlin/com/ionspin/kotlin/bignum/integer/PlatformBigIntegerArithmetic.kt
+++ b/bignum/src/jsMain/kotlin/com/ionspin/kotlin/bignum/integer/PlatformBigIntegerArithmetic.kt
@@ -22,6 +22,7 @@ package com.ionspin.kotlin.bignum.integer
  * ugljesa.jovanovic@ionspin.com
  * on 10-Mar-2019
  */
+@ExperimentalUnsignedTypes
 actual object PlatformBigIntegerArithmetic : BigIntegerArithmetic<IntArray, Int> {
 
 
@@ -74,7 +75,7 @@ actual object PlatformBigIntegerArithmetic : BigIntegerArithmetic<IntArray, Int>
         TODO("not implemented yet")
     }
 
-    override fun pow(operand: IntArray, exponent: Long): IntArray {
+    override fun pow(base: IntArray, exponent: Long): IntArray {
         TODO("not implemented yet")
     }
 
@@ -82,6 +83,10 @@ actual object PlatformBigIntegerArithmetic : BigIntegerArithmetic<IntArray, Int>
         TODO("not implemented yet")
     }
 
+    override fun reciprocal(operand: IntArray): Pair<IntArray, IntArray> {
+        TODO("not implemented yet")
+    }
+
     override fun parseForBase(number: String, base: Int) : IntArray {
         TODO("not implemented yet")
     }
@@ -90,6 +95,10 @@ actual object PlatformBigIntegerArithmetic : BigIntegerArithmetic<IntArray, Int>
         TODO("not implemented yet")
     }
 
+    override fun numberOfDecimalDigits(operand: IntArray): Long {
+        TODO("not implemented yet")
+    }
+
     override fun fromULong(uLong: ULong): IntArray {
         TODO("not implemented yet")
     }
@@ -126,7 +135,7 @@ actual object PlatformBigIntegerArithmetic : BigIntegerArithmetic<IntArray, Int>
         TODO("not implemented yet")
     }
 
-    override fun inv(operand: IntArray): IntArray {
+    override fun not(operand: IntArray): IntArray {
         TODO("not implemented yet")
     }
 
diff --git a/bignum/src/jvmMain/kotlin/com/ionspin/kotlin/bignum/integer/PlatformBigIntegerArithmetic.kt b/bignum/src/jvmMain/kotlin/com/ionspin/kotlin/bignum/integer/PlatformBigIntegerArithmetic.kt
index c7dc808..1c3825d 100644
--- a/bignum/src/jvmMain/kotlin/com/ionspin/kotlin/bignum/integer/PlatformBigIntegerArithmetic.kt
+++ b/bignum/src/jvmMain/kotlin/com/ionspin/kotlin/bignum/integer/PlatformBigIntegerArithmetic.kt
@@ -22,6 +22,7 @@ package com.ionspin.kotlin.bignum.integer
  * ugljesa.jovanovic@ionspin.com
  * on 10-Mar-2019
  */
+@ExperimentalUnsignedTypes
 actual object PlatformBigIntegerArithmetic : BigIntegerArithmetic<IntArray, Int> {
 
 
@@ -70,13 +71,11 @@ actual object PlatformBigIntegerArithmetic : BigIntegerArithmetic<IntArray, Int>
         TODO("not implemented yet")
     }
 
-
-
     override fun multiply(first: IntArray, second: IntArray): IntArray {
         TODO("not implemented yet")
     }
 
-    override fun pow(operand: IntArray, exponent: Long): IntArray {
+    override fun pow(base: IntArray, exponent: Long): IntArray {
         TODO("not implemented yet")
     }
 
@@ -84,6 +83,10 @@ actual object PlatformBigIntegerArithmetic : BigIntegerArithmetic<IntArray, Int>
         TODO("not implemented yet")
     }
 
+    override fun reciprocal(operand: IntArray): Pair<IntArray, IntArray> {
+        TODO("not implemented yet")
+    }
+
     override fun parseForBase(number: String, base: Int) : IntArray {
         TODO("not implemented yet")
     }
@@ -92,6 +95,10 @@ actual object PlatformBigIntegerArithmetic : BigIntegerArithmetic<IntArray, Int>
         TODO("not implemented yet")
     }
 
+    override fun numberOfDecimalDigits(operand: IntArray): Long {
+        TODO("not implemented yet")
+    }
+
     override fun fromULong(uLong: ULong): IntArray {
         TODO("not implemented yet")
     }
@@ -128,7 +135,7 @@ actual object PlatformBigIntegerArithmetic : BigIntegerArithmetic<IntArray, Int>
         TODO("not implemented yet")
     }
 
-    override fun inv(operand: IntArray): IntArray {
+    override fun not(operand: IntArray): IntArray {
         TODO("not implemented yet")
     }
 
diff --git a/bignum/src/jvmMain/kotlin/com/ionspin/kotlin/bignum/integer/ProfilerRunner.kt b/bignum/src/jvmMain/kotlin/com/ionspin/kotlin/bignum/integer/ProfilerRunner.kt
new file mode 100644
index 0000000..687da12
--- /dev/null
+++ b/bignum/src/jvmMain/kotlin/com/ionspin/kotlin/bignum/integer/ProfilerRunner.kt
@@ -0,0 +1,138 @@
+/*
+ *    Copyright 2019 Ugljesa Jovanovic
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ *
+ */
+
+package com.ionspin.kotlin.bignum.integer
+
+import com.ionspin.kotlin.bignum.integer.base63.BigInteger63Arithmetic
+import kotlinx.coroutines.*
+import org.junit.Test
+import java.math.BigInteger
+import kotlin.random.Random
+import kotlin.random.nextULong
+import kotlin.test.assertTrue
+
+/**
+ * Created by Ugljesa Jovanovic
+ * ugljesa.jovanovic@ionspin.com
+ * on 20-Apr-2019
+ */
+@ExperimentalUnsignedTypes
+class ProfilerRunner {
+    companion object {
+        @Suppress("UNUSED_PARAMETER")
+        fun main(args : List<String>) {
+            ProfilerRunner().runReciprocalVsBaseCaseBenchmark()
+        }
+    }
+
+    data class BenchmarkSample(val dividend : ULongArray, val divisor : ULongArray, val expectedQuotient : ULongArray, val expectedRemainder : ULongArray)
+
+    @Test
+    fun runReciprocalVsBaseCaseBenchmark() {
+        runBlocking {
+            delay(10000)
+        }
+        val seed = 1
+        val random = Random(seed)
+        val sampleList = mutableListOf<BenchmarkSample>()
+
+        val jobList: MutableList<Job> = mutableListOf()
+        val generationStartTime = System.currentTimeMillis()
+        for (i in 0..1000 step 1) {
+            val job = GlobalScope.launch {
+                println("Doing $i")
+                val dividend = ULongArray(200) {
+                    random.nextULong() shr 1
+                }
+                val divisor = ULongArray(180) {
+                    random.nextULong() shr 1
+                }
+                val expectedQuotient = dividend.toJavaBigInteger() / divisor.toJavaBigInteger()
+                val expectedRemainder = dividend.toJavaBigInteger() % divisor.toJavaBigInteger()
+                sampleList.add(BenchmarkSample(
+                    dividend,
+                    divisor,
+                    BigInteger63Arithmetic.parseForBase(expectedQuotient.toString(10), 10),
+                    BigInteger63Arithmetic.parseForBase(expectedRemainder.toString(10), 10)))
+                println("Done $i")
+            }
+            jobList.add(job)
+        }
+        runBlocking {
+            jobList.forEach { it.join() }
+        }
+        val generationEndTime = System.currentTimeMillis()
+        println("Done generating samples, took ${generationEndTime - generationStartTime} ms. Generated samples ${sampleList.size}")
+        runBaseCaseOnSampleList(sampleList)
+        runReciprocalOnSampleList(sampleList)
+        runBaseCaseOnSampleList(sampleList)
+        runReciprocalOnSampleList(sampleList)
+        runBaseCaseOnSampleList(sampleList)
+        runReciprocalOnSampleList(sampleList)
+        runBaseCaseOnSampleList(sampleList)
+        runReciprocalOnSampleList(sampleList)
+        runBaseCaseOnSampleList(sampleList)
+        runReciprocalOnSampleList(sampleList)
+        1 == 1
+
+
+
+    }
+
+    fun runReciprocalOnSampleList(sampleList : List<BenchmarkSample>) {
+        val reciprocalStartTime = System.currentTimeMillis()
+        sampleList.forEach {
+            divideUsingReciprocal(it.dividend, it.divisor, it.expectedQuotient, it.expectedRemainder)
+        }
+        val reciprocalEndTime = System.currentTimeMillis()
+        println("Done reciprocal divide in ${reciprocalEndTime - reciprocalStartTime}")
+    }
+
+    fun runBaseCaseOnSampleList(sampleList: List<BenchmarkSample>) {
+        val baseCaseStartTime = System.currentTimeMillis()
+        sampleList.forEach {
+            divideUsingBaseDivide(it.dividend, it.divisor, it.expectedQuotient, it.expectedRemainder)
+        }
+        val baseCaseEndTime = System.currentTimeMillis()
+        println("Done basecase divide in ${baseCaseEndTime - baseCaseStartTime}")
+    }
+
+
+
+    fun divideUsingReciprocal(dividend : ULongArray, divisor : ULongArray, expectedQuotient : ULongArray, expectedRemainder : ULongArray) {
+        val result = BigInteger63Arithmetic.reciprocalDivision(dividend, divisor)
+        assertTrue {
+            result.first.contentEquals(expectedQuotient) && result.second.contentEquals(expectedRemainder)
+        }
+    }
+
+    fun divideUsingBaseDivide(dividend : ULongArray, divisor : ULongArray, expectedQuotient : ULongArray, expectedRemainder : ULongArray) {
+        val result = BigInteger63Arithmetic.divide(dividend, divisor)
+        assertTrue {
+            result.first.contentEquals(expectedQuotient) && result.second.contentEquals(expectedRemainder)
+        }
+    }
+
+
+    private fun ULongArray.toJavaBigInteger(): BigInteger {
+        return this.foldIndexed(BigInteger.valueOf(0)) { index, acc, digit ->
+            acc.or(BigInteger(digit.toString(), 10).shiftLeft((index) * 63))
+
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/bignum/src/nativeMain/kotlin/com/ionspin/kotlin/bignum/integer/PlatformBigIntegerArithmetic.kt b/bignum/src/nativeMain/kotlin/com/ionspin/kotlin/bignum/integer/PlatformBigIntegerArithmetic.kt
index c96a7ad..b23e510 100644
--- a/bignum/src/nativeMain/kotlin/com/ionspin/kotlin/bignum/integer/PlatformBigIntegerArithmetic.kt
+++ b/bignum/src/nativeMain/kotlin/com/ionspin/kotlin/bignum/integer/PlatformBigIntegerArithmetic.kt
@@ -22,6 +22,7 @@ package com.ionspin.kotlin.bignum.integer
  * ugljesa.jovanovic@ionspin.com
  * on 10-Mar-2019
  */
+@ExperimentalUnsignedTypes
 actual object PlatformBigIntegerArithmetic : BigIntegerArithmetic<IntArray, Int> {
     override val ZERO: IntArray
         get() = TODO("not implemented yet")
@@ -72,13 +73,18 @@ actual object PlatformBigIntegerArithmetic : BigIntegerArithmetic<IntArray, Int>
         TODO("not implemented yet")
     }
 
-    override fun pow(operand: IntArray, exponent: Long): IntArray {
+    override fun pow(base: IntArray, exponent: Long): IntArray {
         TODO("not implemented yet")
     }
 
     override fun divide(first: IntArray, second: IntArray): Pair<IntArray, IntArray> {
         TODO("not implemented yet")
     }
+
+    override fun reciprocal(operand: IntArray): Pair<IntArray, IntArray> {
+        TODO("not implemented yet")
+    }
+    
     override fun parseForBase(number: String, base: Int) : IntArray {
         TODO("not implemented yet")
     }
@@ -87,6 +93,10 @@ actual object PlatformBigIntegerArithmetic : BigIntegerArithmetic<IntArray, Int>
         TODO("not implemented yet")
     }
 
+    override fun numberOfDecimalDigits(operand: IntArray): Long {
+        TODO("not implemented yet")
+    }
+
     override fun fromULong(uLong: ULong): IntArray {
         TODO("not implemented yet")
     }
@@ -123,7 +133,7 @@ actual object PlatformBigIntegerArithmetic : BigIntegerArithmetic<IntArray, Int>
         TODO("not implemented yet")
     }
 
-    override fun inv(operand: IntArray): IntArray {
+    override fun not(operand: IntArray): IntArray {
         TODO("not implemented yet")
     }
 


Test patch:
diff --git a/bignum/src/commonTest/kotlin/com/ionspin/kotlin/bignum/decimal/BigDecimalCreationTest.kt b/bignum/src/commonTest/kotlin/com/ionspin/kotlin/bignum/decimal/BigDecimalCreationTest.kt
index 1509780..9cd7cc1 100644
--- a/bignum/src/commonTest/kotlin/com/ionspin/kotlin/bignum/decimal/BigDecimalCreationTest.kt
+++ b/bignum/src/commonTest/kotlin/com/ionspin/kotlin/bignum/decimal/BigDecimalCreationTest.kt
@@ -17,7 +17,6 @@
 
 package com.ionspin.kotlin.bignum.decimal
 
-import com.ionspin.kotlin.bignum.integer.toBigInteger
 import kotlin.test.Test
 import kotlin.test.assertTrue
 
@@ -32,37 +31,37 @@ class BigDecimalCreationTest {
     @Test
     fun testExpandedParsing() {
         assertTrue {
-            val a = BigDecimal.parseString("1.23")
+            val a = BigDecimal.parseStringWithMode("1.23")
             val b = BigDecimal.fromIntWithExponent(123, 0)
             a == b
         }
 
         assertTrue {
-            val a = BigDecimal.parseString("-1.23")
+            val a = BigDecimal.parseStringWithMode("-1.23")
             val b = BigDecimal.fromIntWithExponent(-123, 0)
             a == b
         }
 
         assertTrue {
-            val a = BigDecimal.parseString("0.0123")
+            val a = BigDecimal.parseStringWithMode("0.0123")
             val b = BigDecimal.fromIntWithExponent(123, -2)
             a == b
         }
 
         assertTrue {
-            val a = BigDecimal.parseString("-0.0123")
+            val a = BigDecimal.parseStringWithMode("-0.0123")
             val b = BigDecimal.fromIntWithExponent(-123, -2)
             a == b
         }
 
         assertTrue {
-            val a = BigDecimal.parseString("123.123")
+            val a = BigDecimal.parseStringWithMode("123.123")
             val b = BigDecimal.fromIntWithExponent(123123, 2)
             a == b
         }
 
         assertTrue {
-            val a = BigDecimal.parseString("-123.123")
+            val a = BigDecimal.parseStringWithMode("-123.123")
             val b = BigDecimal.fromIntWithExponent(-123123, 2)
             a == b
         }
@@ -71,37 +70,37 @@ class BigDecimalCreationTest {
     @Test
     fun testSciNotationParsing() {
         assertTrue {
-            val a = BigDecimal.parseString("1.23E+0")
+            val a = BigDecimal.parseStringWithMode("1.23E+0")
             val b = BigDecimal.fromIntWithExponent(123, 0)
             a == b
         }
 
         assertTrue {
-            val a = BigDecimal.parseString("-1.23e+0")
+            val a = BigDecimal.parseStringWithMode("-1.23e+0")
             val b = BigDecimal.fromIntWithExponent(-123, 0)
             a == b
         }
 
         assertTrue {
-            val a = BigDecimal.parseString("1.23E-2")
+            val a = BigDecimal.parseStringWithMode("1.23E-2")
             val b = BigDecimal.fromIntWithExponent(123, -2)
             a == b
         }
 
         assertTrue {
-            val a = BigDecimal.parseString("-1.23E-2")
+            val a = BigDecimal.parseStringWithMode("-1.23E-2")
             val b = BigDecimal.fromIntWithExponent(-123, -2)
             a == b
         }
 
         assertTrue {
-            val a = BigDecimal.parseString("1.23123e+2")
+            val a = BigDecimal.parseStringWithMode("1.23123e+2")
             val b = BigDecimal.fromIntWithExponent(123123, 2)
             a == b
         }
 
         assertTrue {
-            val a = BigDecimal.parseString("-1.23123E+2")
+            val a = BigDecimal.parseStringWithMode("-1.23123E+2")
             val b = BigDecimal.fromIntWithExponent(-123123, 2)
             a == b
         }
diff --git a/bignum/src/commonTest/kotlin/com/ionspin/kotlin/bignum/decimal/BigDecimalReadmeTest.kt b/bignum/src/commonTest/kotlin/com/ionspin/kotlin/bignum/decimal/BigDecimalReadmeTest.kt
index f9352e4..b973ddb 100644
--- a/bignum/src/commonTest/kotlin/com/ionspin/kotlin/bignum/decimal/BigDecimalReadmeTest.kt
+++ b/bignum/src/commonTest/kotlin/com/ionspin/kotlin/bignum/decimal/BigDecimalReadmeTest.kt
@@ -98,7 +98,7 @@ class BigDecimalReadmeTest {
     fun toStringWithoutExponentTest() {
 
         assertTrue {
-            val bigDecimal = BigDecimal.parseString("123.456")
+            val bigDecimal = BigDecimal.parseStringWithMode("123.456")
             println("BigDecimal: ${bigDecimal.toStringExpanded()}")
             bigDecimal.toStringExpanded() == "123.456"
         }
@@ -164,14 +164,14 @@ class BigDecimalReadmeTest {
     @Test
     fun readmeCreationTest() {
         assertTrue {
-            val bigDecimal = BigDecimal.parseString("0.00000123")
+            val bigDecimal = BigDecimal.parseStringWithMode("0.00000123")
             println("BigDecimal: $bigDecimal")
             bigDecimal.toString() == "1.23E-6"
 
         }
 
         assertTrue {
-            val bigDecimal = BigDecimal.parseString("1.23E-6")
+            val bigDecimal = BigDecimal.parseStringWithMode("1.23E-6")
             println("BigDecimal: $bigDecimal")
             bigDecimal.toString() == "1.23E-6"
 
@@ -214,13 +214,13 @@ class BigDecimalReadmeTest {
         assertFailsWith(ArithmeticException::class) {
             val a = 1.toBigDecimal()
             val b = 3.toBigDecimal()
-            val result = a/b
+            val result = a.divide(b)
         }
 
         assertTrue {
             val a = 1.toBigDecimal()
             val b = 3.toBigDecimal()
-            val result = a.div(b, DecimalMode(20, RoundingMode.ROUND_HALF_AWAY_FROM_ZERO))
+            val result = a.divide(b, DecimalMode(20, RoundingMode.ROUND_HALF_AWAY_FROM_ZERO))
             result.toString() == "3.3333333333333333333E-1"
         }
     }
@@ -229,19 +229,19 @@ class BigDecimalReadmeTest {
     fun readmeBigDecimalExtensionsTest() {
         assertTrue("String to big decimal failed") {
             val bigint = "123456789012345678901234567890.1234567890".toBigDecimal()
-            val expected = BigDecimal.parseString("123456789012345678901234567890.1234567890")
+            val expected = BigDecimal.parseStringWithMode("123456789012345678901234567890.1234567890")
             bigint == expected
         }
 
         assertTrue("Float to big decimal failed") {
             val bigint = 1234f.toBigDecimal()
-            val expected = BigDecimal.parseString("1.234E+3")
+            val expected = BigDecimal.parseStringWithMode("1.234E+3")
             bigint == expected
         }
 
         assertTrue("Double to big decimal dailed") {
             val bigint = 123456789012.0.toBigDecimal()
-            val expected = BigDecimal.parseString("1.23456789012E+11")
+            val expected = BigDecimal.parseStringWithMode("1.23456789012E+11")
             bigint == expected
         }
     }
diff --git a/bignum/src/commonTest/kotlin/com/ionspin/kotlin/bignum/integer/BigIntegerReadmeTest.kt b/bignum/src/commonTest/kotlin/com/ionspin/kotlin/bignum/integer/BigIntegerReadmeTest.kt
index 6f36bc3..5a4779f 100644
--- a/bignum/src/commonTest/kotlin/com/ionspin/kotlin/bignum/integer/BigIntegerReadmeTest.kt
+++ b/bignum/src/commonTest/kotlin/com/ionspin/kotlin/bignum/integer/BigIntegerReadmeTest.kt
@@ -172,7 +172,7 @@ class BigIntegerReadmeTest {
     @Test
     fun `Test_readme_inv_sample`(){
         val operand = BigInteger.parseString("11110000", 2)
-        val invResult = operand.invPrecise()
+        val invResult = operand.not()
         println("Inv result: ${invResult.toString(2)}")
 
         val expectedResult = BigInteger.parseString("00001111", 2)
@@ -182,6 +182,28 @@ class BigIntegerReadmeTest {
 
     }
 
+    @Test
+    fun `Test_readme_negate_sample`(){
+        val a = (-5).toBigInteger()
+        val negated = a.negate()
+        println("Negated: ${negated}")
+
+        val expectedResult = 5.toBigInteger()
+
+        assertTrue { negated == expectedResult }
+    }
+
+    @Test
+    fun `Test_readme_abs_sample`(){
+        val a = (-5).toBigInteger()
+        val negated = a.abs()
+        println("Absolute value: ${negated}")
+
+        val expectedResult = 5.toBigInteger()
+
+        assertTrue { negated == expectedResult }
+    }
+
     @Test
     fun `Test_readme_big_integer_extensions`() {
         assertTrue {
@@ -209,4 +231,12 @@ class BigIntegerReadmeTest {
         }
     }
 
+    @Test
+    fun testToModularBigInteger() {
+        val a = 100_002.toBigInteger()
+        val modularA = a.toModularBigInteger(500.toBigInteger())
+        println("ModularBigInteger: ${modularA.toStringWithModulo()}")
+        assertTrue { modularA.compareTo(2.toBigInteger()) == 0 }
+    }
+
 }
\ No newline at end of file
diff --git a/bignum/src/commonTest/kotlin/com/ionspin/kotlin/bignum/integer/BigIntegerTest.kt b/bignum/src/commonTest/kotlin/com/ionspin/kotlin/bignum/integer/BigIntegerTest.kt
index 9975d6c..e1e2759 100644
--- a/bignum/src/commonTest/kotlin/com/ionspin/kotlin/bignum/integer/BigIntegerTest.kt
+++ b/bignum/src/commonTest/kotlin/com/ionspin/kotlin/bignum/integer/BigIntegerTest.kt
@@ -146,12 +146,26 @@ BigIntegerTest {
 
 
     @Test
-    fun testAddition() {
-        val a = BigInteger.parseString("257751265136509073600000000000000000000000000000000000000000000000000" +
-                "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
-            10)
-        val b = BigInteger.parseString("-6866244039176730022", 10)
-        val res = a + b
+    fun testModInverse() {
+
+        assertTrue {
+            var a = BigInteger(11)
+            var aInverse = a.modInverse(5.toBigInteger())
+            aInverse == BigInteger(1)
+        }
+        assertFailsWith<ArithmeticException> {
+            var a = BigInteger(10)
+            a.modInverse(5.toBigInteger())
+        }
+    }
+
+    @Test
+    fun testGcd() {
+        val a = 10.toBigInteger()
+        val b = 3.toBigInteger()
+        assertTrue { a.gcd(b) == 1.toBigInteger() }
+        var c = 6.toBigInteger()
+        assertTrue { a.gcd(c) == 2.toBigInteger() }
     }
 
 }
\ No newline at end of file
diff --git a/bignum/src/commonTest/kotlin/com/ionspin/kotlin/bignum/integer/BitwiseTest.kt b/bignum/src/commonTest/kotlin/com/ionspin/kotlin/bignum/integer/BitwiseTest.kt
index e4147be..a4ad15b 100644
--- a/bignum/src/commonTest/kotlin/com/ionspin/kotlin/bignum/integer/BitwiseTest.kt
+++ b/bignum/src/commonTest/kotlin/com/ionspin/kotlin/bignum/integer/BitwiseTest.kt
@@ -44,7 +44,7 @@ class BitwiseTest {
     @Test
     fun numberOfDigitsTest() {
         val bigInteger = BigInteger.parseString("123456789012345678901234567890123456", 10)
-        val numberOfDigits = bigInteger.numberOfDigits()
+        val numberOfDigits = bigInteger.numberOfDecimalDigits()
         val expectedDigits = 36L
         assertTrue { numberOfDigits == expectedDigits }
     }
@@ -54,7 +54,7 @@ class BitwiseTest {
         for (i in 1 .. 2000L step 101) {
             val string = buildString (i.toInt()) { for (j in 1 .. i) this.append('1')  }
             val bigInteger = BigInteger.parseString(string, 10)
-            val numberOfDigits = bigInteger.numberOfDigits()
+            val numberOfDigits = bigInteger.numberOfDecimalDigits()
             assertTrue { numberOfDigits == i }
         }
 
diff --git a/bignum/src/commonTest/kotlin/com/ionspin/kotlin/bignum/integer/arithmetic/DivisionBenchmark.kt b/bignum/src/commonTest/kotlin/com/ionspin/kotlin/bignum/integer/arithmetic/DivisionBenchmark.kt
new file mode 100644
index 0000000..074ec04
--- /dev/null
+++ b/bignum/src/commonTest/kotlin/com/ionspin/kotlin/bignum/integer/arithmetic/DivisionBenchmark.kt
@@ -0,0 +1,36 @@
+/*
+ *    Copyright 2019 Ugljesa Jovanovic
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ *
+ */
+
+package com.ionspin.kotlin.bignum.integer.arithmetic
+
+import com.ionspin.kotlin.bignum.integer.base63.BigInteger63Arithmetic
+import kotlinx.coroutines.Job
+
+/**
+ * Created by Ugljesa Jovanovic
+ * ugljesa.jovanovic@ionspin.com
+ * on 20-Apr-2019
+ */
+@ExperimentalUnsignedTypes
+class DivisionBenchmark {
+
+
+//    fun divideUsingReciprocal(dividend : ULongArray, divisor : ULongArray, expectedQuotient : ULongArray, expectedRemainder : ULongArray) {
+//        val result = BigInteger63Arithmetic.reciprocalDivision(dividend, divisor)
+//    }
+
+}
\ No newline at end of file
diff --git a/bignum/src/commonTest/kotlin/com/ionspin/kotlin/bignum/modular/ModularBigIntegerAddition.kt b/bignum/src/commonTest/kotlin/com/ionspin/kotlin/bignum/modular/ModularBigIntegerAddition.kt
new file mode 100644
index 0000000..50cab13
--- /dev/null
+++ b/bignum/src/commonTest/kotlin/com/ionspin/kotlin/bignum/modular/ModularBigIntegerAddition.kt
@@ -0,0 +1,46 @@
+/*
+ *    Copyright 2019 Ugljesa Jovanovic
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ *
+ */
+
+package com.ionspin.kotlin.bignum.modular
+
+import kotlin.test.Test
+import kotlin.test.assertTrue
+
+/**
+ * Created by Ugljesa Jovanovic
+ * ugljesa.jovanovic@ionspin.com
+ * on 22-Apr-2019
+ */
+@ExperimentalUnsignedTypes
+class ModularBigIntegerAddition {
+    @Test
+    fun testAddition() {
+        val creator = ModularBigInteger.creatorForModulo(10)
+        val a = creator.fromInt(5)
+        val b = creator.fromInt(7)
+        val expected = creator.fromInt(2)
+        testSingleAddition(a, b, expected)
+    }
+
+
+    fun testSingleAddition(a : ModularBigInteger, b : ModularBigInteger, expected :ModularBigInteger) {
+        assertTrue {
+            val c = a + b
+            c == expected
+        }
+    }
+}
\ No newline at end of file
diff --git a/bignum/src/commonTest/kotlin/com/ionspin/kotlin/bignum/modular/ModularBigIntegerReadmeTest.kt b/bignum/src/commonTest/kotlin/com/ionspin/kotlin/bignum/modular/ModularBigIntegerReadmeTest.kt
new file mode 100644
index 0000000..55af618
--- /dev/null
+++ b/bignum/src/commonTest/kotlin/com/ionspin/kotlin/bignum/modular/ModularBigIntegerReadmeTest.kt
@@ -0,0 +1,41 @@
+/*
+ *    Copyright 2019 Ugljesa Jovanovic
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ *
+ */
+
+package com.ionspin.kotlin.bignum.modular
+
+import com.ionspin.kotlin.bignum.integer.toBigInteger
+import kotlin.test.Test
+import kotlin.test.assertTrue
+
+/**
+ * Created by Ugljesa Jovanovic
+ * ugljesa.jovanovic@ionspin.com
+ * on 22-Apr-2019
+ */
+@ExperimentalUnsignedTypes
+class ModularBigIntegerReadmeTest {
+
+    @Test
+    fun createModularBigInteger() {
+        val creator = ModularBigInteger.creatorForModulo(100)
+        val modularBigInteger = creator.fromLong(150)
+        println("ModularBigInteger: ${modularBigInteger.toStringWithModulo()}")
+        assertTrue {
+            modularBigInteger.residue == 50.toBigInteger()
+        }
+    }
+}
\ No newline at end of file
diff --git a/bignum/src/jvmTest/kotlin/com/ionspin/kotlin/bignum/decimal/BigDecimalJvmTest.kt b/bignum/src/jvmTest/kotlin/com/ionspin/kotlin/bignum/decimal/BigDecimalJvmTest.kt
index 6c5e535..610747b 100644
--- a/bignum/src/jvmTest/kotlin/com/ionspin/kotlin/bignum/decimal/BigDecimalJvmTest.kt
+++ b/bignum/src/jvmTest/kotlin/com/ionspin/kotlin/bignum/decimal/BigDecimalJvmTest.kt
@@ -195,12 +195,13 @@ class BigDecimalJvmTest {
     }
 
 
+    @Suppress("UNUSED_PARAMETER")
     fun singleAdditionTest(i: Int, first: BigDecimal, second: BigDecimal): Job {
         return GlobalScope.launch {
             assertTrue(
                 "Failed on \n" +
-                        "val first = BigDecimal.fromBigIntegerWithExponent(BigInteger.parseString(\"${first.significand}\", 10), ${first.exponent}.toBigInteger())\n " +
-                        "val second = BigDecimal.fromBigIntegerWithExponent(BigInteger.parseString(\"${second.significand}\", 10), ${second.exponent}.toBigInteger())"
+                        "val first = BigDecimal.fromBigIntegerWithExponent(BigInteger.parseStringWithMode(\"${first.significand}\", 10), ${first.exponent}.toBigInteger())\n " +
+                        "val second = BigDecimal.fromBigIntegerWithExponent(BigInteger.parseStringWithMode(\"${second.significand}\", 10), ${second.exponent}.toBigInteger())"
             ) {
                 val result = first + second
                 val resultJavaBigInt = first.toJavaBigDecimal() + second.toJavaBigDecimal()
@@ -245,13 +246,13 @@ class BigDecimalJvmTest {
         }
     }
 
-
+    @Suppress("UNUSED_PARAMETER")
     fun singleSubtractionTest(i: Int, first: BigDecimal, second: BigDecimal): Job {
         return GlobalScope.launch {
             assertTrue(
                 "Failed on \n" +
-                        "val first = BigDecimal.fromBigIntegerWithExponent(BigInteger.parseString(\"${first.significand}\", 10), ${first.exponent}.toBigInteger())\n " +
-                        "val second = BigDecimal.fromBigIntegerWithExponent(BigInteger.parseString(\"${second.significand}\", 10), ${second.exponent}.toBigInteger())"
+                        "val first = BigDecimal.fromBigIntegerWithExponent(BigInteger.parseStringWithMode(\"${first.significand}\", 10), ${first.exponent}.toBigInteger())\n " +
+                        "val second = BigDecimal.fromBigIntegerWithExponent(BigInteger.parseStringWithMode(\"${second.significand}\", 10), ${second.exponent}.toBigInteger())"
             ) {
                 val result = first - second
                 val resultJavaBigInt = first.toJavaBigDecimal() - second.toJavaBigDecimal()
@@ -312,13 +313,13 @@ class BigDecimalJvmTest {
             }
         }
     }
-
+    @Suppress("UNUSED_PARAMETER")
     fun singleMultiplicationTest(i: Int, first: BigDecimal, second: BigDecimal): Job {
         return GlobalScope.launch {
             assertTrue(
                 "Failed on \n" +
-                        "val first = BigDecimal.fromBigIntegerWithExponent(BigInteger.parseString(\"${first.significand}\", 10), ${first.exponent}.toBigInteger())\n " +
-                        "val second = BigDecimal.fromBigIntegerWithExponent(BigInteger.parseString(\"${second.significand}\", 10), ${second.exponent}.toBigInteger())"
+                        "val first = BigDecimal.fromBigIntegerWithExponent(BigInteger.parseStringWithMode(\"${first.significand}\", 10), ${first.exponent}.toBigInteger())\n " +
+                        "val second = BigDecimal.fromBigIntegerWithExponent(BigInteger.parseStringWithMode(\"${second.significand}\", 10), ${second.exponent}.toBigInteger())"
             ) {
                 val result = first * second
                 val resultJavaBigInt = first.toJavaBigDecimal() * second.toJavaBigDecimal()
@@ -337,7 +338,7 @@ class BigDecimalJvmTest {
             val second = BigDecimal.fromLongWithExponent(71, -2)
             val javaBigSecond = second.toJavaBigDecimal()
 
-            val result = first.div(second, DecimalMode(99, RoundingMode.AWAY_FROM_ZERO))
+            val result = first.divide(second, DecimalMode(99, RoundingMode.AWAY_FROM_ZERO))
             val javaBigResult = javaBigFirst.divide(javaBigSecond, MathContext(99, java.math.RoundingMode.UP))
 
             result.toJavaBigDecimal().compareTo(javaBigResult) == 0
@@ -352,7 +353,7 @@ class BigDecimalJvmTest {
             val second = BigDecimal.fromLongWithExponent(3L, 0)
             val javaBigSecond = second.toJavaBigDecimal()
 
-            val result = first.div(second, DecimalMode(99, RoundingMode.AWAY_FROM_ZERO))
+            val result = first.divide(second, DecimalMode(99, RoundingMode.AWAY_FROM_ZERO))
             val javaBigResult = javaBigFirst.divide(javaBigSecond, MathContext(99, java.math.RoundingMode.UP))
 
             result.toJavaBigDecimal().compareTo(javaBigResult) == 0
@@ -367,7 +368,7 @@ class BigDecimalJvmTest {
             val second = BigDecimal.fromLongWithExponent(71, -2)
             val javaBigSecond = second.toJavaBigDecimal()
 
-            val result = first.div(second, DecimalMode(123, RoundingMode.AWAY_FROM_ZERO))
+            val result = first.divide(second, DecimalMode(123, RoundingMode.AWAY_FROM_ZERO))
             val javaBigResult = javaBigFirst.divide(javaBigSecond, MathContext(123, java.math.RoundingMode.UP))
 
             result.toJavaBigDecimal().compareTo(javaBigResult) == 0
@@ -382,7 +383,7 @@ class BigDecimalJvmTest {
             val second = BigDecimal.fromLongWithExponent(3L, 0)
             val javaBigSecond = second.toJavaBigDecimal()
 
-            val result = first.div(second, DecimalMode(401, RoundingMode.AWAY_FROM_ZERO))
+            val result = first.divide(second, DecimalMode(401, RoundingMode.AWAY_FROM_ZERO))
             val javaBigResult = javaBigFirst.divide(javaBigSecond, MathContext(401, java.math.RoundingMode.UP))
 
             result.toJavaBigDecimal().compareTo(javaBigResult) == 0
@@ -393,10 +394,10 @@ class BigDecimalJvmTest {
 
     @Test
     fun debugTestDivision() {
-//        val first = BigDecimal.fromBigIntegerWithExponent(BigInteger.parseString("-884653051988182590", 10), 124.toBigInteger())
-//        val second = BigDecimal.fromBigIntegerWithExponent(BigInteger.parseString("686869704857289531", 10), 51.toBigInteger())
-//        val first = BigDecimal.fromBigIntegerWithExponent(BigInteger.parseString("-2573868278004278171", 10), 86.toBigInteger())
-//        val second = BigDecimal.fromBigIntegerWithExponent(BigInteger.parseString("7343078399229486119", 10), 16.toBigInteger())
+//        val first = BigDecimal.fromBigIntegerWithExponent(BigInteger.parseStringWithMode("-884653051988182590", 10), 124.toBigInteger())
+//        val second = BigDecimal.fromBigIntegerWithExponent(BigInteger.parseStringWithMode("686869704857289531", 10), 51.toBigInteger())
+//        val first = BigDecimal.fromBigIntegerWithExponent(BigInteger.parseStringWithMode("-2573868278004278171", 10), 86.toBigInteger())
+//        val second = BigDecimal.fromBigIntegerWithExponent(BigInteger.parseStringWithMode("7343078399229486119", 10), 16.toBigInteger())
         val first = BigDecimal.fromBigIntegerWithExponent(BigInteger.parseString("-7823836971981477152", 10), 167.toBigInteger())
         val second = BigDecimal.fromBigIntegerWithExponent(BigInteger.parseString("-1241920988109618346", 10), 118.toBigInteger())
 
@@ -404,7 +405,7 @@ class BigDecimalJvmTest {
 
         val javaBigSecond = second.toJavaBigDecimal()
 
-        val result = first.div(second, DecimalMode(401, RoundingMode.AWAY_FROM_ZERO))
+        val result = first.divide(second, DecimalMode(401, RoundingMode.AWAY_FROM_ZERO))
         val javaBigResult = javaBigFirst.divide(javaBigSecond, MathContext(401, java.math.RoundingMode.UP))
         assertTrue {
             result.toJavaBigDecimal().compareTo(javaBigResult) == 0
@@ -428,18 +429,18 @@ class BigDecimalJvmTest {
         }
     }
 
-    fun singleDivisionTest(first: BigDecimal, second: BigDecimal): Job {
+    private fun singleDivisionTest(first: BigDecimal, second: BigDecimal): Job {
         return GlobalScope.launch {
             assertTrue(
                 "Failed on \n" +
-                        "val first = BigDecimal.fromBigIntegerWithExponent(BigInteger.parseString(\"${first.significand}\", 10), ${first.exponent}.toBigInteger())\n " +
-                        "val second = BigDecimal.fromBigIntegerWithExponent(BigInteger.parseString(\"${second.significand}\", 10), ${second.exponent}.toBigInteger())"
+                        "val first = BigDecimal.fromBigIntegerWithExponent(BigInteger.parseStringWithMode(\"${first.significand}\", 10), ${first.exponent}.toBigInteger())\n " +
+                        "val second = BigDecimal.fromBigIntegerWithExponent(BigInteger.parseStringWithMode(\"${second.significand}\", 10), ${second.exponent}.toBigInteger())"
             ) {
                 val javaBigFirst = first.toJavaBigDecimal()
 
                 val javaBigSecond = second.toJavaBigDecimal()
 
-                val result = first.div(second, DecimalMode(401, RoundingMode.AWAY_FROM_ZERO))
+                val result = first.divide(second, DecimalMode(401, RoundingMode.AWAY_FROM_ZERO))
                 val javaBigResult = javaBigFirst.divide(javaBigSecond, MathContext(401, java.math.RoundingMode.UP))
 
                 result.toJavaBigDecimal().compareTo(javaBigResult) == 0
diff --git a/bignum/src/jvmTest/kotlin/com/ionspin/kotlin/bignum/integer/BigIntegerJvmTest.kt b/bignum/src/jvmTest/kotlin/com/ionspin/kotlin/bignum/integer/BigIntegerJvmTest.kt
new file mode 100644
index 0000000..056ce84
--- /dev/null
+++ b/bignum/src/jvmTest/kotlin/com/ionspin/kotlin/bignum/integer/BigIntegerJvmTest.kt
@@ -0,0 +1,93 @@
+/*
+ *    Copyright 2019 Ugljesa Jovanovic
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ *
+ */
+
+package com.ionspin.kotlin.bignum.integer
+
+import com.ionspin.kotlin.bignum.integer.BigInteger.Companion.ZERO
+import com.ionspin.kotlin.bignum.integer.base63.toJavaBigInteger
+import kotlinx.coroutines.GlobalScope
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.runBlocking
+import org.junit.Test
+import kotlin.random.Random
+import kotlin.random.nextULong
+import kotlin.test.assertTrue
+
+/**
+ * Created by Ugljesa Jovanovic
+ * ugljesa.jovanovic@ionspin.com
+ * on 22-Apr-2019
+ */
+@ExperimentalUnsignedTypes
+class BigIntegerJvmTest {
+
+
+    @Test
+    fun testModInverse() {
+        val a = BigInteger(11)
+        val aInverse = a.modInverse(5.toBigInteger())
+        val aJavaInverse = a.toJavaBigInteger().modInverse(java.math.BigInteger.valueOf(5))
+        assertTrue {
+            aInverse.toJavaBigInteger() == aJavaInverse
+        }
+    }
+    //TODO need to implement better testcase, need better coprime generation
+    @Test
+    fun testRandomModInverse() {
+        val seed = 1
+        var random = Random(seed)
+        val jobList: MutableList<Job> = mutableListOf()
+        for (i in 1..1000) {
+            val length = random.nextInt(2, 50)
+            val a = ULongArray(length) {
+                random.nextULong() shr 1
+            }
+
+            val job = GlobalScope.launch {
+                try {
+                    val aBigInt = BigInteger(a, Sign.POSITIVE)
+                    val aPrepared = if (aBigInt % 2 != ZERO) {
+                        aBigInt
+                    } else {
+                        aBigInt - 1
+                    }
+
+                    val bPrepared = aPrepared - 1
+                    testSingleModInverse(aPrepared, bPrepared)
+                } catch (exception: Exception) {
+                    println("Failed on $length")
+                    exception.printStackTrace()
+                }
+            }
+            jobList.add(job)
+
+        }
+        runBlocking {
+            jobList.forEach { it.join() }
+        }
+
+    }
+
+    fun testSingleModInverse(bigInteger: BigInteger, modulo: BigInteger) {
+        assertTrue {
+            val inverse = bigInteger.modInverse(modulo)
+            val javaInverse = bigInteger.toJavaBigInteger().modInverse(modulo.toJavaBigInteger())
+            inverse.toJavaBigInteger().compareTo(javaInverse) == 0
+        }
+    }
+}
\ No newline at end of file
diff --git a/bignum/src/jvmTest/kotlin/com/ionspin/kotlin/bignum/integer/base32/BigInteger32JavaBitwiseTest.kt b/bignum/src/jvmTest/kotlin/com/ionspin/kotlin/bignum/integer/base32/BigInteger32JavaBitwiseTest.kt
index 780dc56..f87424c 100644
--- a/bignum/src/jvmTest/kotlin/com/ionspin/kotlin/bignum/integer/base32/BigInteger32JavaBitwiseTest.kt
+++ b/bignum/src/jvmTest/kotlin/com/ionspin/kotlin/bignum/integer/base32/BigInteger32JavaBitwiseTest.kt
@@ -90,6 +90,17 @@ class BigInteger32JavaBitwiseTest {
 
     }
 
+    @Test
+    fun `Test shift right with specific values`() {
+        val a = intArrayOf(752029288,
+        -964625924,
+        479674580,
+        -1697013934,
+        -1956440078,
+        -1550357085).toUIntArray()
+        shiftRightSingleTest(128, number = a)
+    }
+
     fun shiftRightSingleTest(places : Int, number : UIntArray) {
         assertTrue ("Failed for $places and elements ${number.contentToString()}") {
             val result = BigInteger32Arithmetic.shiftRight(number, places)
diff --git a/bignum/src/jvmTest/kotlin/com/ionspin/kotlin/bignum/integer/base32/BigInteger32JavaDivisionTest.kt b/bignum/src/jvmTest/kotlin/com/ionspin/kotlin/bignum/integer/base32/BigInteger32JavaDivisionTest.kt
index 0856b44..c243877 100644
--- a/bignum/src/jvmTest/kotlin/com/ionspin/kotlin/bignum/integer/base32/BigInteger32JavaDivisionTest.kt
+++ b/bignum/src/jvmTest/kotlin/com/ionspin/kotlin/bignum/integer/base32/BigInteger32JavaDivisionTest.kt
@@ -15,16 +15,23 @@
  *
  */
 
+@file:Suppress("SimplifyBooleanWithConstants")
+
 package com.ionspin.kotlin.bignum.integer.base32
 
-import kotlinx.coroutines.GlobalScope
-import kotlinx.coroutines.Job
-import kotlinx.coroutines.launch
-import kotlinx.coroutines.runBlocking
+import com.ionspin.kotlin.bignum.integer.base63.BigInteger63Arithmetic
+import com.ionspin.kotlin.bignum.integer.base63.toJavaBigInteger
+import kotlinx.coroutines.*
+import org.junit.Ignore
 import org.junit.Test
 import java.lang.ArithmeticException
+import java.math.BigDecimal
+import java.math.BigInteger
+import java.math.MathContext
+import java.math.RoundingMode
 import kotlin.random.Random
 import kotlin.random.nextUInt
+import kotlin.random.nextULong
 import kotlin.test.assertFailsWith
 import kotlin.test.assertTrue
 
@@ -245,4 +252,226 @@ class BigInteger32JavaDivisionTest {
 
         }
     }
+    @Test
+    fun reciprocalTest() {
+        val a = uintArrayOf(100u)
+        val reciprocal = BigInteger32Arithmetic.reciprocalSingleWord(100u)
+        println("Rec ${reciprocal.first} * 2 ^ - ${reciprocal.second}")
+        val reconstructed = BigInteger32Arithmetic.shiftRight(
+            BigInteger32Arithmetic.multiply(a, reciprocal.first),
+            reciprocal.second
+            )
+        println("Reconstructed: ${reconstructed.contentToString()}")
+    }
+
+    @Ignore("Obsolete  reciprocal method")
+    @Test
+    fun debugSingleReciprocalOneWordTest() {
+        singleReciprocalOneWordTest(1074310744U)
+    }
+
+    @Ignore("Obsolete reciprocal method")
+    @Test
+    fun reciprocalOneWordRandomTest() {
+        val seed = 1
+        val random = Random(seed)
+        val jobList: MutableList<Job> = mutableListOf()
+        for (i in 1..Int.MAX_VALUE step 10001) {
+            val word = random.nextUInt()
+            jobList.add(
+                GlobalScope.launch {
+                    singleReciprocalOneWordTest(word)
+                }
+            )
+        }
+        runBlocking {
+            jobList.forEach {
+                it.join()
+            }
+        }
+
+
+    }
+
+    fun singleReciprocalOneWordTest(word : UInt) {
+        assertTrue ("Failed on $word") {
+            val reciprocal = BigInteger32Arithmetic.reciprocalSingleWord(word)
+            val resultJavaBigDecimal = reciprocal.first.toJavaBigInteger().toBigDecimal()
+            val wordJavaBigDecimal = uintArrayOf(word).toJavaBigInteger().toBigDecimal()
+            val multiplication = (resultJavaBigDecimal * wordJavaBigDecimal)
+            val result = multiplication / 2.toBigInteger().pow(reciprocal.second).toBigDecimal()
+            val rounded = result.round(MathContext(2, RoundingMode.HALF_EVEN))
+            rounded.compareTo(BigDecimal.valueOf(1.0)) == 0
+
+        }
+    }
+    @Test
+    fun testRandomReciprocalDivisionWithOneWord() {
+        val seed = 1
+        val random = Random(seed)
+        val jobList: MutableList<Job> = mutableListOf()
+        for (i in 1..Int.MAX_VALUE step 3001) {
+            val word = random.nextUInt()
+            val dividend = uintArrayOf(random.nextUInt(), random.nextUInt(), random.nextUInt())
+            jobList.add(
+                GlobalScope.launch {
+                    testSingleReciprocalDivisonWithOneWord(dividend, word)
+                }
+            )
+        }
+        runBlocking {
+            jobList.forEach {
+                it.join()
+            }
+        }
+    }
+    @Test
+    fun singleReciprocalDivisionTestOneWord() {
+        val dividend = uintArrayOf(3504818262U, 3616430151U, 2530148830U)
+        val divisor = (3959362403U)
+        testSingleReciprocalDivisonWithOneWord(dividend, divisor)
+    }
+
+    fun testSingleReciprocalDivisonWithOneWord(dividend: UIntArray, divisor : UInt) {
+
+        val arrayDivisor = uintArrayOf(divisor)
+        val javaDividend = dividend.toJavaBigInteger()
+        val javaDivisor = arrayDivisor.toJavaBigInteger()
+        val expectedQuotient = javaDividend / javaDivisor
+        val expectedRemainder = javaDividend.rem(javaDivisor)
+        val (resultQuotient, resultRemainder) = BigInteger32Arithmetic.reciprocalDivision(dividend, arrayDivisor)
+        val javaResultQuotient = resultQuotient.toJavaBigInteger()
+        val javaResultRemainder = resultRemainder.toJavaBigInteger()
+        assertTrue ("Failed on \nval dividend = uintArrayOf(${dividend.joinToString(separator = ", ") { "${it}U"}})" +
+                "\nval divisor = ${divisor}U\n"){
+            javaResultQuotient.compareTo(expectedQuotient) == 0 &&
+                    javaResultRemainder.compareTo(expectedRemainder) == 0
+        }
+
+    }
+
+    @Test
+    fun singleReciprocalDivisionTest() {
+//        val dividend = uintArrayOf(3504818262U, 3616430151U, 2530148830U)
+//        val divisor = (3959362403U)
+        val dividend = uintArrayOf(3449361588U, 1756843090U, 1453467775U, 4067428664U, 3191437204U, 2658797275U, 4118577093U, 1510408169U, 1655916993U, 393078469U)
+        val divisor = uintArrayOf(2509423399U, 2721619526U, 1561595252U, 3307230229U, 3373635748U, 761261538U, 3754926477U, 2390345401U, 616031684U)
+//        val dividend = uintArrayOf(2412223697U, 4003211491U, 2443024406U, 2156654946U, 3316815183U, 3124443256U, 48471415U, 3368762895U, 1329509906U, 2006838763U)
+//        val divisor = uintArrayOf(3868219553U, 1852467980U, 291647052U, 1400631124U, 969215731U, 750739415U, 7935153U, 2131261330U, 553254777U)
+        testSingleReciprocalDivison(dividend, divisor)
+    }
+
+    fun testSingleReciprocalDivison(dividend: UIntArray, divisor : UIntArray) {
+
+        val javaDividend = dividend.toJavaBigInteger()
+        val javaDivisor = divisor.toJavaBigInteger()
+        val expectedQuotient = javaDividend / javaDivisor
+        val expectedRemainder = javaDividend.rem(javaDivisor)
+        val (resultQuotient, resultRemainder) = BigInteger32Arithmetic.reciprocalDivision(dividend, divisor)
+        val javaResultQuotient = resultQuotient.toJavaBigInteger()
+        val javaResultRemainder = resultRemainder.toJavaBigInteger()
+        assertTrue ("Failed on \nval dividend = uintArrayOf(${dividend.joinToString(separator = ", ") { "${it}U"}})" +
+                "\nval divisor = ${divisor}U\n"){
+            javaResultQuotient.compareTo(expectedQuotient) == 0 &&
+                    javaResultRemainder.compareTo(expectedRemainder) == 0
+        }
+
+    }
+
+}
+
+@ExperimentalUnsignedTypes
+class DivisionBenchmark {
+
+    data class BenchmarkSample32Bit(val dividend : UIntArray, val divisor : UIntArray, val expectedQuotient : UIntArray, val expectedRemainder : UIntArray)
+
+    @Ignore("This should be run only when necessary")
+    @Test
+    fun runReciprocalVsBaseCaseBenchmark() {
+        runBlocking {
+            delay(10000)
+        }
+        val seed = 1
+        val random = Random(seed)
+        val sampleList = mutableListOf<BenchmarkSample32Bit>()
+
+        val jobList: MutableList<Job> = mutableListOf()
+        val generationStartTime = System.currentTimeMillis()
+        for (i in 0..1000 step 1) {
+            val job = GlobalScope.launch {
+                println("Doing $i")
+                val dividend = UIntArray(10) {
+                    random.nextUInt()
+                }
+                val divisor = UIntArray(9) {
+                    random.nextUInt()
+                }
+                val expectedQuotient = dividend.toJavaBigInteger() / divisor.toJavaBigInteger()
+                val expectedRemainder = dividend.toJavaBigInteger() % divisor.toJavaBigInteger()
+                sampleList.add(BenchmarkSample32Bit(
+                    dividend,
+                    divisor,
+                    BigInteger32Arithmetic.parseForBase(expectedQuotient.toString(10), 10),
+                    BigInteger32Arithmetic.parseForBase(expectedRemainder.toString(10), 10)))
+                println("Done $i")
+            }
+            jobList.add(job)
+        }
+        runBlocking {
+            jobList.forEach { it.join() }
+        }
+        val generationEndTime = System.currentTimeMillis()
+        println("Done generating samples, took ${generationEndTime - generationStartTime} ms. Generated samples ${sampleList.size}")
+        runBaseCaseOnSampleList(sampleList)
+        runReciprocalOnSampleList(sampleList)
+        runBaseCaseOnSampleList(sampleList)
+        runReciprocalOnSampleList(sampleList)
+        runBaseCaseOnSampleList(sampleList)
+        runReciprocalOnSampleList(sampleList)
+        runBaseCaseOnSampleList(sampleList)
+        runReciprocalOnSampleList(sampleList)
+        runBaseCaseOnSampleList(sampleList)
+        runReciprocalOnSampleList(sampleList)
+        1 == 1
+
+
+
+    }
+
+    fun runReciprocalOnSampleList(sampleList : List<BenchmarkSample32Bit>) {
+        val reciprocalStartTime = System.currentTimeMillis()
+        sampleList.forEach {
+            divideUsingReciprocal(it.dividend, it.divisor, it.expectedQuotient, it.expectedRemainder)
+        }
+        val reciprocalEndTime = System.currentTimeMillis()
+        println("Done reciprocal divide in ${reciprocalEndTime - reciprocalStartTime}")
+    }
+
+    fun runBaseCaseOnSampleList(sampleList: List<BenchmarkSample32Bit>) {
+        val baseCaseStartTime = System.currentTimeMillis()
+        sampleList.forEach {
+            divideUsingBaseDivide(it.dividend, it.divisor, it.expectedQuotient, it.expectedRemainder)
+        }
+        val baseCaseEndTime = System.currentTimeMillis()
+        println("Done basecase divide in ${baseCaseEndTime - baseCaseStartTime}")
+    }
+
+
+
+    fun divideUsingReciprocal(dividend : UIntArray, divisor : UIntArray, expectedQuotient : UIntArray, expectedRemainder : UIntArray) {
+        val result = BigInteger32Arithmetic.reciprocalDivision(dividend, divisor)
+        assertTrue ("Failed on: \n val dividend = uintArrayOf(${dividend.joinToString(separator =", ") { "${it}U"}})\n" +
+                "val divisor = uintArrayOf(${divisor.joinToString(separator =", ") { "${it}U"}})"){
+
+            result.first.contentEquals(expectedQuotient) && result.second.contentEquals(expectedRemainder)
+        }
+    }
+
+    fun divideUsingBaseDivide(dividend : UIntArray, divisor : UIntArray, expectedQuotient : UIntArray, expectedRemainder : UIntArray) {
+        val result = BigInteger32Arithmetic.divide(dividend, divisor)
+        assertTrue {
+            result.first.contentEquals(expectedQuotient) && result.second.contentEquals(expectedRemainder)
+        }
+    }
+
 }
\ No newline at end of file
diff --git a/bignum/src/jvmTest/kotlin/com/ionspin/kotlin/bignum/integer/base63/BigInteger63JavaBitwiseTest.kt b/bignum/src/jvmTest/kotlin/com/ionspin/kotlin/bignum/integer/base63/BigInteger63JavaBitwiseTest.kt
index 5b31b0a..0502887 100644
--- a/bignum/src/jvmTest/kotlin/com/ionspin/kotlin/bignum/integer/base63/BigInteger63JavaBitwiseTest.kt
+++ b/bignum/src/jvmTest/kotlin/com/ionspin/kotlin/bignum/integer/base63/BigInteger63JavaBitwiseTest.kt
@@ -215,7 +215,7 @@ class BigInteger63JavaBitwiseTest {
 
     //Hmmm this is not behaving as I would expect it to on java side
     fun singleInvTest(operand: ULongArray) {
-        val result = BigInteger63Arithmetic.inv(operand)
+        val result = BigInteger63Arithmetic.not(operand)
         val bigIntResult = operand.toJavaBigInteger()
             .xor(1.toBigInteger().shr(operand.toJavaBigInteger().bitLength()) - 1.toBigInteger())
 
diff --git a/bignum/src/jvmTest/kotlin/com/ionspin/kotlin/bignum/integer/base63/BigInteger63JavaDivisionTest.kt b/bignum/src/jvmTest/kotlin/com/ionspin/kotlin/bignum/integer/base63/BigInteger63JavaDivisionTest.kt
index 3aa4015..89418f8 100644
--- a/bignum/src/jvmTest/kotlin/com/ionspin/kotlin/bignum/integer/base63/BigInteger63JavaDivisionTest.kt
+++ b/bignum/src/jvmTest/kotlin/com/ionspin/kotlin/bignum/integer/base63/BigInteger63JavaDivisionTest.kt
@@ -17,13 +17,14 @@
 
 package com.ionspin.kotlin.bignum.integer.base63
 
-import kotlinx.coroutines.GlobalScope
-import kotlinx.coroutines.Job
-import kotlinx.coroutines.launch
-import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.*
 import org.junit.Test
+import java.lang.Exception
+import java.lang.RuntimeException
+import java.math.BigInteger
 import kotlin.random.Random
 import kotlin.random.nextULong
+import kotlin.test.Ignore
 import kotlin.test.assertTrue
 
 /**
@@ -97,13 +98,15 @@ class BigInteger63JavaDivisionTest {
 
             val a = ulongArrayOf(random.nextULong() shr 1, random.nextULong() shr 1)
             val b = ulongArrayOf(random.nextULong() shr 1, random.nextULong() shr 1)
-            GlobalScope.launch {
-                if (BigInteger63Arithmetic.compare(a, b) > 0) {
-                    divisionSingleTest(a, b)
-                } else {
-                    divisionSingleTest(b, a)
+            jobList.add(
+                GlobalScope.launch {
+                    if (BigInteger63Arithmetic.compare(a, b) > 0) {
+                        divisionSingleTest(a, b)
+                    } else {
+                        divisionSingleTest(b, a)
+                    }
                 }
-            }
+            )
 
 
         }
@@ -117,40 +120,59 @@ class BigInteger63JavaDivisionTest {
     fun `Test four words divided by two words`() {
         val seed = 1
         val random = Random(seed)
+
+        val jobList: MutableList<Job> = mutableListOf()
         for (i in 1..Int.MAX_VALUE step 3001) {
 
-            val a = ulongArrayOf(random.nextULong() shr 1, random.nextULong() shr 1, random.nextULong() shr 1, random.nextULong() shr 1)
+            val a = ulongArrayOf(
+                random.nextULong() shr 1,
+                random.nextULong() shr 1,
+                random.nextULong() shr 1,
+                random.nextULong() shr 1
+            )
             val b = ulongArrayOf(random.nextULong() shr 1, random.nextULong() shr 1)
-            GlobalScope.launch {
-                try {
-                    if (BigInteger63Arithmetic.compare(a, b) > 0) {
-                        divisionSingleTest(a, b)
-                    } else {
-                        divisionSingleTest(b, a)
+            jobList.add(
+                GlobalScope.launch {
+                    try {
+                        if (BigInteger63Arithmetic.compare(a, b) > 0) {
+                            divisionSingleTest(a, b)
+                        } else {
+                            divisionSingleTest(b, a)
+                        }
+                    } catch (e: Throwable) {
+                        println(
+                            "Failed on ulongArrayOf(${a.joinToString(separator = ",") { it.toString() + "U" }}), " +
+                                    "ulongArrayOf(${b.joinToString(separator = ",") { it.toString() + "U" }})"
+                        )
+                        e.printStackTrace()
                     }
-                } catch (e : Throwable) {
-                    println("Failed on ulongArrayOf(${a.joinToString(separator = ",") { it.toString() + "U" }}), " +
-                            "ulongArrayOf(${b.joinToString(separator = ",") { it.toString() + "U" }})")
-                    e.printStackTrace()
                 }
-            }
+            )
 
         }
 
     }
 
 
-
     @Test
     fun preciseDebugTest() {
-        divisionSingleTest(ulongArrayOf(7011262718134162982U,165064388400841479U,8071396034697521068U,3707335022938319120U), ulongArrayOf(189041424779232614U,1430782222387740366U))
+        divisionSingleTest(
+            ulongArrayOf(
+                7011262718134162982U,
+                165064388400841479U,
+                8071396034697521068U,
+                3707335022938319120U
+            ), ulongArrayOf(189041424779232614U, 1430782222387740366U)
+        )
 //        divisionSingleTest(ulongArrayOf(3449361588UL,1278830002UL,3123489057UL,3720277819UL, 1UL, 1UL, 1UL, 1UL), ulongArrayOf(1UL, 1UL))
 
     }
 
-    fun divisionSingleTest(dividend : ULongArray, divisor : ULongArray) {
-        assertTrue("Failed on ulongArrayOf(${dividend.joinToString(separator = ",") { it.toString() + "U" }}), " +
-                "ulongArrayOf(${divisor.joinToString(separator = ",") { it.toString() + "U" }})") {
+    fun divisionSingleTest(dividend: ULongArray, divisor: ULongArray) {
+        assertTrue(
+            "Failed on ulongArrayOf(${dividend.joinToString(separator = ",") { it.toString() + "U" }}), " +
+                    "ulongArrayOf(${divisor.joinToString(separator = ",") { it.toString() + "U" }})"
+        ) {
             val a = dividend
             val b = divisor
             try {
@@ -163,17 +185,284 @@ class BigInteger63JavaDivisionTest {
                 val bigIntRemainder = a.toJavaBigInteger() % b.toJavaBigInteger()
 
                 bi64quotient == bigIntQuotient && bi64remainder == bigIntRemainder
-            } catch (e : Throwable) {
+            } catch (e: Throwable) {
                 e.printStackTrace()
                 false
             }
 
 
+        }
+    }
+
+    @Test
+    fun testReciprocal() {
+        val seed = 1
+        val random = Random(seed)
+
+        val jobList: MutableList<Job> = mutableListOf()
+        for (i in 1..Int.MAX_VALUE step 3001) {
+
+            val a = ulongArrayOf(
+                random.nextULong() shr 1,
+                random.nextULong() shr 1,
+                random.nextULong() shr 1,
+                random.nextULong() shr 1
+            )
+            val job = GlobalScope.launch {
+                reciprocalSingleTest(a)
+            }
+            jobList.add(job)
+
+        }
+        runBlocking {
+            jobList.forEach { it.join() }
+        }
+    }
+
+    @Test
+    fun testReciprocalPrecise() {
+//        val a = ulongArrayOf(1288756325682545368UL, 8091178732961339830UL, 8060639783838683711UL, 8865155242765229713UL)
+//        val a = ulongArrayOf(1044716880932840986UL, 4262802357929821493UL, 8033697874689306672UL, 1362612340666419151UL)
+//        val a = ulongArrayOf(12997UL)
+        val a = ulongArrayOf(6486747088144942085UL, 1710444079094491755UL)
+        reciprocalSingleTest(a)
+    }
+
+    fun reciprocalSingleTest(operand: ULongArray) {
+        assertTrue("Failed on ulongArrayOf(${operand.joinToString(separator = ", ") { it.toString() + "UL" }})") {
+            val a = operand
+            val shift = if (a.size == 1) {
+                1
+            } else {
+                a.size - 1
+            }
+            val recWithRem = try {
+                BigInteger63Arithmetic.reciprocal(a)
+            } catch (exception: Exception) {
+                exception.printStackTrace()
+                throw RuntimeException(
+                    "Failed on ulongArrayOf(${operand.joinToString(separator = ", ") { it.toString() + "UL" }}) + ${exception.message}"
+                )
+            }
+            val aRec = recWithRem.first
+
+            val aRecPlusOne = BigInteger63Arithmetic.add(aRec, BigInteger63Arithmetic.ONE)
+            val rawResult = BigInteger63Arithmetic.multiply(a, aRec)
+            val rawResultWithRecPlusOne = BigInteger63Arithmetic.multiply(a, aRecPlusOne)
+            val result =
+                BigInteger63Arithmetic.shiftRight(rawResult, shift * 2 * 63)
+            val resultWithRecPlusOne = BigInteger63Arithmetic.shiftRight(rawResultWithRecPlusOne, shift * 2 * 63)
+            result.contentEquals(BigInteger63Arithmetic.ZERO) && resultWithRecPlusOne.contentEquals(
+                BigInteger63Arithmetic.ONE
+            )
+
+
+        }
+    }
+
+
+    @Test
+    fun `Test four words divided by two words using reciprocal division`() {
+        val seed = 1
+        val random = Random(seed)
+        val jobList: MutableList<Job> = mutableListOf()
+        for (i in 1..Int.MAX_VALUE step 3001) {
+
+            val a = ulongArrayOf(
+                random.nextULong() shr 1,
+                random.nextULong() shr 1,
+                random.nextULong() shr 1,
+                random.nextULong() shr 1
+            )
+            val b = ulongArrayOf(random.nextULong() shr 1, random.nextULong() shr 1)
+            val job = GlobalScope.launch {
+                reciprocalDivisionSingleTest(a, b)
+            }
+            jobList.add(job)
+
+        }
+        runBlocking {
+            jobList.forEach { it.join() }
+        }
+
+    }
+
+    @Test
+    fun `Test random number of word divided using reciprocal division`() {
+        val seed = 1
+        val random = Random(seed)
+        val jobList: MutableList<Job> = mutableListOf()
+        for (i in 1..100) {
+
+            val length = random.nextInt(2, 5000)
+            val a = ULongArray(length) {
+                random.nextULong() shr 1
+            }
+            val divisorLength = random.nextInt(1, length)
+            val b = ULongArray(divisorLength) {
+                random.nextULong() shr 1
+            }
+            val job = GlobalScope.launch {
+                try {
+                    reciprocalDivisionSingleTest(a, b)
+                } catch (exception: Exception) {
+                    println("Failed on $length $divisorLength")
+                }
+            }
+            jobList.add(job)
+
+        }
+        runBlocking {
+            jobList.forEach { it.join() }
+        }
+
+    }
+
 
+    @Test
+    fun testReciprocalDivision() {
+//        val a = ulongArrayOf(0UL, 0UL, 0UL, 0UL, 4UL)
+//        val b = ulongArrayOf(0UL, 0UL, 0UL, 2UL)
+//        val a = ulongArrayOf(0UL, 0UL, 0UL, 4UL, 0UL, 4UL)
+//        val b = ulongArrayOf(0UL, 0UL, 2UL, 0UL, 2UL)
+//        val a = ulongArrayOf(0UL, 0UL, 0UL, 4UL, 0UL, 4UL)
+//        val b = ulongArrayOf(2UL, 1UL, 2UL)
+//        val a = ulongArrayOf(35526194523336114UL, 5792101143026746304UL, 5736945918018393883UL, 8794898263700565859UL)
+//        val b = ulongArrayOf(6486747088144942085UL, 1710444079094491755UL)
+        val seed = 1
+        val random = Random(1916)
+        val a = ULongArray(1374) {
+            random.nextULong() shr 1
+        }
+        val b = ULongArray(871) {
+            random.nextULong() shr 1
+        }
 
 
 
+        reciprocalDivisionSingleTest(a, b)
+    }
+
+    private fun reciprocalDivisionSingleTest(first: ULongArray, second: ULongArray) {
+        assertTrue(
+            "Failed on \nval a = ulongArrayOf(${first.joinToString(separator = ", ") { it.toString() + "UL" }})\n" +
+                    "val b = ulongArrayOf(${second.joinToString(separator = ", ") { it.toString() + "UL" }})"
+        ) {
+            val result = BigInteger63Arithmetic.reciprocalDivision(first, second)
+            val normalResult = BigInteger63Arithmetic.divide(first, second)
+            result.first.contentEquals(normalResult.first) && result.second.contentEquals(normalResult.second)
         }
     }
 
-}
\ No newline at end of file
+}
+
+@ExperimentalUnsignedTypes
+class DivisionBenchmark {
+
+    data class BenchmarkSample(
+        val dividend: ULongArray,
+        val divisor: ULongArray,
+        val expectedQuotient: ULongArray,
+        val expectedRemainder: ULongArray
+    )
+    @Suppress("UnusedEquals")
+    @Ignore("This should be run only when necessary")
+    @Test
+    fun runReciprocalVsBaseCaseBenchmark() {
+        runBlocking {
+            delay(10000)
+        }
+        val seed = 1
+        val random = Random(seed)
+        val sampleList = mutableListOf<BenchmarkSample>()
+
+        val jobList: MutableList<Job> = mutableListOf()
+        val generationStartTime = System.currentTimeMillis()
+        for (i in 0..1000 step 1) {
+            val job = GlobalScope.launch {
+                println("Doing $i")
+                val dividend = ULongArray(10) {
+                    random.nextULong() shr 1
+                }
+                val divisor = ULongArray(9) {
+                    random.nextULong() shr 1
+                }
+                val expectedQuotient = dividend.toJavaBigInteger() / divisor.toJavaBigInteger()
+                val expectedRemainder = dividend.toJavaBigInteger() % divisor.toJavaBigInteger()
+                sampleList.add(
+                    BenchmarkSample(
+                        dividend,
+                        divisor,
+                        BigInteger63Arithmetic.parseForBase(expectedQuotient.toString(10), 10),
+                        BigInteger63Arithmetic.parseForBase(expectedRemainder.toString(10), 10)
+                    )
+                )
+                println("Done $i")
+            }
+            jobList.add(job)
+        }
+        runBlocking {
+            jobList.forEach { it.join() }
+        }
+        val generationEndTime = System.currentTimeMillis()
+        println("Done generating samples, took ${generationEndTime - generationStartTime} ms. Generated samples ${sampleList.size}")
+        runBaseCaseOnSampleList(sampleList)
+        runReciprocalOnSampleList(sampleList)
+        runBaseCaseOnSampleList(sampleList)
+        runReciprocalOnSampleList(sampleList)
+        runBaseCaseOnSampleList(sampleList)
+        runReciprocalOnSampleList(sampleList)
+        runBaseCaseOnSampleList(sampleList)
+        runReciprocalOnSampleList(sampleList)
+        runBaseCaseOnSampleList(sampleList)
+        runReciprocalOnSampleList(sampleList)
+        1 == 1
+
+
+    }
+
+    fun runReciprocalOnSampleList(sampleList: List<BenchmarkSample>) {
+        val reciprocalStartTime = System.currentTimeMillis()
+        sampleList.forEach {
+            divideUsingReciprocal(it.dividend, it.divisor, it.expectedQuotient, it.expectedRemainder)
+        }
+        val reciprocalEndTime = System.currentTimeMillis()
+        println("Done reciprocal divide in ${reciprocalEndTime - reciprocalStartTime}")
+    }
+
+    fun runBaseCaseOnSampleList(sampleList: List<BenchmarkSample>) {
+        val baseCaseStartTime = System.currentTimeMillis()
+        sampleList.forEach {
+            divideUsingBaseDivide(it.dividend, it.divisor, it.expectedQuotient, it.expectedRemainder)
+        }
+        val baseCaseEndTime = System.currentTimeMillis()
+        println("Done basecase divide in ${baseCaseEndTime - baseCaseStartTime}")
+    }
+
+
+    fun divideUsingReciprocal(
+        dividend: ULongArray,
+        divisor: ULongArray,
+        expectedQuotient: ULongArray,
+        expectedRemainder: ULongArray
+    ) {
+        val result = BigInteger63Arithmetic.reciprocalDivision(dividend, divisor)
+        assertTrue {
+            result.first.contentEquals(expectedQuotient) && result.second.contentEquals(expectedRemainder)
+        }
+    }
+
+    fun divideUsingBaseDivide(
+        dividend: ULongArray,
+        divisor: ULongArray,
+        expectedQuotient: ULongArray,
+        expectedRemainder: ULongArray
+    ) {
+        val result = BigInteger63Arithmetic.divide(dividend, divisor)
+        assertTrue {
+            result.first.contentEquals(expectedQuotient) && result.second.contentEquals(expectedRemainder)
+        }
+    }
+
+}
+
diff --git a/bignum/src/jvmTest/kotlin/com/ionspin/kotlin/bignum/modular/ModularBigIntegerDivisionTest.kt b/bignum/src/jvmTest/kotlin/com/ionspin/kotlin/bignum/modular/ModularBigIntegerDivisionTest.kt
new file mode 100644
index 0000000..bf77ea2
--- /dev/null
+++ b/bignum/src/jvmTest/kotlin/com/ionspin/kotlin/bignum/modular/ModularBigIntegerDivisionTest.kt
@@ -0,0 +1,84 @@
+/*
+ *    Copyright 2019 Ugljesa Jovanovic
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ *
+ */
+
+package com.ionspin.kotlin.bignum.modular
+
+import com.ionspin.kotlin.bignum.integer.BigInteger
+import com.ionspin.kotlin.bignum.integer.Sign
+import com.ionspin.kotlin.bignum.integer.base63.toJavaBigInteger
+import kotlinx.coroutines.GlobalScope
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.runBlocking
+import org.junit.Test
+import kotlin.random.Random
+import kotlin.random.nextULong
+import kotlin.test.assertTrue
+
+/**
+ * Created by Ugljesa Jovanovic
+ * ugljesa.jovanovic@ionspin.com
+ * on 22-Apr-2019
+ */
+@ExperimentalUnsignedTypes
+class ModularBigIntegerDivisionTest {
+    @Test
+    fun testRandomModularMultiplication() {
+        val seed = 1
+        val random = Random(seed)
+        val jobList: MutableList<Job> = mutableListOf()
+        for (i in 1..1000) {
+            val aLength = random.nextInt(2, 500)
+            val a = ULongArray(aLength) {
+                random.nextULong() shr 1
+            }
+            val b = ULongArray(random.nextInt(1, aLength)) {
+                random.nextULong() shr 1
+            }
+
+            val modulo = ULongArray(random.nextInt(1, 500)) {
+                random.nextULong() shr 1
+            }
+            val creator = ModularBigInteger.creatorForModulo(BigInteger(modulo, Sign.POSITIVE))
+
+            val job = GlobalScope.launch {
+                try {
+                    val aMod = creator.fromBigInteger(BigInteger(a, Sign.POSITIVE))
+                    val bMod = creator.fromBigInteger(BigInteger(b, Sign.POSITIVE))
+                    singleDivisionTest(aMod, bMod)
+                } catch (exception: Exception) {
+                    exception.printStackTrace()
+                }
+            }
+            jobList.add(job)
+
+        }
+        runBlocking {
+            jobList.forEach { it.join() }
+        }
+    }
+
+    fun singleDivisionTest(a : ModularBigInteger, b : ModularBigInteger) {
+        assertTrue {
+            val result = a divrem  b
+            val javaResultQuotient = (a.residue.toJavaBigInteger() / b.residue.toJavaBigInteger()).mod(a.modulo.toJavaBigInteger())
+            val javaResultRemainder = (a.residue.toJavaBigInteger() % b.residue.toJavaBigInteger()).mod(a.modulo.toJavaBigInteger())
+            result.quotient.residue.toJavaBigInteger() == javaResultQuotient &&
+                    result.remainder.residue.toJavaBigInteger() == javaResultRemainder
+        }
+    }
+}
\ No newline at end of file
diff --git a/bignum/src/jvmTest/kotlin/com/ionspin/kotlin/bignum/modular/ModularBigIntegerMultiplication.kt b/bignum/src/jvmTest/kotlin/com/ionspin/kotlin/bignum/modular/ModularBigIntegerMultiplication.kt
new file mode 100644
index 0000000..d543fd9
--- /dev/null
+++ b/bignum/src/jvmTest/kotlin/com/ionspin/kotlin/bignum/modular/ModularBigIntegerMultiplication.kt
@@ -0,0 +1,82 @@
+/*
+ *    Copyright 2019 Ugljesa Jovanovic
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ *
+ */
+
+package com.ionspin.kotlin.bignum.modular
+
+import com.ionspin.kotlin.bignum.integer.BigInteger
+import com.ionspin.kotlin.bignum.integer.Sign
+import com.ionspin.kotlin.bignum.integer.base63.toJavaBigInteger
+import kotlinx.coroutines.GlobalScope
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.runBlocking
+import kotlin.random.Random
+import kotlin.random.nextULong
+import kotlin.test.Test
+import kotlin.test.assertTrue
+
+/**
+ * Created by Ugljesa Jovanovic
+ * ugljesa.jovanovic@ionspin.com
+ * on 22-Apr-2019
+ */
+@ExperimentalUnsignedTypes
+class ModularBigIntegerMultiplication {
+
+    @Test
+    fun testRandomModularMultiplication() {
+        val seed = 1
+        var random = Random(seed)
+        val jobList: MutableList<Job> = mutableListOf()
+        for (i in 1..1000) {
+            val a = ULongArray(random.nextInt(1, 500)) {
+                random.nextULong() shr 1
+            }
+            val b = ULongArray(random.nextInt(1, 500)) {
+                random.nextULong() shr 1
+            }
+
+            val modulo = ULongArray(random.nextInt(1, 500)) {
+                random.nextULong() shr 1
+            }
+            val creator = ModularBigInteger.creatorForModulo(BigInteger(modulo, Sign.POSITIVE))
+
+            val job = GlobalScope.launch {
+                try {
+                    val aMod = creator.fromBigInteger(BigInteger(a, Sign.POSITIVE))
+                    val bMod = creator.fromBigInteger(BigInteger(b, Sign.POSITIVE))
+                    singleMultiplicationTest(aMod, bMod)
+                } catch (exception: Exception) {
+                    exception.printStackTrace()
+                }
+            }
+            jobList.add(job)
+
+        }
+        runBlocking {
+            jobList.forEach { it.join() }
+        }
+    }
+
+    fun singleMultiplicationTest(a : ModularBigInteger, b : ModularBigInteger) {
+        assertTrue {
+            val result = a * b
+            val javaResult = (a.residue.toJavaBigInteger() * b.residue.toJavaBigInteger()).mod(a.modulo.toJavaBigInteger())
+            result.residue.toJavaBigInteger() == javaResult
+        }
+    }
+}
\ No newline at end of file