在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
开源软件名称(OpenSource Name):ionspin/kotlin-multiplatform-bignum开源软件地址(OpenSource Url):https://github.com/ionspin/kotlin-multiplatform-bignum开源编程语言(OpenSource Language):Kotlin 99.7%开源软件介绍(OpenSource Introduction):Kotlin MP BigNum libraryKotlin Multiplatform BigNum library is a pure kotlin implementation of arbitrary precision arithmetic operations. It follows the same approach as Kotlin does on JVM to keep the interface familiar. Notes & RoadmapThis is an implementation of pure kotlin arbitrary integer and floating-point arithmetic support. The APIs might change until v1.0 Version 0.3.0 brings API changes to BigDecimal API see changelog for full list. Also, there is a plan to implement platform native versions. Testing to verify that the library works properly is mostly done against Java BigInteger and BigDecimal implementations. Should I use this in production?The library is still under development, but at the moment it is feature complete, further improvements will be optimizations and bug-fixing. IntegrationGradleimplementation("com.ionspin.kotlin:bignum:0.3.6") Snapshot buildsrepositories {
maven {
url = uri("https://oss.sonatype.org/content/repositories/snapshots")
}
}
implementation("com.ionspin.kotlin:bignum:0.3.7-SNAPSHOT")
SerializationSerializers for KotlinX Serializtion library are provided, see more here kotlinx serialization support Note that because kotlinx doesn't support linux ARM targets as well as MinGW x86, serialization support library doesn't either. Additionally, because of a bug when building serialization support library only JS IR variant is provided. UsageIntegersCreating Big IntegersTo create a big integer you can parse a string: BigInteger.parse("-1122334455667788990011223344556677889900", 10) Or use the extensions or companion function for val bigIntegerExtension = 234L.toBigInteger()
val bigIntegerCompanion = BigInteger.fromLong(234L)
Or use extensions functions for "12345678".toBigInteger() Basic Arithmetic OperationsAdditionval a = BigInteger.fromLong(Long.MAX_VALUE)
val b = BigInteger.fromInt(Integer.MAX_VALUE)
val sum = a + b
println("Sum: $sum")
----- Output -----
Sum: Sum: 9223372039002259454 Subtractionval a = BigInteger.fromLong(Long.MIN_VALUE)
val b = BigInteger.fromLong(Long.MAX_VALUE)
val difference = a - b
println("Difference: $difference")
----- Output -----
Difference: -18446744073709551615 Multiplicationval a = BigInteger.fromLong(Long.MAX_VALUE)
val b = BigInteger.fromLong(Long.MIN_VALUE)
val product = a * b
println("Product: $product")
----- Output -----
Product: -85070591730234615856620279821087277056 Division - Quotientval a = BigInteger.fromLong(Long.MAX_VALUE)
val b = BigInteger.fromInt(Int.MAX_VALUE)
val dividend = a + b
val divisor = BigInteger.fromLong(Long.MAX_VALUE)
val quotient = dividend / divisor
println("Quotient: $quotient")
----- Output -----
Quotient: 1 Division - Remainderval a = BigInteger.fromLong(Long.MAX_VALUE)
val b = BigInteger.fromInt(Int.MAX_VALUE)
val dividend = a + b
val divisor = BigInteger.fromLong(Long.MAX_VALUE)
val remainder = dividend % divisor
println("Remainder: $remainder")
----- Output -----
Remainder: 2147483647 Division - Quotient and Remainderval a = BigInteger.fromLong(Long.MAX_VALUE)
val b = BigInteger.fromInt(Int.MAX_VALUE)
val dividend = a + b
val divisor = BigInteger.fromLong(Long.MAX_VALUE)
val quotientAndRemainder = dividend divrem divisor
println("Quotient: ${quotientAndRemainder.quotient} \nRemainder: ${quotientAndRemainder.remainder}")
----- Output -----
Quotient: 1
Remainder: 2147483647 Bitwise OperationsShift Leftval a = BigInteger.fromByte(1)
val shifted = a shl 215
println("Shifted: $shifted")
----- Output -----
Shifted: 52656145834278593348959013841835216159447547700274555627155488768 Shift Rightval a = BigInteger.parseString("100000000000000000000000000000000", 10)
val shifted = a shr 90
----- Output -----
Shifted: 80779
Xorval operand = BigInteger.parseString("11110000", 2)
val mask = BigInteger.parseString("00111100", 2)
val xorResult = operand xor mask
println("Xor result: ${xorResult.toString(2)}")
----- Output -----
Xor result: 11001100 Andval operand = BigInteger.parseString("FFFFFFFFFF000000000000", 16)
val mask = BigInteger.parseString("00000000FFFF0000000000", 16)
val andResult = operand and mask
println("And result: ${andResult.toString(16)}")
----- Output -----
And result: ff000000000000 Orval operand = BigInteger.parseString("FFFFFFFFFF000000000000", 16)
val mask = BigInteger.parseString("00000000FFFF0000000000", 16)
val orResult = operand or mask
println("Or result: ${orResult.toString(16)}")
----- Output -----
Or result: ffffffffffff0000000000 Binary NotUnlike Java BigInteger which does two's complement inversion, this method does bitwise inversion, i.e.:
val operand = BigInteger.parseString("11110000", 2)
val result = operand.not()
println("Not operation result: ${result.toString(2)}")
----- Output -----
Inv result: 1111 Modular integersA Big integers can be converted to modularIntegers with same modulo, and then 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 More inforamtion about the ModularBigIntegers can be found in the third section Floating PointCreatingParsingTo create a BigDecimal you can parse a string in expanded or scientific notation Scientific val bigDecimal = BigDecimal.parseString("1.23E-6)")
println("BigDecimal: $bigDecimal")
----- Output -----
BigDecimal: 1.23E-6 Expanded val bigDecimal = BigDecimal.parseString("0.00000123")
println("BigDecimal: $bigDecimal")
----- Output -----
BigDecimal: 1.23E-6 From Long, Int, Short, ByteYou can convert standard types to BigDecimal, i.e. Long val bigDecimal = BigDecimal.fromLong(7111)
println("BigDecimal: $bigDecimal")
----- Output -----
BigDecimal: 7.111E+3 Or you can specify an exponent. when you do specify an exponent, input value (long, int, short, byte) is considered to be in scientific notation. val bigDecimal = BigDecimal.fromLongWithExponent(1, -5L)
println("BigDecimal: $bigDecimal")
println("BigDecimalExpanded: ${bigDecimal.toStringExpanded()}")
----- Output -----
BigDecimal: 1.0E-5
BigDecimalExpanded: 0.00001
Extension functionsFor val bigDecimal = "12345678.123".toBigInteger Or for val bigDecimalFromFloat = 123.456f.toBigDecimal()
val bigDecimalFromDouble = 123.456.toBigDecimal()
val bigDecimalFromLong = 10.toLong().toBigDecimal()
val bigDecimalFromInt = 10.toInt().toBigDecimal()
val bigDecimalFromShort = 10.toShort().toBigDecimal()
val bigDecimalFromByte = 10.toByte().toBigDecimal() toStringBy default toString() is returned in scientific output, but expanded output is also available val bigDecimal = BigDecimal.parseString("123.456")
println("BigDecimal: ${bigDecimal.toStringExpanded()}")
bigDecimal.toStringExpanded() == "123.456"
----- Output -----
BigDecimal: 123.456 toByteArray and fromByteArrayConverts the BigInteger to and from big endian byte array. val bigIntOriginal = BigInteger.fromULong(ULong.MAX_VALUE)
val byteArray = bigIntOriginal.toByteArray()
val reconstructed = BigInteger.fromByteArray(byteArray)
println("${bigIntOriginal == reconstructed}")
----- Output -----
true There are two helper methods when converting from two's complement array (the same form that Java BigInteger provides):
val negativeInput = ubyteArrayOf(0xFFU, 0x55U, 0x44U, 0x34U)
val negativeBigInt = BigInteger.fromTwosComplementByteArray(negativeInput.asByteArray())
val negativeBigInt = BigInteger.parseString("-AABBCC", 16)
val negativeBigIntArray = negativeBigInt.toTwosComplementByteArray()
Arithmetic operationsStandard arithmetic operations that are present:
(Suspiciously missing is square root, should be added soon™) Operations are executed with existing significands and then rounded down afterwards. Decimal mode parameter controls the precision and rounding mode DecimalModeThis is a counterpart to the Java BigDecimal MathContext and scale at the same time. Decimal mode API is under revision and will be improved during 0.3.0-0.4.0 library lifecycle data class DecimalMode(val decimalPrecision : Long = 0, val roundingMode : RoundingMode = RoundingMode.NONE, val scale: Long = -1)
Decimal mode resolution
ScaleScale, or the number of digits to the right of the decimal, can also be specified. Default is no
scale, which puts no restriction on number of digits to the right of the decimal. When scale is
specified, a
Infinite precisionPrecision 0 and roundingMode none attempt to provide infinite precisions. Exception is division (and exponentiation with negative parameter), where default precision is the sum of precisions of operands (or 6, if the sum is below 6). If result of the operation cannot fit inside precision and RoundingMode is NONE, Example from the tests: fun readmeDivisionTest() {
assertFailsWith(ArithmeticException::class) {
val a = 1.toBigDecimal()
val b = 3.toBigDecimal()
val result = a/b
}
assertTrue {
val a = 1.toBigDecimal()
val b = 3.toBigDecimal()
val result = a.div(b, DecimalMode(20, RoundingMode.ROUND_HALF_AWAY_FROM_ZERO))
result.toString() == "3.3333333333333333333E-1"
}
} Convenience rounding methods
|
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论