# Convert an f64 to an i32

**URL:** <https://users.rust-lang.org/t/convert-an-f64-to-an-i32/50991>\
**Category:** help\
**Created:** [November 2, 2020, 5:56pm UTC](https://users.rust-lang.org/t/convert-an-f64-to-an-i32/50991 "2020-11-02T17:56:07Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![user122122](https://avatars.discourse-cdn.com/v4/letter/u/ebca7d/32.png) [@user122122](https://users.rust-lang.org/u/user122122)\
**Post date:** [November 2, 2020, 5:56pm UTC](https://users.rust-lang.org/t/convert-an-f64-to-an-i32/50991/1 "2020-11-02T17:56:08Z")

</div>

The integral part of the `f64` is over the limit of the `i32`. I have the corresponding C++ code.

```rust
// compiler - g++
// version - 10.2.0
// standard - C++14
int32_t n_int = (long int) round(n_double);

```

Can you show me the rust code which does exactly this?

I tried using wraps. But instead of wrapping around, the variable takes a limit of `i32`, i.e. either `2147483647` or `-2147483648` depending on the sign of the `f64`.

The other ways I considered were to

1. Just keep the least significant 32 bits (I know how to do this for an i64, but not an f64, also when truncated, we need to worry about the sign and the twos complement).
2. Subtract the limit over and over till the number gets under the limit (I don't know if I should consider MAX or MAX-MIN or something else).

I'm not sure if either method does exactly what the C code does (even in the extreme/corner cases).

Edit -  
Very good solutions below. I'll just mark this for future reference.

---

<div class="post-metadata">

**Author:** ![sfackler](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/sfackler/32/132_2.png) [@sfackler](https://users.rust-lang.org/u/sfackler)\
**Post date:** [November 2, 2020, 6:08pm UTC](https://users.rust-lang.org/t/convert-an-f64-to-an-i32/50991/2 "2020-11-02T18:08:54Z")

</div>

The behavior of the C++ code is undefined if the integer part of the double cannot be represented by a long int. If you want that exact behavior, you can use [f64 - Rust](https://doc.rust-lang.org/std/primitive.f64.html#method.to_int_unchecked).

---

<div class="post-metadata">

**Author:** ![user122122](https://avatars.discourse-cdn.com/v4/letter/u/ebca7d/32.png) [@user122122](https://users.rust-lang.org/u/user122122)\
**Post date:** [November 2, 2020, 6:29pm UTC](https://users.rust-lang.org/t/convert-an-f64-to-an-i32/50991/3 "2020-11-02T18:29:49Z")

</div>

By long int, do you mean the 64-bit one?

---

<div class="post-metadata">

**Author:** ![mbrubeck](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/mbrubeck/32/648_2.png) [@mbrubeck](https://users.rust-lang.org/u/mbrubeck)\
**Post date:** [November 2, 2020, 6:38pm UTC](https://users.rust-lang.org/t/convert-an-f64-to-an-i32/50991/4 "2020-11-02T18:38:51Z")

</div>

In [Rust 1.45.0 and later](https://blog.rust-lang.org/2020/07/16/Rust-1.45.0.html#fixing-unsoundness-in-casts), casting using the `as` keyword has the behavior that you desire

```rust
/// If `x` is out of range, this returns `i32::MAX` or `i32::MIN`.
fn convert(x: f64) -> i32 {
    x as i32
}

```

For more details, see [PR #71269](https://github.com/rust-lang/rust/pull/71269) and the [Rust Reference](https://doc.rust-lang.org/reference/expressions/operator-expr.html?highlight=cast#semantics).

---

<div class="post-metadata">

**Author:** ![user122122](https://avatars.discourse-cdn.com/v4/letter/u/ebca7d/32.png) [@user122122](https://users.rust-lang.org/u/user122122)\
**Post date:** [November 2, 2020, 6:40pm UTC](https://users.rust-lang.org/t/convert-an-f64-to-an-i32/50991/5 "2020-11-02T18:40:48Z")

</div>

I need it to wrap around the i32 boundaries.

To be clear, keep subtracting MAX - MIN (+1?) until the number falls inside the boundary, i.e. less that MAX and greater than MIN.

---

<div class="post-metadata">

**Author:** ![sfackler](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/sfackler/32/132_2.png) [@sfackler](https://users.rust-lang.org/u/sfackler)\
**Post date:** [November 2, 2020, 6:41pm UTC](https://users.rust-lang.org/t/convert-an-f64-to-an-i32/50991/6 "2020-11-02T18:41:38Z")

</div>

By long int, I mean the `long int` type you are using in that C++ code.

---

<div class="post-metadata">

**Author:** ![mbrubeck](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/mbrubeck/32/648_2.png) [@mbrubeck](https://users.rust-lang.org/u/mbrubeck)\
**Post date:** [November 2, 2020, 6:55pm UTC](https://users.rust-lang.org/t/convert-an-f64-to-an-i32/50991/7 "2020-11-02T18:55:31Z")

</div>

Ah, sorry, I misunderstood which behavior you wanted.

Something like this should work:

```rust
fn convert(x: f64) -> i32 {
    x.round().rem_euclid(2f64.powi(32)) as u32 as i32
}

```

---

<div class="post-metadata">

**Author:** ![user122122](https://avatars.discourse-cdn.com/v4/letter/u/ebca7d/32.png) [@user122122](https://users.rust-lang.org/u/user122122)\
**Post date:** [November 2, 2020, 7:01pm UTC](https://users.rust-lang.org/t/convert-an-f64-to-an-i32/50991/8 "2020-11-02T19:01:42Z")

</div>

So I experimented a bit on the C++ code using a few values for the `f64/double`.

I think this fits the best, I'm not completely sure though.

```rust
let a: f64 = <some_f64>;
let M: i64 = i32::MAX as i64;
let m: i64 = i32::MIN as i64;
let q: i64 = M - m + 1;
let mut b: i64 = a.round() as i64 % q;
b = if b > M { b-q } else if b < m { b+q } else { b };
let c: i32 = b as i32;
dbg!(c);

```

---

<div class="post-metadata">

**Author:** ![user122122](https://avatars.discourse-cdn.com/v4/letter/u/ebca7d/32.png) [@user122122](https://users.rust-lang.org/u/user122122)\
**Post date:** [November 2, 2020, 7:02pm UTC](https://users.rust-lang.org/t/convert-an-f64-to-an-i32/50991/9 "2020-11-02T19:02:17Z")

</div>

That's a handful of terms. I didn't know converting a u32 to an i32 was safe.

---

<div class="post-metadata">

**Author:** ![trentj](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/trentj/32/5690_2.png) [@trentj](https://users.rust-lang.org/u/trentj)\
**Post date:** [November 2, 2020, 7:49pm UTC](https://users.rust-lang.org/t/convert-an-f64-to-an-i32/50991/10 "2020-11-02T19:49:30Z")

</div>

To imitate C++ code which has undefined behavior seems like a fool's errand. Even if you get it right today, it could change tomorrow, with a new compiler, different optimizations...

---

<div class="post-metadata">

**Author:** ![system](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/system/32/51372_2.png) [@system](https://users.rust-lang.org/u/system)\
**Post date:** [February 2, 2021, 10:16am UTC](https://users.rust-lang.org/t/convert-an-f64-to-an-i32/50991/12 "2021-02-02T10:16:08Z")

</div>

Closed on February 2, 2021, 10:16am UTC

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.
