Swift-BigInt

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

它支持整数 (BInt) 和分数 (BDouble),并带有大多数常用的数学运算符。像阶乘或最大公约数这样的优化数学函数也已实现,并且可以通过 BIntMath 访问。有关更多详细信息,请继续阅读。

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

调查时间!

调查链接

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

安装

拖放

该库的主要目标之一是轻量级和独立性。

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

是的,就这么简单 :)

Swift 包管理器

您可以使用 Swift Package Manager 并在您的 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       // Returns 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 提供以下结构体方法

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 necessary, 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) 为 272 毫秒 vs 530 毫秒),乘法的速度是其两倍以上。当给定连续计算和打印阶乘的任务时,BInt 的性能明显优于 GMP。此外,GMP 明显更难使用,而 BInt 提供了直观的界面。

贡献

  1. Fork 它!
  2. 创建您的功能分支:git checkout -b my-new-feature
  3. 提交您的更改:git commit -am 'Add some feature'
  4. 推送到分支:git push origin my-new-feature
  5. 提交 pull request :D