Currently there are no `to_i128`

and `to_u128`

methods for `BigInts`

.

This causes some problems for doing math in some instances.

See e.g. Integer root algorithm · Issue #13416 · crystal-lang/crystal · GitHub and

Ruby out performs Crystal significantly on this numerical algorithm - #15 by jzakiya

A really simple (and not too ugly) way to convert a number of one type to another is as follows.

If `a = "1283984894429".to_big_i`

can fit into a smaller `Int`

primitive you can do

` x = typeof(1i64).new(a.to_s)`

, and `x = a`

will now be a `Int64`

.

Here’s an actual use case from above issue.

```
lib LibGMP
fun root = __gmpz_root(rop : MPZ*, op : MPZ*, n : ULong) : Int
end
def irootgmp(val, n : Int::Primitive)
# error handling / range check not shown
root = BigInt.new { |mpz| LibGMP.root(mpz, val.to_big_i, n) }
typeof(val).new(root.to_s)
end
```

Here `LibGMP.root(mpz, val.to_big_i, n)`

returns the nth integer root of `val`

.

`root`

is returned from the function as a `BigInt`

, but is always smaller than `val`

, and when doing actual math in an algorithm you usually want them to be the same type.

So `typeof(val).new(root.to_s)`

returns `root`

as the same type as `val`

.

This gets around the current case where you can’t do `BigInt.to_(u|i)128`

.

This has the added benefit of converting any larger `Int`

type to a smaller one it can fit within (and obviously vice versa) without having to do explicit `to_(u|i)xint`

.