Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cleanup for v1.0.0 #41

Merged
merged 9 commits into from
Feb 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ The name will be in the format "exact-numbers-version", where the version is spe
This app has a dependency on the [kotlin-utils](https://github.com/lbressler13/kotlin-utils) package, which is published to the GitHub Packages registry.
In order to build the project, you will need a GitHub access token with at least the `read:packages` scope.

You can add the following properties to a gradle.properties file in order to build:
You can add the following properties to a local gradle properties file in order to build:
```properties
gpr.user=GITHUB_USERNAME
gpr.key=GITHUB_PAT
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,9 @@ sealed class ExactFraction : Comparable<ExactFraction>, Number() {
abstract fun isWholeNumber(): Boolean

/**
* Round ExactFraction to nearest whole number.
* Round to nearest whole number
*
* @param roundingMode [RoundingMode]: mode to use for rounding number. Optional, defaults to [RoundingMode.HALF_UP]
* @param roundingMode [RoundingMode]: mode to use for rounding number. Defaults to [RoundingMode.HALF_UP]
*/
abstract fun roundToWhole(roundingMode: RoundingMode = RoundingMode.HALF_UP): ExactFraction

Expand All @@ -90,8 +90,7 @@ sealed class ExactFraction : Comparable<ExactFraction>, Number() {
/**
* Create a string representation in standard decimal format
*
* @param digits [Int]: digits of precision in string. Defaults to 8.
* Will be ignored if this number results in a string in exponential format
* @param digits [Int]: maximum number of digits after decimal point. Defaults to 8
* @return [String]: representation in decimal format
*/
abstract fun toDecimalString(digits: Int = 8): String
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ package xyz.lbres.exactnumbers.exactfraction
* [ArithmeticException] for ExactFraction overflow.
* Has field for string representation of value that caused overflow
*/
class ExactFractionOverflowException private constructor(message: String?, overflowValue: String?, noArgs: Boolean) : ArithmeticException() {
class ExactFractionOverflowException private constructor(
message: String?,
overflowValue: String?,
noArgsConstructor: Boolean
) : ArithmeticException() {
override val message: String?
val overflowValue: String?

Expand All @@ -13,9 +17,9 @@ class ExactFractionOverflowException private constructor(message: String?, overf
this.overflowValue = overflowValue
}

constructor() : this(null, null, true)
constructor() : this(null, null, noArgsConstructor = true)

constructor(message: String) : this(message, null, false)
constructor(message: String) : this(message, null, noArgsConstructor = false)

constructor(message: String, overflowValue: String) : this(message, overflowValue, false)
constructor(message: String, overflowValue: String) : this(message, overflowValue, noArgsConstructor = false)
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,77 +14,77 @@ fun ExactFraction(numerator: BigInteger, denominator: BigInteger): ExactFraction
* @param numerator [Int]
* @param denominator [Int]
*/
fun ExactFraction(numerator: Int, denominator: Int): ExactFraction = ExactFractionImpl(numerator.toBigInteger(), denominator.toBigInteger())
fun ExactFraction(numerator: Int, denominator: Int): ExactFraction = ExactFraction(numerator.toBigInteger(), denominator.toBigInteger())

/**
* Construct an ExactFraction by specifying numerator and denominator
* @param numerator [Long]
* @param denominator [Long]
*/
fun ExactFraction(numerator: Long, denominator: Long): ExactFraction = ExactFractionImpl(numerator.toBigInteger(), denominator.toBigInteger())
fun ExactFraction(numerator: Long, denominator: Long): ExactFraction = ExactFraction(numerator.toBigInteger(), denominator.toBigInteger())

/**
* Construct an ExactFraction by specifying numerator and denominator
* @param numerator [Int]
* @param denominator [Long]
* @param numerator [Long]
* @param denominator [Int]
*/
fun ExactFraction(numerator: Long, denominator: Int): ExactFraction = ExactFractionImpl(numerator.toBigInteger(), denominator.toBigInteger())
fun ExactFraction(numerator: Long, denominator: Int): ExactFraction = ExactFraction(numerator.toBigInteger(), denominator.toBigInteger())

/**
* Construct an ExactFraction by specifying numerator and denominator
* @param numerator [Int]
* @param denominator [Long]
*/
fun ExactFraction(numerator: Int, denominator: Long): ExactFraction = ExactFractionImpl(numerator.toBigInteger(), denominator.toBigInteger())
fun ExactFraction(numerator: Int, denominator: Long): ExactFraction = ExactFraction(numerator.toBigInteger(), denominator.toBigInteger())

/**
* Construct an ExactFraction by specifying numerator and denominator
* @param numerator [BigInteger]
* @param denominator [Long]
* @param denominator [Int]
*/
fun ExactFraction(numerator: BigInteger, denominator: Int): ExactFraction = ExactFractionImpl(numerator, denominator.toBigInteger())
fun ExactFraction(numerator: BigInteger, denominator: Int): ExactFraction = ExactFraction(numerator, denominator.toBigInteger())

/**
* Construct an ExactFraction by specifying numerator and denominator
* @param numerator [Int]
* @param denominator [BigInteger]
*/
fun ExactFraction(numerator: Int, denominator: BigInteger): ExactFraction = ExactFractionImpl(numerator.toBigInteger(), denominator)
fun ExactFraction(numerator: Int, denominator: BigInteger): ExactFraction = ExactFraction(numerator.toBigInteger(), denominator)

/**
* Construct an ExactFraction by specifying numerator and denominator
* @param numerator [BigInteger]
* @param denominator [Long]
*/
fun ExactFraction(numerator: BigInteger, denominator: Long): ExactFraction = ExactFractionImpl(numerator, denominator.toBigInteger())
fun ExactFraction(numerator: BigInteger, denominator: Long): ExactFraction = ExactFraction(numerator, denominator.toBigInteger())

/**
* Construct an ExactFraction by specifying numerator and denominator
* @param numerator [Long]
* @param denominator [BigInteger]
*/
fun ExactFraction(numerator: Long, denominator: BigInteger): ExactFraction = ExactFractionImpl(numerator.toBigInteger(), denominator)
fun ExactFraction(numerator: Long, denominator: BigInteger): ExactFraction = ExactFraction(numerator.toBigInteger(), denominator)

/**
* Construct an ExactFraction by specifying numerator only
* @param numerator [BigInteger]
*/
fun ExactFraction(numerator: BigInteger): ExactFraction = ExactFractionImpl(numerator, BigInteger.ONE)
fun ExactFraction(numerator: BigInteger): ExactFraction = ExactFraction(numerator, BigInteger.ONE)

/**
* Construct an ExactFraction by specifying numerator only
* @param numerator [Int]
*/
fun ExactFraction(numerator: Int): ExactFraction = ExactFractionImpl(numerator.toBigInteger(), BigInteger.ONE)
fun ExactFraction(numerator: Int): ExactFraction = ExactFraction(numerator.toBigInteger())

/**
* Construct an ExactFraction by specifying numerator only
* @param numerator [Long]
*/
fun ExactFraction(numerator: Long): ExactFraction = ExactFractionImpl(numerator.toBigInteger(), BigInteger.ONE)
fun ExactFraction(numerator: Long): ExactFraction = ExactFraction(numerator.toBigInteger())

/**
* Construct ExactFraction by parsing a string
* Construct ExactFraction by parsing an EF-format or decimal string
* @param string [String]
*/
fun ExactFraction(string: String): ExactFraction = ExactFraction.parse(string)
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,7 @@ internal fun simplifyFraction(numerator: BigInteger, denominator: BigInteger): T
* Create a string representation of an [ExactFraction] in standard decimal format
*
* @param ef [ExactFraction]: number to convert to string
* @param digits [Int]: digits of precision in string. Must be non-negative.
* Will be ignored if this number results in a string in exponential format.
* @param digits [Int]: maximum number of digits after decimal point. Must be non-negative
* @return [String]: representation in decimal format
*/
internal fun createDecimalString(ef: ExactFraction, digits: Int): String {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package xyz.lbres.exactnumbers.exactfraction

import xyz.lbres.kotlinutils.general.simpleIf
import xyz.lbres.kotlinutils.general.succeeds
import xyz.lbres.kotlinutils.general.tryOrDefault
import xyz.lbres.kotlinutils.string.ext.isInt
import java.math.BigDecimal
import java.math.BigInteger

Expand Down Expand Up @@ -86,16 +86,6 @@ internal fun checkIsEFString(s: String): Boolean {
return false
}

return tryOrDefault(false) {
val numbers = trimmed.substring(efPrefix.length, s.length - efSuffix.length).split(' ')
val validNumber: (String) -> Boolean = {
when {
it.isEmpty() -> false
it.length == 1 -> it[0].isDigit()
else -> (it[0] == '-' || it[0].isDigit()) && it.substring(1).all(Char::isDigit)
}
}

numbers.size == 2 && validNumber(numbers[0]) && validNumber(numbers[1])
}
val numbers = trimmed.substring(efPrefix.length, s.length - efSuffix.length).split(' ')
return numbers.size == 2 && numbers[0].isInt() && numbers[1].isInt()
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,20 @@ class CastingOverflowException private constructor(
baseType: String,
targetType: String,
valueString: String,
overflowValue: Any?,
noArgs: Boolean
val overflowValue: Any?,
noArgsConstructor: Boolean
) : ArithmeticException() {
override val message: String?
val overflowValue: Any?

init {
if (noArgs) {
this.message = null
this.overflowValue = null
this.message = if (noArgsConstructor) {
null
} else {
this.message = "Overflow casting value $valueString of type $baseType to $targetType"
this.overflowValue = overflowValue
"Overflow casting value $valueString of type $baseType to $targetType"
}
}

constructor() : this("", "", "", null, true)
constructor() : this("", "", "", null, noArgsConstructor = true)

/**
* @param baseType [String]: name of type being cast from
Expand All @@ -32,5 +29,5 @@ class CastingOverflowException private constructor(
* @param overflowValue [Any]?: number that caused overflow. Optional, defaults to `null`
*/
constructor (baseType: String, targetType: String, valueString: String, overflowValue: Any? = null) :
this(baseType, targetType, valueString, overflowValue, false)
this(baseType, targetType, valueString, overflowValue, noArgsConstructor = false)
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import xyz.lbres.exactnumbers.utils.irrationalsPackage
import xyz.lbres.kotlinutils.collection.ext.toConstMultiSet
import xyz.lbres.kotlinutils.general.simpleIf
import xyz.lbres.kotlinutils.iterable.ext.countElement
import xyz.lbres.kotlinutils.list.listOfValue
import java.math.BigDecimal
import kotlin.math.abs

Expand Down Expand Up @@ -100,13 +101,13 @@ sealed class Term : Number() {
* @param coefficient [ExactFraction]
* @param logs [List]<Log>: list of log numbers
* @param roots [List]<Sqrt>: list of square root numbers
* @param piCount [Int]: how many occurrence of Pi to include in the list of numbers.
* A negative number corresponds to divided Pi values
* @param piCount [Int]: how many occurrences of pi to include in the list of numbers.
* A negative number corresponds to Pi values where inverted is `true`
* @return [Term] with the given values
*/
fun fromValues(coefficient: ExactFraction, logs: List<Log>, roots: List<Sqrt>, piCount: Int): Term {
val pis = List(abs(piCount)) { simpleIf(piCount < 0, { Pi().inverse() }, { Pi() }) }
return fromValues(coefficient, logs + roots + pis)
val pi = simpleIf(piCount < 0, Pi().inverse(), Pi())
return fromValues(coefficient, logs + roots + listOfValue(abs(piCount), pi))
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import xyz.lbres.kotlinutils.general.simpleIf
import xyz.lbres.kotlinutils.set.multiset.anyConsistent
import xyz.lbres.kotlinutils.set.multiset.const.ConstMultiSet
import xyz.lbres.kotlinutils.set.multiset.const.emptyConstMultiSet
import xyz.lbres.kotlinutils.set.multiset.mapToSetConsistent
import xyz.lbres.kotlinutils.set.multiset.mapToSet
import java.math.BigDecimal

// implementation of Term class
Expand Down Expand Up @@ -47,8 +47,8 @@ internal class TermImpl(coefficient: ExactFraction, factors: ConstMultiSet<Irrat

override fun times(other: Term): Term {
other as TermImpl
val newIrrationals = factorSet + other.factorSet
return TermImpl(coefficient * other.coefficient, newIrrationals.toConstMultiSet())
val newFactors = factorSet + other.factorSet
return TermImpl(coefficient * other.coefficient, newFactors.toConstMultiSet())
}

override fun div(other: Term): Term {
Expand All @@ -57,7 +57,7 @@ internal class TermImpl(coefficient: ExactFraction, factors: ConstMultiSet<Irrat
}

other as TermImpl
val newFactors = factorSet + other.factorSet.mapToSetConsistent { it.inverse() }
val newFactors = factorSet + other.factorSet.mapToSet { it.inverse() }
return TermImpl(coefficient / other.coefficient, newFactors.toConstMultiSet())
}

Expand Down Expand Up @@ -111,9 +111,8 @@ internal class TermImpl(coefficient: ExactFraction, factors: ConstMultiSet<Irrat
val fractionString = coefficient.toFractionString()
val coeffString = simpleIf(fractionString.contains("/"), "[$fractionString]", fractionString)
val factorString = factorSet.joinToString("x")
val result = simpleIf(factorString.isEmpty(), "<$coeffString>", "<${coeffString}x$factorString>")

string = result
string = simpleIf(factorString.isEmpty(), "<$coeffString>", "<${coeffString}x$factorString>")
}

return string!!
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ internal fun createSimplifiedTerm(coefficient: ExactFraction, factorGroups: Map<
/**
* Simplify a set of irrational numbers by extracting the rational values
*
* @param values [ConstMultiSet]<IrrationalNumber<*>>: list of values
* @param values [ConstMultiSet]<IrrationalNumber<*>>: list of values, which are assumed to have the same type
* @return [Pair]<ExactFraction, ConstMultiSet<IrrationalNumber<*>>: pair of values where first value is the product of the numbers
* with rational values, and the second is a set of the irrational values
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package xyz.lbres.exactnumbers.ext

import xyz.lbres.exactnumbers.utils.divideByZero
import xyz.lbres.kotlinutils.general.succeeds
import java.math.BigDecimal
import java.math.MathContext

Expand All @@ -22,3 +23,10 @@ internal fun BigDecimal.divideBy(other: BigDecimal): BigDecimal {
divide(other, mc)
}
}

/**
* Determine if decimal is a whole number
*
* @return `true` if number is a whole number, `false` otherwise
*/
internal fun BigDecimal.isWholeNumber(): Boolean = succeeds { toBigIntegerExact() }
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import java.math.BigDecimal
*/
abstract class IrrationalNumber<T : IrrationalNumber<T>> : Comparable<T>, Number() {
/**
* Type of number, should correspond to the type name for the class
* Type of number
*/
abstract val type: String

Expand All @@ -28,7 +28,7 @@ abstract class IrrationalNumber<T : IrrationalNumber<T>> : Comparable<T>, Number
*/
abstract val isInverted: Boolean
@Deprecated("Property $deprecatedV1", ReplaceWith("isInverted"), DeprecationLevel.WARNING)
val isDivided: Boolean
val isDivided: Boolean // maintained from Irrational interface
get() = isInverted

/**
Expand Down Expand Up @@ -57,7 +57,7 @@ abstract class IrrationalNumber<T : IrrationalNumber<T>> : Comparable<T>, Number
abstract fun inverse(): T

@Deprecated("Method $deprecatedV1", ReplaceWith("inverse"), DeprecationLevel.WARNING)
fun swapDivided(): T = inverse()
fun swapDivided(): T = inverse() // maintained from Irrational interface

operator fun times(other: IrrationalNumber<*>): Term = Term.fromValues(ExactFraction.ONE, listOf(this, other))
operator fun times(other: ExactFraction): Term = Term.fromValues(other, listOf(this))
Expand Down Expand Up @@ -89,7 +89,6 @@ abstract class IrrationalNumber<T : IrrationalNumber<T>> : Comparable<T>, Number
override fun toShort(): Short = castToShort(getValue(), this, type)
override fun toInt(): Int = castToInt(getValue(), this, type)
override fun toLong(): Long = castToLong(getValue(), this, type)

override fun toFloat(): Float = castToFloat(getValue(), this, type)
override fun toDouble(): Double = castToDouble(getValue(), this, type)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,7 @@ sealed class Log : IrrationalNumber<Log>() {
if (log != ONE) {
val diff = logValues.getCountOf(log) - logValues.getCountOf(log.inverse())
val valueToAdd = simpleIf(diff < 0, { log.inverse() }, { log })
val simplified: ConstMultiSet<Log> = ConstMultiSet(abs(diff)) { valueToAdd }
simplifiedValues.addAll(simplified)
repeat(abs(diff)) { simplifiedValues.add(valueToAdd) }
}
}

Expand Down
Loading
Loading