I'm practicing some Rust by going through Numerical Recipes, but I'm not getting very far because I don't understand how to work with generic types. Here's the function I'm trying to implement.
/// Return a value with the magnitude of `a` and and the sign of `b`
pub fn sign<T>(a: T, b: T) -> T
where T: PartialOrd + std::ops::Neg<Output = T>,
{
if b >= 0 {
if a >= 0 {
a
} else {
-a
}
} else {
if a >= 0 {
-a
} else {
a
}
}
}
This doesn't work because 0 is an integer and not a T. What's the right way to do this?
I'm not familiar with this "Numerical Recipes" thing, but using generic integers is generally rather cumbersome in Rust. I would recommend just picking an integer type and using that.
The num_traits crate has traits for working with generic number types. I believe you could use a num_traits::Num bound to get the comparison to zero, though you'd have to rewrite it slightly so you aren't using a 0 literal.
Thanks for the help. I was able to get it to work with num_traits like this...
use num_traits::{self, Signed};
/// Return a value with the magnitude of `a` and and the sign of `b`
pub fn sign<T>(a: T, b: T) -> T
where T: PartialOrd + Signed,
{
if b.is_positive() {
if a.is_positive() {
a
} else {
-a
}
} else {
if a.is_positive(){
-a
} else {
a
}
}
}
I think the most literal translation of your original code would be
pub fn sign<T>(a: T, b: T) -> T
where
T: PartialOrd + std::ops::Neg<Output = T> + num_traits::Num,
{
if b >= T::zero() {
if a >= T::zero() {
a
} else {
-a
}
} else {
if a >= T::zero() {
-a
} else {
a
}
}
}