Swift-BigInt 2.3.0

Swift-BigInt 2.3.0

Marcel Kröker 维护。



  • mkrd

Swift-BigInt

Swift-BigInt 是一个轻量级且易于使用的Swift 5任意精度算术库。

它支持整数字(BInt)和分数(BDouble),并包含大部分常见的数学运算符。还实现了优化的数学函数,如阶乘或最大公约数,可以通过 BIntMath 访问。更多详情请继续阅读。

一些基准测试在 Benchmarks.swift 中,请注意,它在发布模式下比 Xcode 的调试模式快10倍以上。

问卷调查时间!

问卷调查链接

我们想听听您对 Swift BigInt 的意见!如果您有时间,请帮助我们回答一些关于您如何使用此项目的问题,并告诉我们您的看法。此调查完全匿名,将用于评估哪些功能会在未来优先考虑。

安装

拖放

本库的主要目标是轻量级且独立。

只需将Swift-Big-Number-Core.swiftsources文件夹拖放到您的项目中即可!

是的,就这么简单:)

Swift包管理器

您可以使用Swift包管理器,并指定包依赖关系,通过在您的Package.swift文件中添加以下内容:

.package(url: "https://github.com/mkrd/Swift-BigInt.git", from: "2.0.0")
import BigNumber

CocoaPods

将以下内容放入您的Podfile中:

pod 'Swift-BigInt', '~> 2.0'
import BigNumber

兼容性

建议使用Xcode 9+和Swift 4+。已报告较旧版本存在问题,因此如果您无法更新,可能需要使用本库的旧版。

入门

以下是一个示例,用来展示本库的一些功能。如果您想了解更多,请继续阅读下面的“用法”部分。

let a = BInt(12)
let b = BInt("-10000000000000000000000000000000000000000000000000000000000000000")!

print(b)
>>> -10000000000000000000000000000000000000000000000000000000000000000

print(-a * b)
>>> 120000000000000000000000000000000000000000000000000000000000000000

print(BInt(200).factorial())
>>> 788657867364790503552363213932185062295135977687173263294742533244359449963403342920304284011984623904177212138919638830257642790242637105061926624952829931113462857270763317237396988943922445621451664240254033291864131227428294853277524242407573903240321257405579568660226031904170324062351700858796178922222789623703897374720000000000000000000000000000000000000000000000000

用法

BInt

初始化

您可以用 IntUIntString 初始化 BInt。如果您使用 String,初始化后的 BInt 将会是一个可选类型,如果 String 不包含有效数字,则它将为空。

BInt(Int)
BInt(UInt)
BInt(String)?
BInt(String, radix: Int)?

示例

let a = BInt(12)
print(a)
>>> 12


let b = BInt("-234324176583764598326758236587632649181349105368042856028465298620328782652623")
print(b!)
>>> -234324176583764598326758236587632649181349105368042856028465298620328782652623


let invalid = BInt("I'm not a number")
if let c = invalid {
  print(c)
} else {
  print("Not a valid number!")
}
>>> Not a valid number!


let d = BInt("fff", radix: 16)
print(d)
>>> 4095

BInt 提供以下结构方法

let big = BInt("-143141341")!

big.description // Returns "-143141341"
=> print(big) // prints "-143141341"

big.toInt() // returns -143141341 (only works when Int.min <= big <= Int.max)

big.isPositive() // Returns false
big.isNegative() // Returns true
big.isZero() // Returns false

big.negate() // Returns noting, but negates the BInt (mutating func)

big.rawData() // Returns internal structure

以下运算符与 BInt 一起使用

// Operating on Int and BInt result in a typecast to BInt

// Addition
BIntOrInt  +  BIntOrInt // Returns BInt
BIntOrInt  += BIntOrInt

//Subtraction
BIntOrInt -  BIntOrInt // Returns BInt
BIntOrInt -= BIntOrInt

// Multiplication
BIntOrInt *  BIntOrInt // Returns BInt
BIntOrInt *= BIntOrInt

// Exponentiation
BInt ** Int       // Retuns BInt to the power of Int

// Modulo
BIntOrInt  %  BIntOrInt // Returns BInt
BInt       %= BInt

// Division
BInt /  BInt // Returns BInt
BInt /= BInt


// Comparing
BInt == BInt
BInt != BInt
BInt <  BInt
BInt <= BInt
BInt >  BInt
BInt >= BInt

实现了 BInt 数学函数

fact(Int) // Returns factorial as BInt

gcd(BInt, BInt) // Returns greatest common divisor as BInt

lcm(BInt, BInt) // Returns lowest common multiple as BInt

permutations(BInt, BInt) // Returns BInt

combinations(BInt, BInt) // Returns BInt

BDouble

BDouble 允许以下构造函数

BDouble(Int)
BDouble(Double)
BDouble(String)?
BDouble(Int, over: Int)
BDouble(String, over: String)?
BDouble(String, radix: Int)?

示例

let integer = BDouble(221)
let double = BDouble(1.192)
let fraction = BDouble(3, over: 4)
let stringFraction = BDouble("1" over: "3421342675925672365438867862653658268376582356831563158967")!

BDouble 提供以下 struct 方法

let bigD = BDouble(-12.32)

bigD.description // Returns "-308/25"
=> print(bigD) // prints "-308/25"


bigD.minimize() // Divides numerator and denominator by their gcd for storage and operation efficiency, usually not neccesary, because of automatic minimization

bigD.rawData() // Returns internal structure

以下操作符与 BDouble 一起使用

// Needs more operators, interoperability with BInt

// Addition
BDouble + BDouble // Returns BDouble

// Subtraction
BDouble - BDouble // Returns BDouble

// Multiplication
BDouble * BDouble // Returns BDouble

// Division
BDouble / BDouble // Returns BDouble

// Comparing
BDouble < BDouble
/*
Important:
a < b <==> b > a
a <= b <==> b >= a
but:
a < b <==> !(a >= b)
a <= b <==> !(a > b)
*/

// More will follow

关于性能

BInt 的速度大约是 mini-gmp 的两倍(目前不算正常的 gmp,因为它需要安装且不便于移植)。例如,BInt 添加数字的速度大约比 GMP 快 2 倍(fib(100,000) 的速度是 272ms 比 530ms),乘法速度则快一倍以上。当需要进行连续的计算和打印阶乘时,BInt 的性能显著优于 GMP。此外,与 GMP 相比,BInt 的使用难度显著降低,且提供了直观的接口。

贡献

  1. 开启分支!
  2. 创建你的功能分支: git checkout -b my-new-feature
  3. 提交您的更改: git commit -am '添加一些功能'
  4. 推送到分支: git push origin my-new-feature
  5. 提交拉取请求 :D