rust-num / num-traits

Numeric traits for generic mathematics in Rust
Apache License 2.0
694 stars 131 forks source link

Document and/or allow truncation/rounding when casting from float to int? #296

Closed JulianKnodt closed 10 months ago

JulianKnodt commented 10 months ago

When casting from a float to an int, currently it follows the default approach of truncating the digits. I think it may be worth more explicit in the docs that this is the default behavior. In addition, for some cases it may be worth letting the caller dictate the rounding behavior, as right now in a generic context it's not possible to control how it's handled, unless I use some hacky check after conversion.

cuviper commented 10 months ago

Doc improvements are welcome in PRs.

it may be worth letting the caller dictate the rounding behavior,

That sounds like a whole new API! Maybe you could implement your own wrapper with different floating point behavior, and I found an example of that in a different crate with az::Round. Another option I found is numeric_cast with multiple traits available.

JulianKnodt commented 10 months ago

I'm currently working with num_traits inside of a crate I don't own (see linked PR), and it is using ToPrimitive in order to cast between f32 to either an integer or a float (specified only as an impl Primitive). If it is a float that it is being cast to, I don't want to do any rounding. While the library could change to use a different trait for their numeric types, it's a bit invasive of a change, and it feels natural that conversion between primitives should be able to control their rounding mode.

For the specific issue, there's workarounds, but I think it was worth asking here since it seems to be the most natural place to change it. If you don't think it should be added though, that's fine

cuviper commented 10 months ago

If it is a float that it is being cast to, I don't want to do any rounding.

This isn't generally possible to guarantee either. f64 to f32 definitely has to round, but even integer to float will round if the value is greater than the mantissa bits can represent.

In any case, it's not possible to control rounding with the current API. A new rounding API would need to be proposed.

JulianKnodt commented 10 months ago

ah yes, currently I'm doing f32 -> Generic which would not require rounding.

Sounds good. I don't think I'll propose such an API myself, so for now I'll just close this.