JuliaLang / julia

The Julia Programming Language
https://julialang.org/
MIT License
45.85k stars 5.49k forks source link

FR: `length(BigInt, x)` to avoid overflow #43422

Open fonsp opened 2 years ago

fonsp commented 2 years ago

For some built-in Julia types, calling the length function causes integer overflow:

julia> Iterators.product(1:1e9, 1:1e9) |> length
1000000000000000000

julia> Iterators.product(1:1e10, 1:1e9) |> length
-8446744073709551616

This caused a problem for me, where I was checking "is this object small enough to send over the network?", and the second object gives a false postive. It seems like Base Julia has no built-in way to avoid this.

My feature request would be a to standardise a method length(T::Type, x), where the first argument provides the output type. In my case, I would use it like length(BigInt, x), and the default is length(Int, x).

Usage

With a fallback length(T::Type, x) = convert(T, length(x)), this could gradually be added to the ecosystem:

For example, the new method for the ProductIterator would look like:

length(T::Type, pr::Iterators.ProductIterator) = prod(T[length(T, i) for i in pr.iterators])
DilumAluthge commented 2 years ago

Alternatively, should this particular method of Base.length use checked integer arithmetic?

fonsp commented 2 years ago

Good idea! I implemented this in #43429. The FR remains (it is still not possible to get the length), but my use case ("does x have fewer than y elements?") is covered by doing checked arithmetic, because I can catch for the OverflowError.

adienes commented 1 year ago

since the original example now gives an OverflowError and can be addressed by using BigInt ranges, I think this issue can be closed