ImpreciseFraction. Dear... god. There's more. Noooo!
This commit is contained in:
parent
3313a3d011
commit
a859084b6f
@ -68,7 +68,7 @@ private fun bytesToLongBE(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const val EPSILON = 0.0000001
|
const val EPSILON = 0.0000000000001
|
||||||
|
|
||||||
private fun cmpDouble(a: Double, b: Double): Boolean {
|
private fun cmpDouble(a: Double, b: Double): Boolean {
|
||||||
if (a == b)
|
if (a == b)
|
||||||
@ -89,6 +89,12 @@ private val BI_DOUBLE_MIN = BigDecimal(Double.MIN_VALUE.toString()).toBigInteger
|
|||||||
|
|
||||||
private val PERCENTAGE_CONTEXT = MathContext(6)
|
private val PERCENTAGE_CONTEXT = MathContext(6)
|
||||||
|
|
||||||
|
private const val MEANINGFUL_BITS = 16
|
||||||
|
private const val MEANINGFUL_BITS_LONG = 1000000000000000000L
|
||||||
|
private const val MEANINGFUL_BITS_DOUBLE = MEANINGFUL_BITS_LONG.toDouble()
|
||||||
|
private val MEANINGFUL_BITS_CONTEXT = MathContext(MEANINGFUL_BITS)
|
||||||
|
private val MEANINGFUL_BITS_BI = BigInteger.valueOf(MEANINGFUL_BITS_LONG)
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
class ImpreciseFraction @JvmOverloads constructor(whole: BigInteger, decimal: Double = 0.0) : Comparable<ImpreciseFraction> {
|
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: Byte, decimal: Double = 0.0) : this(BigInteger.valueOf(whole.toLong()), decimal)
|
||||||
@ -151,22 +157,61 @@ class ImpreciseFraction @JvmOverloads constructor(whole: BigInteger, decimal: Do
|
|||||||
val a = whole
|
val a = whole
|
||||||
val c = other.whole
|
val c = other.whole
|
||||||
|
|
||||||
val b = 1.0 / decimal
|
val bZero = cmpDouble(decimal, 0.0)
|
||||||
val d = 1.0 / other.decimal
|
val dZero = cmpDouble(other.decimal, 0.0)
|
||||||
|
|
||||||
|
if (bZero && dZero) {
|
||||||
|
if (isZero(a) || isZero(c))
|
||||||
|
return this
|
||||||
|
|
||||||
|
return ImpreciseFraction(a * c)
|
||||||
|
} else if (bZero) {
|
||||||
|
val d = other.decimal * MEANINGFUL_BITS_DOUBLE
|
||||||
|
val dL = d.toLong()
|
||||||
|
val adInflated = a * BigInteger.valueOf(dL)
|
||||||
|
val ad = adInflated.divideAndRemainder(MEANINGFUL_BITS_BI)
|
||||||
|
|
||||||
|
return ImpreciseFraction(
|
||||||
|
a * c + ad[0],
|
||||||
|
ad[1].toDouble() / MEANINGFUL_BITS_DOUBLE
|
||||||
|
)
|
||||||
|
} else if (dZero) {
|
||||||
|
val b = decimal * MEANINGFUL_BITS_DOUBLE
|
||||||
|
val bL = b.toLong()
|
||||||
|
val bcInflated = c * BigInteger.valueOf(bL)
|
||||||
|
val bc = bcInflated.divideAndRemainder(MEANINGFUL_BITS_BI)
|
||||||
|
|
||||||
|
return ImpreciseFraction(
|
||||||
|
a * c + bc[0],
|
||||||
|
bc[1].toDouble() / b
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
val b = decimal * MEANINGFUL_BITS_DOUBLE
|
||||||
|
val d = other.decimal * MEANINGFUL_BITS_DOUBLE
|
||||||
|
|
||||||
val bL = b.toLong()
|
val bL = b.toLong()
|
||||||
val dL = d.toLong()
|
val dL = d.toLong()
|
||||||
|
|
||||||
val bc = c.divideAndRemainder(BigInteger.valueOf(bL))
|
val bcInflated = c * BigInteger.valueOf(bL)
|
||||||
val ad = a.divideAndRemainder(BigInteger.valueOf(dL))
|
val adInflated = a * BigInteger.valueOf(dL)
|
||||||
|
|
||||||
|
val bc = bcInflated.divideAndRemainder(MEANINGFUL_BITS_BI)
|
||||||
|
val ad = adInflated.divideAndRemainder(MEANINGFUL_BITS_BI)
|
||||||
|
|
||||||
return ImpreciseFraction(
|
return ImpreciseFraction(
|
||||||
a * c + bc[0] + ad[0],
|
a * c + bc[0] + ad[0],
|
||||||
decimal * other.decimal + bc[1].toDouble() / b + ad[1].toDouble() / d
|
decimal * other.decimal + bc[1].toDouble() / MEANINGFUL_BITS_DOUBLE + ad[1].toDouble() / MEANINGFUL_BITS_DOUBLE
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
operator fun div(other: ImpreciseFraction): ImpreciseFraction {
|
operator fun div(other: ImpreciseFraction): ImpreciseFraction {
|
||||||
|
if (isZero && other.isZero)
|
||||||
|
return this
|
||||||
|
|
||||||
|
if (isZero(whole) && isZero(other.whole))
|
||||||
|
return ImpreciseFraction(BigInteger.ZERO, decimal / other.decimal)
|
||||||
|
|
||||||
val a = toBigDecmial()
|
val a = toBigDecmial()
|
||||||
val b = other.toBigDecmial()
|
val b = other.toBigDecmial()
|
||||||
val div = a.divideAndRemainder(b, MathContext(a.precision() + b.precision()))
|
val div = a.divideAndRemainder(b, MathContext(a.precision() + b.precision()))
|
||||||
@ -240,7 +285,7 @@ class ImpreciseFraction @JvmOverloads constructor(whole: BigInteger, decimal: Do
|
|||||||
if (decimals == 0) {
|
if (decimals == 0) {
|
||||||
return whole.toString()
|
return whole.toString()
|
||||||
} else if (decimals > 0) {
|
} else if (decimals > 0) {
|
||||||
val strDecimal = if (decimal == 0.0 || decimal == -0.0) {
|
val strDecimal = if (decimal == 0.0 || decimal == -0.0 || decimal > 0.0 && decimal < 1E-11 || decimal < 0.0 && decimal > -1E-11) {
|
||||||
"0"
|
"0"
|
||||||
} else if (decimal > 0.0) {
|
} else if (decimal > 0.0) {
|
||||||
decimal.toString().substring(2)
|
decimal.toString().substring(2)
|
||||||
|
Loading…
Reference in New Issue
Block a user