Bigger

This is a crystal native implementation of an arbitrary arithmetic math library. This library aims to provide the same methods and interface that crystal's own big library provides.

FAQ

Is this faster than big?

Nope.

Is it more memory efficient?

Still no.

Is it written in Crystal?

Yes.

Can it be made more efficient?

Absolutely. All operations were implemented using a naive algorithm. There's lots of room for improvement.

Is it actually bigger?

No. But it could be! Maybe! Being written in crystal means it can be modified as needed to support different use cases.

Features

Performance

Running with an intel i7-8565U 1.80GHz CPU. Benchmark run with numbers:

a = 418376253051223933501534965978459129894917720729884038908657101374047974
b = 56628806604608093150302361055407918781958950380522727726457202444371318

| | Big Avg Op Time | Bigger Avg Op Time | Bigger vs Big Time | Big Mem | Bigger Mem | Bigger vs Big Mem | | ------------- | --------------- | ------------------ | ------------------ | ------- | ---------- | ----------------- | | a + b | 28.91ns | 85.88ns | 2.97× slower | 48B | 161B | 3.35x | | a - b | 32.40ns | 179.38ns | 5.54× slower | 48B | 384B | 8.00x | | a // b | 123.42ns | 345.05µs | 6698.15× slower | 16B | 710kiB | 45,411.62x | | b // a | 51.51ns | 107.25ns | 2.08× slower | 16B | 272B | 17.00x | | a % b | 119.79ns | 341.06µs | 7332.65× slower | 48B | 709kiB | 15,125.15x | | b % a | 46.51ns | 107.17ns | 2.30× slower | 48B | 272B | 5.67x | | a * b | 47.10ns | 1.36µs | 28.80× slower | 80B | 2.8kiB | 35.83x | | a tdiv b | 65.03ns | 715.16µs | 10998.00× slower | 16B | 1.39MiB | 91,057.00x | | a remainder b | 115.18ns | 717.47µs | 6228.90× slower | 48B | 1.39MiB | 30,360.71x | | ~a | 26.95ns | 172.72ns | 6.41× slower | 48B | 402B | 8.38x | | !a | 1.46ns | 1.46ns | 1.00× slower | 0B | 0B | NaNx | | a**(40) | 2.86µs | 254.70µs | 89.13× slower | 1.31kiB | 462kiB | 352.06x | | a<<(40) | 28.61ns | 177.85ns | 6.22× slower | 48B | 273B | 5.69x | | a>>(40) | 32.74ns | 118.31ns | 3.61× slower | 48B | 208B | 4.33x |

This table was generated by running make benchmark, which uses Benchmark::IPS::Job under the hood.

Installation

  1. Add the dependency to your shard.yml:

    dependencies:
      bigger:
        github: vici37/bigger
  2. Run shards install

Usage

require "bigger"

a = "418376253051223933501534965978459129894917720729884038908657101374047974".to_bigger_i
b = "56628806604608093150302361055407918781958950380522727726457202444371318".to_bigger_i

a + b

Development

Specs are the lifeblood of any library's success. When making changes, make sure to run the specs frequently. For convenience, you can use:

> make test
> make test-prod

The first one runs all of the specs using a base of UInt8, while the latter runs specs using with a base of UInt32. Running with bases of UInt8 tends to make things easier to debug as it's easier to test around the digit overflow points.

Contributing

  1. Fork it (https://github.com/vici37/bigger-num/fork)
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request

Contributors