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
- [x] Big Int
- [ ] Big Float
- [ ] Big Decimal
- [ ] Big Rational
- [ ] Big Complex
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
-
Add the dependency to your
shard.yml
:dependencies: bigger: github: vici37/bigger
-
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
- Fork it (https://github.com/vici37/bigger-num/fork)
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create a new Pull Request
Contributors
- Troy Sornson - creator and maintainer