# Convert to integer type of minimum required size

**URL:** <https://discourse.julialang.org/t/convert-to-integer-type-of-minimum-required-size/58567>\
**Category:** General Usage\
**Created:** [April 4, 2021, 6:12pm UTC](https://discourse.julialang.org/t/convert-to-integer-type-of-minimum-required-size/58567 "2021-04-04T18:12:20Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![heliosdrm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/heliosdrm/32/3851_2.png) [@heliosdrm](https://discourse.julialang.org/u/heliosdrm)\
**Post date:** [April 4, 2021, 6:12pm UTC](https://discourse.julialang.org/t/convert-to-integer-type-of-minimum-required-size/58567/1 "2021-04-04T18:12:20Z")

</div>

I thought that this should be a trivial question, but I’m failing to find the answer. How can I convert an arbitrary value for which `isinteger(x)` is `true`, into the subtype of `Signed` or `Unsigned` with the minimum required size?

For instance, if I want a `Signed` this should be `Int64` for `2e10`, `Int128` for `2e19`, etc.

I hoped that the `Signed` constructor would do this, but it seems to be equivalent to `Int` (and `Unsigned` seems to be the same as `UInt`), so it doesn’t work.

For floating point numbers, there is the `float` function that converts any number to an appropriate subtype of `AbstractFloat`, but I didn’t find an equivalent solution for integers.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [April 4, 2021, 6:34pm UTC](https://discourse.julialang.org/t/convert-to-integer-type-of-minimum-required-size/58567/2 "2021-04-04T18:34:13Z")

</div>

> [@heliosdrm](#):
>
> How can I convert an arbitrary value for which `isinteger(x)` is `true` , into the subtype of `Signed` or `Unsigned` with the minimum required size?

Doing a conversion like this is type-unstable (because it depends on the value, not the type), so you wouldn’t normally want to do it in performance-sensitive code. And if you have performance-insensitive code, you might as well just use `BigInt`.

That being said, you could certainly do something like this in principle:

```julia
function tointeger(x::AbstractFloat)
    for T in (Int8, Int16, Int32, Int64, Int128)
        if typemin(T) ≤ x ≤ typemax(T)
            return T(x)
        end
    end
    return BigInt(x)
end

```

But as I said, doing type-unstable conversions like this will result in slow code.

Why do you want to do this?

---

<div class="post-metadata">

**Author:** ![Jean\_Michel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jean_michel/32/8282_2.png) [@Jean\_Michel](https://discourse.julialang.org/u/Jean_Michel)\
**Post date:** [April 4, 2021, 7:44pm UTC](https://discourse.julialang.org/t/convert-to-integer-type-of-minimum-required-size/58567/3 "2021-04-04T19:44:26Z")

</div>

Well, I do not know why heliosdrm had to it, but it is certainly necessary sometimes. As pointed in previous discussions, if one wants an exact determinant of an integer matrix, one has often to convert  
the matrix to `BigInt`. If the determinant happens to be a normal integer, then converting it to `Int`  
will certainly speed up the rest of the computation…

---

<div class="post-metadata">

**Author:** ![heliosdrm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/heliosdrm/32/3851_2.png) [@heliosdrm](https://discourse.julialang.org/u/heliosdrm)\
**Post date:** [April 4, 2021, 10:41pm UTC](https://discourse.julialang.org/t/convert-to-integer-type-of-minimum-required-size/58567/4 "2021-04-04T22:41:42Z")

</div>

> [@stevengj](#):
>
> Why do you want to do this?

Actually nothing serious; I was just experimenting with conversions between numeric types, and noticed this lack of an equivalent to `float`, which as pointed out by @Jean_Michel might be convenient in some situations. But the problem of type stability makes a lot of sense of course, so I understand that the advice is: for arbitrary size just use `BigInt` (well, or [SafeIntegers](https://github.com/JeffreySarnoff/SaferIntegers.jl) maybe).

Yet, looking into the precision limits of different types, I can see that there are some constraints that can be used to define type-stable (partial) solutions to this problem:

- If a number is an integer approximated in a `Float16`, it can always be represented as an `Int32`, since `Float16(typemax(Int32)) == Inf16` (and for `typemin` it is `-Inf16`).
- Integer approximations in `Float32` or higher can only be expressed in full by `BigInt`.
- Exact integers represented by `Float16` (smaller than `maxintfloat(Float16)`) can be represented by `Int16`; and same for `Float32`/`Int32`, and `Float64`/`Int64`.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [April 5, 2021, 12:02am UTC](https://discourse.julialang.org/t/convert-to-integer-type-of-minimum-required-size/58567/5 "2021-04-05T00:02:44Z")

</div>

> [@heliosdrm](#):
>
> Exact integers represented by `Float16` (smaller than `maxintfloat(Float16)` ) can be represented by `Int16` ; and same for `Float32` / `Int32` , and `Float64` / `Int64` .

`Float16(6.5504e4) == 65504` is an exact integer. `maxintfloat(Float16)` is only the largest _consecutive_ integer that is exactly represented in `Float16`.

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [April 5, 2021, 4:02am UTC](https://discourse.julialang.org/t/convert-to-integer-type-of-minimum-required-size/58567/6 "2021-04-05T04:02:06Z")

</div>

> [@heliosdrm](#):
>
> Exact integers represented by `Float16` (smaller than `maxintfloat(Float16)` ) can be represented by `Int16` ; and same for `Float32` / `Int32` , and `Float64` / `Int64` .

You mean `UInt16` right? Because:

```julia
julia> trunc(Int16, prevfloat(typemax(Float16)))
ERROR: InexactError: trunc(Int16, 65504.0)
Stacktrace:
 [1] trunc at ./float.jl:682 [inlined]
 [2] trunc(::Type{Int16}, ::Float16) at ./float.jl:360
 [3] top-level scope at REPL[12]:1

```

but

```julia
julia> trunc(UInt16, prevfloat(typemax(Float16)))
0xffe0

```

Also:

```julia
julia> trunc(UInt32, prevfloat(typemax(Float32)))
ERROR: InexactError: trunc(UInt32, 3.4028235e38)
Stacktrace:
 [1] trunc(::Type{UInt32}, ::Float32) at ./float.jl:682
 [2] top-level scope at REPL[14]:1

julia> trunc(UInt64, prevfloat(typemax(Float64)))
ERROR: InexactError: trunc(UInt64, 1.7976931348623157e308)
Stacktrace:
 [1] trunc(::Type{UInt64}, ::Float64) at ./float.jl:682
 [2] top-level scope at REPL[15]:1

```

So I do not believe this holds for larger Floating Point numbers for which the exponent is bigger.

---

<div class="post-metadata">

**Author:** ![heliosdrm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/heliosdrm/32/3851_2.png) [@heliosdrm](https://discourse.julialang.org/u/heliosdrm)\
**Post date:** [April 5, 2021, 7:30am UTC](https://discourse.julialang.org/t/convert-to-integer-type-of-minimum-required-size/58567/7 "2021-04-05T07:30:52Z")

</div>

> [@Henrique\_Becker](#):
>
> You mean `UInt16` right?

No, I meant Int16, but due to an incomplete understanding of `maxintfloat`, as pointed out by @stevengj .
