mkrd / swift-bigint Goto Github PK
View Code? Open in Web Editor NEWA lightweight, Arbitrary Precision Arithmetic Library for Swift!
License: MIT License
A lightweight, Arbitrary Precision Arithmetic Library for Swift!
License: MIT License
Will you support hex string conversion in a near future?
Steps to reproduce:
print(BInt(0).factorial())
Should return 1
I've tried to use the BDouble for storage but at some point I need to use decimalExpansion
to format the value to end users, and I was getting really weird values. In a debug session I got the following:
(lldb) po percent
▿ 7450921770987/7450936270987
- sign : false
▿ numerator : 1 element
- 0 : 7450921770987
▿ denominator : 1 element
- 0 : 7450936270987
- magnitude : 0.0
- _precision : 4
(lldb) po percent.decimalDescription
"0.99910"
(lldb) po percent.decimalExpansion(precisionAfterDecimalPoint: 2)
"0.910"
(lldb) po percent.decimalExpansion(precisionAfterDecimalPoint: 0)
"0.0"
(lldb) po percent.decimalExpansion(precisionAfterDecimalPoint: 7)
"0.9999981"
I'm pretty certain a value nearly 1 should not round to 0 when displayed to end users. Is decimalExpansion
not the function I'm expecting and should I be using something else? I had expected the value to round to either 1.0
or 0.9
.
There are a ton of data types we could support. See https://github.com/vmanot/Swallow/blob/9f686ef305b6c83179ace64eaa26a1b3877a640c/Sources/Intermodular/Helpers/Swift/FloatingPointInitiable.swift
Currently we only support Int
and Double
. It would not be hard to support more types
Mentioned in #19 but duplicated here as not to inflate that issue
I'm trying to init a BDouble with BDouble("8.585213060425812e-06")
and BDouble(8.585213060425812e-06)
.
I'm setting the precision to 32.
Initialising with String
or Double
seems to be the same result when call decimalDescription
:
8585213.06042581200000000000000000000000
I think the correct number is supposed to be: 0.00000858521306042581200000000000
Thanks in advance.
The following code crashes:
let x = BDouble(0.000000025)
print("Testing \(x)")
let y = x.rounded()
print("Testing \(y)")
The output would be:
Testing 1/40000000
Swift/Collection.swift:1323: Fatal error: Can't take a prefix of negative length from a collection
2023-03-17 11:51:15.206359+0100 wallace[94628:1194297] Swift/Collection.swift:1323: Fatal error: Can't take a prefix of negative length from a collection
(lldb) po x
▿ 1/40000000
- sign : false
▿ numerator : 1 element
- 0 : 1
▿ denominator : 1 element
- 0 : 40000000
- magnitude : 0.0
- _precision : 4
Integer literal '8000000000' overflows when stored into 'Int'
@twodayslate lets publish a new release, since a few fixed have been merged recently.
Since I didn't setup the package manager stuff, I'm not sure how to do it.
Can you maybe tell me how it is done?
Is it as simple as making a new Github release, or is it more involved, like uploading to a package registry?
Hi
The README contains the following:
// Exponentiation
BInt ** Int // Retuns BInt to the power of Int
but I get a compilation error of "Cannot convert value of type 'BInt' to expected argument type 'BDouble'" from the following code. Am I doing something wrong or is the documentation or API at fault?
let TWO : BInt = 2
let TWO_SIX_THREE : Int = 263
var TWO_POW_263 : BInt = TWO ** TWO_SIX_THREE
Thanks in anticipation
Martin
Hi,
I just tried this library on Linux but it failed. I tried to fix it but then I gave up because the errors are out of my knowledge level yet. I tested it on Linux Ubuntu 14.04 using Swift v3.
So, any plan to support Linux? I need this library to support my web app (written in Swift).
Thank you.
-Bee
It appears that for some values of BDouble, decimal expansion produces incorrect values below certain precision points.
For example, I added the following test case to the project:
bigD?.decimalExpansion(precisionAfterComma: 2)
is expected to equal "0.71"
, but instead resolves to "0.00".
This is also the case for any precision value up to 9, where the decimalExpansions resolves to what it is expected to be:
I don't know enough about the maths side of this to fix it, but I had a quick look at the decimalExpansion
function and found this block of code:
if res.count < digits + 2
{
let pad = String(repeating: "0", count: max(digits, 1))
res = res.padding(toLength: digits+2-origRes.count, withPad: pad, startingAt: res.count)
}
Removing that res.count < digits + 2
check fixes this issue, but I'm guessing it's required for some other reason?
All the tests in the project pass if this block is removed.
BigInt(UInt64.max)
, when executed, will crash, throwing "Swift/Integers.swift:3564: Fatal error: Not enough bits to represent the passed value". This is likely due the BigInt
initializer trying and failing to convert a UInt64
value to Int
.
The following code does not crash: BigInt(String(UInt64.max))!
I simply threw this in a new project, but it will not build due to 1 issue:
Command failed due to signal: Segmentation fault: 11
Xcode 8.3.3
I can't compile SMP.swift file because SignedNumeric and BinaryInteger are undeclared.
let hundred = 100
if let bint = BInt("11173433833219812840") {
if hundred < bint {
print("bint(\(bint)) is bigger than a hundred")
} else {
print("bint(\(bint)) is lower than a hundred or equals")
}
if 100 < bint {
print("bint(\(bint)) is bigger than 100")
} else {
print("bint(\(bint)) is lower than 100 or equals")
}
}
bint(11173433833219812840) is lower than a hundred or equals
bint(11173433833219812840) is bigger than 100
It is ok when a Bint is compared with a numeric constant directly, but comparing with a "let constant" is not correct.
For permanent storage purposes, implement full compatibility with NSData, so that a BInt can be converted from and to the NSData type
Greetings! This is an awesome library. Nice work.
I imported it to a project to run some tests, and ran into this error for the ** operator: Operator implementation without matching operator declaration. I commented out the static ** function and the few other functions that used ** and was able to still use the library for basic BInt operations (e.g. +,-). Maybe this is an incompatibility introduced in Swift 4?
Again, great job!
How is it possible to get the Bint values in the form of and [Uint]
Let's face it, the readme could be a lot better. It should be refactored to conform to current conventions, provide a more complete overview of the library and to increase readability
It is currently throwing an error that it is not a valid directory structure.
var a = 5
a += BInt(10)
print("a=\(a)")
=======
a=20
Thank you for your development.
let w = BInt("0b1310c5a2c30000", radix: 16)
(lldb) po w
nil
The problem seems to be with the hex strings starting with 0b
.
BInt("0b", radix: 16).asString(radix: 10)
also returns zero.
In my podspec, add this pod,
s.dependency 'BigNumber', :git => 'https://github.com/mkrd/Swift-Big-Integer.git'
it said that I cant do this way.
Podspecs cannot specify the source of dependencies. The `:git` option is not supported. `:git` can be used in the Podfile instead to override global dependencies
So, could you push your pod to trunk, then we can search this pod when pod search
, and add this pod as a dependency in podsepc.
Hi,
Since now Swift 2 is deprecated, when swift 3 support will come?
Thank you.
-Bee
I have implemented a wrapper class for use in a set of mathemetical calculations I am experimenting with. I am trying to present an arbitrary math set of tools largely because IEEE standards introduce many approximations. So I have been unit testing the use of BDouble to support my needs, and i have found several use cases where BDouble loops infinitely. one such use case is the square root of 1024000.0. My unit test is very simple.
func testSqrt1MPure() {
BDouble.precision = 30
let testcase = BDouble("1024000")!
let testResult = testcase.nthroot(2)
XCTAssert(testResult - BDouble("1011.92885125388138623964593421847026868")! < Double.ulpOfOne, "testcase5 = testResult.decimalExpansion(precisionAfterDecimalPoint: 30))")
}
I have to try convert hex string: 0x00000000000000000000000000000000000000000000000a4cc799563c380000
but library return nil.
How to convert it?
I am just wondering how I should serialize BInt
and BDouble
to Data type. Is there any good way you can think of?
BigInt has a method for this. (https://github.com/attaswift/BigInt/blob/f2a3c28ce44a8e8ed9cc576d779861d4145bae0e/sources/Data%20Conversion.swift#L81)
It would be great if you could get a random big number.
Below are my proposed function stubs
//: Generate a BInt between 0 and `upperBound`
public func random(upperBound: BInt) -> BInt
//: Generate a BInt between low and high
public func random(low: BInt, high: BInt) -> BInt
//: Generate a BDouble between 0 and upperBound
public func random(upperBound: BDouble) -> BDouble
//: Generate a BDouble between low and high
public func random(low: BDouble, high: BDouble) -> BDouble
class BInt {
//: Generate a BInt between 0 and `upperBound`
class public func random(upperBound: BInt) -> BInt
//: Generate a BInt between low and high
class public func random(low: BInt, high: BInt) -> BInt
}
class BDouble {
//: Generate a random DBouble between 0 and 1
class public func random() -> BDouble
//: Generate a BDouble between 0 and upperBound
class public func random(upperBound: BDouble) -> BDouble
//: Generate a BDouble between low and high
class public func random(low: BDouble, high: BDouble) -> BDouble
}
Both global and class functions would be available.
Thoughts? Ideas on implementation?
Trying to add master branch as dependency in Xcode 11 GM 2. Got error:
: package at 'https://github.com/mkrd/Swift-BigInt' @ 0b353aa84f2a4c0de499f496ce8d551f07bd8d9c is using Swift tools version 3.1.0 which is no longer supported; consider using '// swift-tools-version:5.1' to specify the current tools version
when performing 75! % 13, the answer should be 10, but instead, it shows 0
4216953730099865132 % 2 will crash (see full details below)
2214286210472843133 % 2 will crash
I'm implementing the Rabin-Miller primality test so I'm generating lots of big ints with BIntMath randomBInt(...)
and testing to see if they are prime. I am not using the BIntMath func isPrime(_ n: BInt) -> Bool
, but rather testing with my implementation of the primality test.
From the console:
Fatal error: Double value cannot be converted to Int because it is either infinite or NaN
2019-12-10 10:21:47.948907-0500 Primes[49528:3931759] Fatal error: Double value cannot be converted to Int because it is either infinite or NaN
(lldb) po n
▿ 4216953730099865132
(lldb) po n % 2
Fatal error: Double value cannot be converted to Int because it is either infinite or NaN
2019-12-10 10:22:20.063759-0500 Primes[49528:3931759] Fatal error: Double value cannot be converted to Int because it is either infinite or NaN
error: Execution was interrupted, reason: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0).
The process has been returned to the state before expression evaluation.
BUT check this out. When I try to test I get a BInt with one less limb ... not sure what it means but it seems important.
(lldb) po BInt("4216953730099865132")! % 2
▿ 0
- sign : false
▿ limbs : 1 element
- 0 : 0
The randomly created numbers seem different from their string-created siblings.
in some case , using prealloced memory would be a better choice
it would be appreciated that if you offer a clean function to reset the limbs to zero .
keeping temp sensitive data on memory is not a good choice
maybe codes below say more
func afunction(b:inout Bint){
var temporaryObjects = BInt alloc from Buffer Pool user provide
.
.
.
/// do the CLEAN job,
temporaryBints.SetLimbsBytesToZero()
temporaryBints set all the storage data to 0;
}
BDouble
is missing some important functionality. Below are some of things I think should be added:
BDouble
also needs full support for the String
initialization method (completed in #20)
Also proposing a repository name change to some variant of BigNumber
The swift package manager makes it a lot easier to manage third party libraries. This library should also support the new package manager
lines 2282 and 2888
'encodedOffset' is deprecated: encodedOffset has been deprecated as most common usage is incorrect. Use utf16Offset(in:) to achieve the same behavior.
https://github.com/BitBaum/Swift-Big-Integer/search?utf8=✓&q=getPrime
Thank you for your lib!
Hi,
Do you have any plan to give it a number formatter support? I need at least a thousand separator, a decimal separator, and currency symbol, similar to NumberFormatter.
Thank you.
Regards,
-Bee
https://twitter.com/v_pradeilles/status/1496463121455751168?s=21
Not sure what protocol gives you this but we should support it.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.