Coder Social home page Coder Social logo

mkrd / swift-bigint Goto Github PK

View Code? Open in Web Editor NEW
240.0 240.0 61.0 5.89 MB

A lightweight, Arbitrary Precision Arithmetic Library for Swift!

License: MIT License

Swift 96.09% Ruby 3.25% Shell 0.66%
arbitrary-precision bigint biginteger bignum bint gmp swift swift-bigint xcode

swift-bigint's People

Contributors

currybab avatar mdaxter avatar mgriebling avatar mkrd avatar mrs1669 avatar mura-admin avatar nathanfallet avatar piggy-park avatar sunzhic avatar tingwoo avatar twodayslate avatar verebes1 avatar ypopovych avatar yuzushioh avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

swift-bigint's Issues

decimalExpansion gives out unexpected values

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.

Initialization of negative scientific notation

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.

BigDouble Mod Error

I think there is an error with the mod function.
Error occurs when testing mod functions with values greater than two digits.
Is there any solution or test case? or something I wrong?

스크린샷 2022-09-29 오전 11 33 15

스크린샷 2022-09-29 오전 10 15 01

Crash calling `rounded()` on a BDouble value

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

Publish v2.2.1

@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?

Exponentiation and types

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

Linux support

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

BDouble.DecimalExpansion produces incorrect results for some BDouble values unless precision is set higher

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:
screen shot 2018-04-25 at 18 12 44
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:
screen shot 2018-04-25 at 18 15 23

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 initializer crashes on large integers

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))!

Cannot Build

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

Critical comparing bug: Int(100) is sometimes bigger than BInt("11173433833219812840")

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.

NSData

For permanent storage purposes, implement full compatibility with NSData, so that a BInt can be converted from and to the NSData type

Implementation of "**" and Swift 4 compatability

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!

Bint to [UInt]

How is it possible to get the Bint values in the form of and [Uint]

Refactor readme

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

Convert hex string to decimal returns null

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.

Why not push a podspec to trunk?

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.

Swift 3 support

Hi,

Since now Swift 2 is deprecated, when swift 3 support will come?

Thank you.

-Bee

nthroot(1024000, 2) looping forever

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))")
}

Convert hex string to decimal number

I have to try convert hex string: 0x00000000000000000000000000000000000000000000000a4cc799563c380000 but library return nil.

How to convert it?

Random Big Number

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?

Update Package.swift to Swift 5 toolchain

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

Valid (n % p) leads to Fatal error: Double value cannot be converted to Int because it is either infinite or NaN

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

  • sign : false
    ▿ limbs : 2 elements
    • 0 : 4216953730099865132
    • 1 : 0

(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.

adding a clean function and a prealloc buffer support

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 Operations

BDouble is missing some important functionality. Below are some of things I think should be added:

  • Powering
  • Modulo
  • Floor
  • Ceiling
  • Rounding
  • Square root
  • Scientific Notation
  • #22

BDouble also needs full support for the String initialization method (completed in #20)

Also proposing a repository name change to some variant of BigNumber

Swift Package Manager

The swift package manager makes it a lot easier to manage third party libraries. This library should also support the new package manager

Warnings in Swift-Big-Number-Core.swift

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.

Formatter support

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

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.