获取整型的双精度版本



我正在寻找一种通用机制,允许我获得给定整数类型的双精度版本

u8 -> u16
u16 -> u32

等等

在c++中,我们可以定义模板结构
#include <cstddef>
using undefined = void;
template <class T>
struct double_precision {
using type = undefined;
};
template <class T>
using double_precision_t = typename double_precision<T>::type;

和添加专门化

template <>
struct double_precision<std::uint8_t> {
using type = std::uint16_t;
};
template <>
struct double_precision<std::uint16_t> {
using type = std::uint32_t;
};
template <>
struct double_precision<std::uint32_t> {
using type = std::uint64_t;
};

在之后得到双精度版本的double_precision_t<T>,如

template<class T>
double_precision_t<T> square(T value) {
double_precision_t<T> double_precision_value = value;
return double_precision_value * double_precision_value;
}

我们如何在Rust中做类似的事情?

你可以使用traits:

trait DoublePrecision {
type Output: From<Self>;
}
impl DoublePrecision for u16 {
type Output = u32;
}
// etc...

然后按如下方式使用:

fn square<T: DoublePrecision>(value: T) -> T::Output
where
T::Output: std::ops::Mul<T::Output, Output = T::Output>
{
value.into() * value.into()
}

对于更复杂的用法,请参见numtrait向T添加需求。

您可以使用一个trait和一些numtrait来使其相当通用:

use num::cast::AsPrimitive;
trait DoublePrecision: AsPrimitive<Self::Output> {
type Output: std::ops::Mul<Output = Self::Output> + Copy;
fn double_precision(self) -> Self::Output {
self.as_() * self.as_()
}
}
impl DoublePrecision for u8 {
type Output = u16;
}
fn main() {
assert_eq!(16, 4.double_precision());
}

你可以写一个小宏来写impl块。

最新更新