ImpreciseFraction
This commit is contained in:
parent
6cd04682d7
commit
dab5cd6a2b
@ -1,6 +1,5 @@
|
||||
package ru.dbotthepony.mc.otm.block.entity
|
||||
|
||||
import net.minecraft.MethodsReturnNonnullByDefault
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.network.chat.TranslatableComponent
|
||||
@ -16,7 +15,6 @@ import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||
import ru.dbotthepony.mc.otm.capability.MatteryMachineEnergyStorage
|
||||
import ru.dbotthepony.mc.otm.core.Fraction
|
||||
import ru.dbotthepony.mc.otm.menu.AndroidStationMenu
|
||||
import javax.annotation.ParametersAreNonnullByDefault
|
||||
|
||||
class BlockEntityAndroidStation(p_155229_: BlockPos, p_155230_: BlockState) :
|
||||
BlockEntityMatteryPowered(Registry.BlockEntities.ANDROID_STATION, p_155229_, p_155230_), MenuProvider {
|
||||
|
@ -1,16 +1,12 @@
|
||||
package ru.dbotthepony.mc.otm.block.entity.worker
|
||||
|
||||
import net.minecraft.MethodsReturnNonnullByDefault
|
||||
import javax.annotation.ParametersAreNonnullByDefault
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
import ru.dbotthepony.mc.otm.block.entity.BlockEntityMatteryPowered
|
||||
import net.minecraft.nbt.CompoundTag
|
||||
import net.minecraft.nbt.DoubleTag
|
||||
import net.minecraft.world.level.Level
|
||||
import net.minecraft.world.level.block.Block
|
||||
import net.minecraft.world.level.block.entity.BlockEntity
|
||||
import ru.dbotthepony.mc.otm.core.Fraction
|
||||
import ru.dbotthepony.mc.otm.ifHas
|
||||
import ru.dbotthepony.mc.otm.set
|
||||
|
@ -11,7 +11,6 @@ import ru.dbotthepony.mc.otm.set
|
||||
import ru.dbotthepony.mc.otm.storage.IStorageTuple
|
||||
import ru.dbotthepony.mc.otm.storage.ItemStackWrapper
|
||||
import ru.dbotthepony.mc.otm.storage.StorageObjectRegistry
|
||||
import ru.dbotthepony.mc.otm.storage.StorageObjectTuple
|
||||
import java.util.*
|
||||
|
||||
class ItemMatteryDrive : AbstractMatteryDrive<ItemStackWrapper>, IItemMatteryDrive {
|
||||
|
@ -10,7 +10,7 @@ import java.math.BigInteger
|
||||
import java.math.MathContext
|
||||
import java.math.RoundingMode
|
||||
|
||||
fun powScale(int: Int): BigInteger {
|
||||
private fun powScale(int: Int): BigInteger {
|
||||
if (int <= 0)
|
||||
return BigInteger.ONE
|
||||
|
||||
@ -22,7 +22,7 @@ fun powScale(int: Int): BigInteger {
|
||||
return result
|
||||
}
|
||||
|
||||
fun powUnscaled(unscaled: BigInteger, scale: Int): BigInteger {
|
||||
private fun powUnscaled(unscaled: BigInteger, scale: Int): BigInteger {
|
||||
if (scale >= 0)
|
||||
return unscaled
|
||||
|
||||
@ -37,7 +37,7 @@ fun powUnscaled(unscaled: BigInteger, scale: Int): BigInteger {
|
||||
val DEFAULT_MATH_CONTEXT = MathContext(64, RoundingMode.HALF_UP)
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
inline fun invertCompare(int: Int): Int {
|
||||
private inline fun invertCompare(int: Int): Int {
|
||||
if (int == 0)
|
||||
return 0
|
||||
|
||||
@ -206,7 +206,7 @@ private fun compactTwo(value1: BigInteger, value2: BigInteger, compact: Boolean
|
||||
return compactTwoMod(value1, value2, compact)
|
||||
}
|
||||
|
||||
fun unsignedInt(value: Byte): Int {
|
||||
private fun unsignedInt(value: Byte): Int {
|
||||
if (value < 0) {
|
||||
return 256 + value
|
||||
}
|
||||
|
322
src/main/kotlin/ru/dbotthepony/mc/otm/core/ImpreciseFraction.kt
Normal file
322
src/main/kotlin/ru/dbotthepony/mc/otm/core/ImpreciseFraction.kt
Normal file
@ -0,0 +1,322 @@
|
||||
package ru.dbotthepony.mc.otm.core
|
||||
|
||||
import net.minecraft.nbt.ByteArrayTag
|
||||
import net.minecraft.nbt.StringTag
|
||||
import net.minecraft.nbt.Tag
|
||||
import java.math.BigDecimal
|
||||
import java.math.BigInteger
|
||||
import java.math.MathContext
|
||||
import java.nio.ByteBuffer
|
||||
import kotlin.math.absoluteValue
|
||||
|
||||
private fun isZero(value: BigInteger) = value == BigInteger.ZERO
|
||||
|
||||
private val LONG_BUFF = ByteBuffer.allocate(8)
|
||||
|
||||
private fun longToBytes(value: Long): ByteArray {
|
||||
LONG_BUFF.position(0)
|
||||
LONG_BUFF.putLong(value)
|
||||
return LONG_BUFF.array().copyOf()
|
||||
}
|
||||
|
||||
private fun bytesToLong(value: ByteArray, from: Int = 0): Long {
|
||||
val arr = LONG_BUFF.array()
|
||||
arr[0] = value[from]
|
||||
arr[1] = value[from + 1]
|
||||
arr[2] = value[from + 2]
|
||||
arr[3] = value[from + 3]
|
||||
arr[4] = value[from + 4]
|
||||
arr[5] = value[from + 5]
|
||||
arr[6] = value[from + 6]
|
||||
arr[7] = value[from + 7]
|
||||
LONG_BUFF.position(0)
|
||||
return LONG_BUFF.long
|
||||
}
|
||||
|
||||
const val EPSILON = 0.0000001
|
||||
|
||||
private fun cmpDouble(a: Double, b: Double): Boolean {
|
||||
if (a == b)
|
||||
return true
|
||||
|
||||
return (a - b).absoluteValue <= EPSILON
|
||||
}
|
||||
|
||||
@Suppress("unused")
|
||||
class ImpreciseFraction @JvmOverloads constructor(whole: BigInteger, decimal: Double = 0.0) : Comparable<ImpreciseFraction> {
|
||||
@JvmOverloads constructor(whole: Byte, decimal: Double = 0.0) : this(BigInteger.valueOf(whole.toLong()), decimal)
|
||||
@JvmOverloads constructor(whole: Short, decimal: Double = 0.0) : this(BigInteger.valueOf(whole.toLong()), decimal)
|
||||
@JvmOverloads constructor(whole: Int, decimal: Double = 0.0) : this(BigInteger.valueOf(whole.toLong()), decimal)
|
||||
@JvmOverloads constructor(whole: Long, decimal: Double = 0.0) : this(BigInteger.valueOf(whole), decimal)
|
||||
constructor(value: BigDecimal) : this(value.toBigInteger(), value.remainder(BigDecimal.ONE).toDouble()) // TODO
|
||||
constructor(value: Float) : this(BigDecimal(value.toString()))
|
||||
constructor(value: Double) : this(BigDecimal(value.toString()))
|
||||
constructor(value: String) : this(BigDecimal(value))
|
||||
|
||||
val decimal: Double
|
||||
val whole: BigInteger
|
||||
|
||||
init {
|
||||
var decimal = decimal
|
||||
var whole = whole
|
||||
|
||||
if (decimal <= -1f || decimal >= 1f) {
|
||||
val frac = decimal % 1f
|
||||
whole += BigInteger.valueOf((decimal - frac).toLong())
|
||||
decimal = frac
|
||||
}
|
||||
|
||||
// дробная часть равна нулю
|
||||
if (decimal == -0.0 || decimal == 0.0) {
|
||||
if (!isZero(whole)) {
|
||||
this.decimal = 0.0
|
||||
this.whole = whole
|
||||
} else { // сохраняет минус ноль
|
||||
this.decimal = decimal
|
||||
this.whole = whole
|
||||
}
|
||||
// целая часть и дробная часть имеют одинаковые знаки
|
||||
} else if (decimal > 0.0 && whole.signum() >= 0 || decimal < 0.0 && whole.signum() <= 0) {
|
||||
this.decimal = decimal
|
||||
this.whole = whole
|
||||
} else {
|
||||
// целая часть и дробная часть имеют разные знаки
|
||||
|
||||
if (decimal > 0.0) {
|
||||
this.decimal = decimal - 1f
|
||||
this.whole = whole + BigInteger.ONE
|
||||
//} else if (double < 0.0 && whole.signum() > 0) {
|
||||
} else {
|
||||
this.decimal = decimal + 1f
|
||||
this.whole = whole - BigInteger.ONE
|
||||
}
|
||||
|
||||
//throw InternalError("This should never happen, but it happened. Input was: $whole $double")
|
||||
}
|
||||
}
|
||||
|
||||
fun isNaN() = decimal.isNaN()
|
||||
|
||||
operator fun plus(other: ImpreciseFraction) = ImpreciseFraction(whole + other.whole, decimal + other.decimal)
|
||||
operator fun minus(other: ImpreciseFraction) = ImpreciseFraction(whole - other.whole, decimal - other.decimal)
|
||||
|
||||
operator fun times(other: ImpreciseFraction): ImpreciseFraction {
|
||||
val a = whole
|
||||
val c = other.whole
|
||||
|
||||
val b = 1.0 / decimal
|
||||
val d = 1.0 / other.decimal
|
||||
|
||||
val bL = b.toLong()
|
||||
val dL = d.toLong()
|
||||
|
||||
val bc = c.divideAndRemainder(BigInteger.valueOf(bL))
|
||||
val ad = a.divideAndRemainder(BigInteger.valueOf(dL))
|
||||
|
||||
return ImpreciseFraction(
|
||||
a * c + bc[0] + ad[0],
|
||||
decimal * other.decimal + bc[1].toDouble() / b + ad[1].toDouble() / d
|
||||
)
|
||||
}
|
||||
|
||||
operator fun div(other: ImpreciseFraction): ImpreciseFraction {
|
||||
val a = toBigDecmial()
|
||||
val b = other.toBigDecmial()
|
||||
val div = a.divideAndRemainder(b, MathContext(a.precision() + b.precision()))
|
||||
|
||||
val bD = b.toDouble()
|
||||
|
||||
if (bD.isInfinite()) {
|
||||
return ImpreciseFraction(div[0].toBigInteger())
|
||||
}
|
||||
|
||||
return ImpreciseFraction(div[0].toBigInteger(), div[1].toDouble() / bD)
|
||||
}
|
||||
|
||||
operator fun unaryMinus(): ImpreciseFraction {
|
||||
return ImpreciseFraction(-whole, decimal)
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (isNaN())
|
||||
return false
|
||||
|
||||
if (other is ImpreciseFraction) {
|
||||
return other.whole == whole && cmpDouble(decimal, other.decimal)
|
||||
}
|
||||
|
||||
return super.equals(other)
|
||||
}
|
||||
|
||||
fun equalsStrict(other: Any?): Boolean {
|
||||
if (isNaN())
|
||||
return false
|
||||
|
||||
if (other is ImpreciseFraction) {
|
||||
return other.whole == whole && other.decimal == decimal
|
||||
}
|
||||
|
||||
return super.equals(other)
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
if (isNaN())
|
||||
return Double.NaN.hashCode()
|
||||
|
||||
return 31 * decimal.hashCode() + whole.hashCode()
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
if (isNaN())
|
||||
return "NaN"
|
||||
|
||||
return when (signum()) {
|
||||
1 -> "$whole.${decimal.toString().substring(2)}"
|
||||
0 -> "0.0"
|
||||
-1 -> "$whole.${decimal.toString().substring(3)}"
|
||||
else -> throw IllegalArgumentException("invalid signum")
|
||||
}
|
||||
}
|
||||
|
||||
fun toDouble(): Double {
|
||||
return java.lang.Double.parseDouble(toString())
|
||||
}
|
||||
|
||||
fun toBigDecmial(): BigDecimal {
|
||||
return BigDecimal(whole) + BigDecimal(decimal)
|
||||
}
|
||||
|
||||
fun signum(): Int {
|
||||
val sign = whole.signum()
|
||||
|
||||
if (sign != 0) {
|
||||
return sign
|
||||
}
|
||||
|
||||
return if (decimal > 0.0) 1 else if (decimal < 0.0) -1 else 0
|
||||
}
|
||||
|
||||
override fun compareTo(other: ImpreciseFraction): Int {
|
||||
if (isNaN())
|
||||
return 1
|
||||
else if (other.isNaN())
|
||||
return -1
|
||||
|
||||
val a = signum()
|
||||
val b = other.signum()
|
||||
|
||||
if (a < b)
|
||||
return -1
|
||||
else if (a > b)
|
||||
return 1
|
||||
|
||||
if (other.whole == whole) {
|
||||
if (cmpDouble(decimal, other.decimal)) {
|
||||
return 0
|
||||
}
|
||||
|
||||
return if (other.decimal < decimal) 1 else -1
|
||||
}
|
||||
|
||||
return whole.compareTo(other.whole)
|
||||
}
|
||||
|
||||
fun compareToStrict(other: ImpreciseFraction): Int {
|
||||
if (isNaN())
|
||||
return 1
|
||||
else if (other.isNaN())
|
||||
return -1
|
||||
|
||||
val a = signum()
|
||||
val b = other.signum()
|
||||
|
||||
if (a < b)
|
||||
return -1
|
||||
else if (a > b)
|
||||
return 1
|
||||
|
||||
if (other.whole == whole) {
|
||||
if (other.decimal == decimal) {
|
||||
return 0
|
||||
}
|
||||
|
||||
return if (other.decimal < decimal) 1 else -1
|
||||
}
|
||||
|
||||
return whole.compareTo(other.whole)
|
||||
}
|
||||
|
||||
fun toBytesArray(): ByteArray {
|
||||
val whole = whole.toByteArray()
|
||||
return byteArrayOf(whole.size.toByte(), *whole, *longToBytes(decimal.toBits()))
|
||||
}
|
||||
|
||||
fun serializeNBT(): Tag {
|
||||
return ByteArrayTag(toBytesArray())
|
||||
}
|
||||
|
||||
fun isZero() = cmpDouble(decimal, 0.0) && isZero(whole)
|
||||
|
||||
fun moreThanZero(): ImpreciseFraction {
|
||||
if (signum() >= 0)
|
||||
return this
|
||||
|
||||
return ZERO
|
||||
}
|
||||
|
||||
fun lessOrZero(): ImpreciseFraction {
|
||||
if (signum() <= 0)
|
||||
return this
|
||||
|
||||
return ZERO
|
||||
}
|
||||
|
||||
fun max(vararg others: ImpreciseFraction): ImpreciseFraction {
|
||||
var max = this
|
||||
|
||||
for (other in others) {
|
||||
if (max < other) {
|
||||
max = other
|
||||
}
|
||||
}
|
||||
|
||||
return max
|
||||
}
|
||||
|
||||
fun min(vararg others: ImpreciseFraction): ImpreciseFraction {
|
||||
var min = this
|
||||
|
||||
for (other in others) {
|
||||
if (min > other) {
|
||||
min = other
|
||||
}
|
||||
}
|
||||
|
||||
return min
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmField val MINUS_ZERO = ImpreciseFraction(0, -0.0)
|
||||
@JvmField val ZERO = ImpreciseFraction(BigInteger.ZERO)
|
||||
@JvmField val ONE = ImpreciseFraction(BigInteger.ONE)
|
||||
@JvmField val TWO = ImpreciseFraction(BigInteger.TWO)
|
||||
@JvmField val TEN = ImpreciseFraction(BigInteger.TEN)
|
||||
|
||||
fun fromBytesArray(input: ByteArray): ImpreciseFraction {
|
||||
val size = if (input[0] < 0) input[0].toInt() + 256 else input[0].toInt()
|
||||
val slice = input.copyOfRange(1, 1 + size)
|
||||
val bits = bytesToLong(input, 1 + size)
|
||||
return ImpreciseFraction(BigInteger(slice), Double.fromBits(bits))
|
||||
}
|
||||
|
||||
fun deserializeNBT(input: Tag?): ImpreciseFraction {
|
||||
if (input is ByteArrayTag) {
|
||||
return fromBytesArray(input.asByteArray)
|
||||
} else if (input is StringTag) {
|
||||
return ImpreciseFraction(input.asString)
|
||||
}
|
||||
|
||||
return ZERO
|
||||
}
|
||||
}
|
||||
}
|
@ -6,8 +6,6 @@ import ru.dbotthepony.mc.otm.capability.matter.IPatternStorage
|
||||
import ru.dbotthepony.mc.otm.core.Fraction
|
||||
import ru.dbotthepony.mc.otm.menu.MatteryMenu
|
||||
import ru.dbotthepony.mc.otm.menu.data.FractionDataContainer
|
||||
import ru.dbotthepony.mc.otm.menu.data.IntDataContainer
|
||||
import ru.dbotthepony.mc.otm.menu.data.ShortDataContainer
|
||||
|
||||
@Suppress("unused")
|
||||
class LevelGaugeWidget(menu: MatteryMenu) : AbstractWidget(menu) {
|
||||
|
@ -1,4 +0,0 @@
|
||||
package ru.dbotthepony.mc.otm.storage
|
||||
|
||||
import ru.dbotthepony.mc.otm.core.Fraction
|
||||
import java.util.*
|
@ -3,7 +3,6 @@ package ru.dbotthepony.mc.otm.storage
|
||||
import ru.dbotthepony.mc.otm.capability.IMatteryEnergyStorage
|
||||
import ru.dbotthepony.mc.otm.core.Fraction
|
||||
import java.util.*
|
||||
import java.util.function.Supplier
|
||||
|
||||
class RemoteTuple<T : IStorageStack>(val obj: T, val remote_id: UUID, val provider: IStorageView<T>, val local: LocalTuple<T>) {
|
||||
fun extract(amount: Fraction, simulate: Boolean): T {
|
||||
|
@ -4,10 +4,9 @@ import org.junit.jupiter.api.DisplayName
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.assertThrows
|
||||
import ru.dbotthepony.mc.otm.core.Fraction
|
||||
import java.lang.Math.floor
|
||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
||||
import java.math.BigDecimal
|
||||
import java.math.BigInteger
|
||||
import kotlin.random.Random
|
||||
|
||||
object FractionTests {
|
||||
@Test
|
||||
@ -138,6 +137,15 @@ object FractionTests {
|
||||
Fraction(1043, -648),
|
||||
)
|
||||
|
||||
private val samplesIM = arrayOf(
|
||||
ImpreciseFraction(9475.0 / 4729),
|
||||
ImpreciseFraction(23535.0 / 58723),
|
||||
ImpreciseFraction(-4852.0 / 6859),
|
||||
ImpreciseFraction(-45623.0 / -76849),
|
||||
ImpreciseFraction(38494.0 / -76849),
|
||||
ImpreciseFraction(1043.0 / -648),
|
||||
)
|
||||
|
||||
private val samples2 = arrayOf(
|
||||
(9475.0 / 4729),
|
||||
(23535.0 / 58723),
|
||||
@ -161,6 +169,7 @@ object FractionTests {
|
||||
fun performance() {
|
||||
val rand = java.util.Random()
|
||||
val blackHole = arrayOfNulls<Fraction>(100_000)
|
||||
val blackHoleIM = arrayOfNulls<ImpreciseFraction>(100_000)
|
||||
val size = samples.size
|
||||
var time = System.currentTimeMillis()
|
||||
|
||||
@ -175,6 +184,19 @@ object FractionTests {
|
||||
|
||||
println("Mean time for Fraction operation is ~${System.currentTimeMillis() - time} ms per 100,000 ops")
|
||||
|
||||
time = System.currentTimeMillis()
|
||||
|
||||
for (i in 0 until 100_000) {
|
||||
when (rand.nextInt(3)) {
|
||||
0 -> blackHoleIM[i] = samplesIM[rand.nextInt(size)] + samplesIM[rand.nextInt(size)]
|
||||
1 -> blackHoleIM[i] = samplesIM[rand.nextInt(size)] - samplesIM[rand.nextInt(size)]
|
||||
2 -> blackHoleIM[i] = samplesIM[rand.nextInt(size)] * samplesIM[rand.nextInt(size)]
|
||||
// 3 -> blackHole[i] = samples[rand.nextInt(size)] / samples[rand.nextInt(size)]
|
||||
}
|
||||
}
|
||||
|
||||
println("Mean time for ImpreciseFraction operation is ~${System.currentTimeMillis() - time} ms per 100,000 ops")
|
||||
|
||||
var sum = Fraction.ZERO
|
||||
|
||||
// перемешаем чтоб оптимизатор не отбросил
|
||||
@ -227,6 +249,14 @@ object FractionTests {
|
||||
blackHole3[i] = blackHole3[rand.nextInt(size)]
|
||||
}
|
||||
|
||||
var sum4 = 0.0
|
||||
|
||||
// перемешаем чтоб оптимизатор не отбросил
|
||||
for (i in 0 until size) {
|
||||
sum4 += blackHoleIM[i]!!.toDouble()
|
||||
blackHoleIM[i] = blackHoleIM[rand.nextInt(size)]
|
||||
}
|
||||
|
||||
println("$sum $sum2 $sum3")
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,43 @@
|
||||
package ru.dbotthepony.mc.otm.tests
|
||||
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
import org.junit.jupiter.api.Test
|
||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
||||
|
||||
object ImpreciseFractionTests {
|
||||
@Test
|
||||
@DisplayName("ImpreciseFraction comparison")
|
||||
fun comparison() {
|
||||
check(ImpreciseFraction(642, 0.43774) > ImpreciseFraction(641, 0.43774)) { "must be bigger" }
|
||||
check(ImpreciseFraction(642, 0.43774) > ImpreciseFraction(-641, 0.43774)) { "must be bigger" }
|
||||
check(ImpreciseFraction(0) == ImpreciseFraction(0)) { "integer notation" }
|
||||
check(ImpreciseFraction(0.1) > ImpreciseFraction(0)) { "must be bigger" }
|
||||
check(ImpreciseFraction(-0.1) < ImpreciseFraction(0)) { "must be lesser" }
|
||||
check(ImpreciseFraction(-1, -0.1) < ImpreciseFraction(-1)) { "must be lesser" }
|
||||
check(ImpreciseFraction(0.1) == ImpreciseFraction(0.1)) { "double notation" }
|
||||
check(ImpreciseFraction("0.1") == ImpreciseFraction("0.1")) { "string notation" }
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("ImpreciseFraction mathematical operations")
|
||||
fun math() {
|
||||
check((ImpreciseFraction(1) + ImpreciseFraction(2)) == ImpreciseFraction(3)) { "1 + 2 != 3" }
|
||||
check((ImpreciseFraction(0, 0.5) + ImpreciseFraction(0, 0.5)) == ImpreciseFraction(1)) { "0.5 + 0.5 != 1" }
|
||||
check((ImpreciseFraction(0, 0.5) + ImpreciseFraction(0, -0.5)) == ImpreciseFraction(0)) { "0.5 + -0.5 != 1" }
|
||||
check((ImpreciseFraction(0, 0.5) - ImpreciseFraction(0, -0.5)) == ImpreciseFraction(1)) { "0.5 - -0.5 != 1" }
|
||||
check((ImpreciseFraction(0, 0.3) - ImpreciseFraction(1, 0.2)) == ImpreciseFraction(0, -0.9)) { "0.3 - 1.2 != -0.9" }
|
||||
check((ImpreciseFraction(0, 0.3) * ImpreciseFraction(0, 0.3)) == ImpreciseFraction(0, 0.09)) { "0.3 * 0.3 != 0.9 ${ImpreciseFraction(0, 0.3) * ImpreciseFraction(0, 0.3)}" }
|
||||
check((ImpreciseFraction(2, 0.3) * ImpreciseFraction(2, 0.3)) == ImpreciseFraction(5, 0.29)) { "2.3 * 2.3 != 5.29 ${ImpreciseFraction(2, 0.3) * ImpreciseFraction(2, 0.3)}" }
|
||||
check((ImpreciseFraction(4) / ImpreciseFraction(2)) == ImpreciseFraction(2)) { "4 / 2 != 2" }
|
||||
check((ImpreciseFraction(6) / ImpreciseFraction(2)) == ImpreciseFraction(3)) { "6 / 2 != 2" }
|
||||
check((ImpreciseFraction(1) / ImpreciseFraction(0, 0.25)) == ImpreciseFraction(4)) { "1 / 0.25 != 4" }
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("ImpreciseFraction store/load")
|
||||
fun storeLoad() {
|
||||
val f = ImpreciseFraction(4, 0.28)
|
||||
val loaded = ImpreciseFraction.fromBytesArray(f.toBytesArray())
|
||||
check(f == loaded) { "$f != $loaded" }
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user