Skip to content
This repository has been archived by the owner on Jul 5, 2022. It is now read-only.

Commit

Permalink
More work
Browse files Browse the repository at this point in the history
  • Loading branch information
soywiz committed Feb 9, 2019
1 parent 262c9ef commit d7fb604
Show file tree
Hide file tree
Showing 8 changed files with 69 additions and 18 deletions.
@@ -1,4 +1,4 @@
package com.soywiz
package com.soywiz.kbignum

// Big Integer
val Long.bi get() = BigInt(this)
Expand Down
@@ -1,4 +1,4 @@
package com.soywiz
package com.soywiz.kbignum

import kotlin.math.*

Expand Down Expand Up @@ -46,7 +46,12 @@ class BigInt private constructor(val data: UInt16ArrayZeroPad, val signum: Int,
private fun create(value: Int): BigInt {
val magnitude = value.toLong().absoluteValue
if (value == 0) return BigInt(uint16ArrayZeroPadOf(), 0, true)
return BigInt(uint16ArrayZeroPadOf((magnitude ushr 0).toInt(), (magnitude ushr 16).toInt()), value.sign)
return BigInt(
uint16ArrayZeroPadOf(
(magnitude ushr 0).toInt(),
(magnitude ushr 16).toInt()
), value.sign
)
}

operator fun invoke(value: Int): BigInt {
Expand Down Expand Up @@ -147,7 +152,10 @@ class BigInt private constructor(val data: UInt16ArrayZeroPad, val signum: Int,
(this shl other.trailingZeros()).data,
if (this.signum == other.signum) +1 else -1
)
else -> BigInt(UnsignedBigInt.mul(this.data, other.data), if (this.signum == other.signum) +1 else -1)
else -> BigInt(
UnsignedBigInt.mul(this.data, other.data),
if (this.signum == other.signum) +1 else -1
)
}
}

Expand All @@ -160,7 +168,10 @@ class BigInt private constructor(val data: UInt16ArrayZeroPad, val signum: Int,

fun divRem(other: BigInt): DivRem {
return when {
this.isZero -> DivRem(ZERO, ZERO)
this.isZero -> DivRem(
ZERO,
ZERO
)
other.isZero -> error("Division by zero")
this.isNegative && other.isNegative -> this.absoluteValue.divRem(other.absoluteValue).let {
DivRem(
Expand All @@ -180,9 +191,18 @@ class BigInt private constructor(val data: UInt16ArrayZeroPad, val signum: Int,
it.rem
)
}
other == ONE -> DivRem(this, ZERO)
other == TWO -> DivRem(this shr 1, BigInt(this.getBitInt(0)))
other <= SMALL -> UnsignedBigInt.divRemSmall(this.data, other.toInt()).let {
other == ONE -> DivRem(
this,
ZERO
)
other == TWO -> DivRem(
this shr 1,
BigInt(this.getBitInt(0))
)
other <= SMALL -> UnsignedBigInt.divRemSmall(
this.data,
other.toInt()
).let {
DivRem(
BigInt(it.div, signum),
BigInt(it.rem)
Expand All @@ -198,7 +218,10 @@ class BigInt private constructor(val data: UInt16ArrayZeroPad, val signum: Int,

// Simple euclidean division
private fun divRemBig(other: BigInt): DivRem {
if (this.isZero) return DivRem(ZERO, ZERO)
if (this.isZero) return DivRem(
ZERO,
ZERO
)
if (other.isZero) error("division by zero")
if (this.isNegative || other.isNegative) error("Non positive numbers")
val lbits = this.significantBits
Expand Down Expand Up @@ -273,7 +296,10 @@ class BigInt private constructor(val data: UInt16ArrayZeroPad, val signum: Int,
(other is BigInt) && this.signum == other.signum && this.data.contentEquals(other.data)

val absoluteValue get() = abs()
fun abs() = if (this.isZero) ZERO else if (this.isPositive) this else BigInt(this.data, 1)
fun abs() = if (this.isZero) ZERO else if (this.isPositive) this else BigInt(
this.data,
1
)
operator fun unaryPlus(): BigInt = this
operator fun unaryMinus(): BigInt = BigInt(this.data, -signum, false)

Expand All @@ -289,9 +315,16 @@ class BigInt private constructor(val data: UInt16ArrayZeroPad, val signum: Int,
infix fun xor(other: BigInt): BigInt = bitwise(other, Int::xor)

private inline fun bitwise(other: BigInt, op: (a: Int, b: Int) -> Int): BigInt {
return BigInt(UInt16ArrayZeroPad(max(this.data.size, other.data.size)).also {
for (n in 0 until it.size) it[n] = op(this.data[n], other.data[n])
}, 1)
return BigInt(
UInt16ArrayZeroPad(
max(
this.data.size,
other.data.size
)
).also {
for (n in 0 until it.size) it[n] = op(this.data[n], other.data[n])
}, 1
)
}

override fun toString() = toString(10)
Expand Down Expand Up @@ -348,7 +381,8 @@ class UInt16ArrayZeroPad private constructor(val data: IntArray) {
}

fun contentEquals(other: UInt16ArrayZeroPad) = this.data.contentEquals(other.data)
fun copyOf(size: Int): UInt16ArrayZeroPad = UInt16ArrayZeroPad(data.copyOf(size))
fun copyOf(size: Int): UInt16ArrayZeroPad =
UInt16ArrayZeroPad(data.copyOf(size))
}

fun uint16ArrayZeroPadOf(vararg values: Int) =
Expand Down
@@ -1,4 +1,4 @@
package com.soywiz
package com.soywiz.kbignum

import kotlin.math.*

Expand Down Expand Up @@ -38,7 +38,8 @@ class BigNum(val int: BigInt, val scale: Int) {

operator fun plus(other: BigNum): BigNum = binary(other, BigInt::plus)
operator fun minus(other: BigNum): BigNum = binary(other, BigInt::minus)
operator fun times(other: BigNum): BigNum = BigNum(this.int * other.int, this.scale + other.scale)
operator fun times(other: BigNum): BigNum =
BigNum(this.int * other.int, this.scale + other.scale)
operator fun div(other: BigNum): BigNum = div(other, this.scale)

fun div(other: BigNum, precision: Int): BigNum {
Expand Down
7 changes: 7 additions & 0 deletions kbignum/src/commonMain/kotlin/com/soywiz/kbignum/KBigNum.kt
@@ -0,0 +1,7 @@
package com.soywiz.kbignum

import com.soywiz.kbignum.internal.KBIGNUM_VERSION

object KBigNum {
val VERSION = KBIGNUM_VERSION
}
@@ -1,5 +1,6 @@
package com.soywiz

import com.soywiz.kbignum.bi
import kotlin.test.*

class BigIntTest {
Expand Down
@@ -1,5 +1,8 @@
package com.soywiz

import com.soywiz.kbignum.BigNum
import com.soywiz.kbignum.bi
import com.soywiz.kbignum.bn
import kotlin.test.*

class BigNumTest {
Expand Down
@@ -1,4 +1,5 @@
import com.soywiz.*
package com.soywiz.kbignum

import java.math.*
import kotlin.test.*

Expand Down
6 changes: 5 additions & 1 deletion settings.gradle
Expand Up @@ -2,7 +2,11 @@ rootProject.name = rootDir.name + "-root"

for (file in rootDir.listFiles()) {
if (file.name == "build" || file.name == "buildSrc" || file.name.startsWith(".")) continue
if (["build.gradle", "build.gradle.kts"].collect { new File(file, it) }.any { it.exists() }) {
if (
["build.gradle", "build.gradle.kts"].collect { new File(file, it) }.any { it.exists() } &&
["settings.gradle", "settings.gradle.kts"].collect { new File(file, it) }.every { !it.exists() }
) {
include(":${file.name}")
}
}

0 comments on commit d7fb604

Please sign in to comment.