From and Into traits and conversion of usize to f64
我一直试图以一种非常通用的方式编写一些Rust代码,而没有明确指定类型。 但是,我到达需要将
那么,如果我想编写尽可能通用的代码,那有什么选择呢? 显然,我应该使用可能会失败的特征(与
这是下面的代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | #![feature(zero_one)] use std::num::{Zero, One}; use std::ops::{Add, Mul, Div, Neg}; use std::convert::{From, Into}; /// Computes the reciprocal of a polynomial or of a truncation of a /// series. /// /// If the input is of length `n`, then this performs `n^2` /// multiplications. Therefore the complexity is `n^2` when the type /// of the entries is bounded, but it can be larger if the type is /// unbounded, as for BigInt's. /// fn series_reciprocal< T >(a: &Vec< T >) -> Vec< T > where T: Zero + One + Add<Output=T> + Mul<Output=T> + Div<Output=T> + Neg<Output=T> + Copy { let mut res: Vec< T > = vec![T::zero(); a.len()]; res[0] = T::one() / a[0]; for i in 1..a.len() { res[i] = a.iter() .skip(1) .zip(res.iter()) .map(|(&a, &b)| a * b) .fold(T::zero(), |a, b| a + b) / (-a[0]); } res } /// This computes the ratios `B_n/n!` for a range of values of `n` /// where `B_n` are the Bernoulli numbers. We use the formula /// /// z/(e^z - 1) = \\sum_{k=1}^\\infty \\frac {B_k}{k!} z^k. /// /// To find the ratios we truncate the series /// /// (e^z-1)/z = 1 + 1/(2!) z + 1/(3!) z^2 + ... /// /// to the desired length and then compute the inverse. /// fn bernoulli_over_factorial<T, U>(n: U) -> Vec< T > where U: Into<usize> + Copy, T: Zero + One + Add<Output=T> + Mul<Output=T> + Add<Output=T> + Div<Output=T> + Neg<Output=T> + Copy + From<usize> { let mut ans: Vec< T > = vec![T::zero(); n.into()]; ans[0] = T::one(); for k in 1..n.into() { ans[k] = ans[k - 1] / (k + 1).into(); } series_reciprocal(&ans) } fn main() { let v = vec![1.0f32, 1.0f32]; let inv = series_reciprocal(&v); println!("v = {:?}", v); println!("v^-1 = {:?}", inv); let bf = bernoulli_over_factorial::<f64,i8>(30i8); } |
问题是整数→浮点转换(浮点类型的大小等于或小于整数)不能保留所有值。 因此
这些类型的转换基本上是
使用
1 2 3 4 5 6 7 8 9 | use conv::prelude::*; ... where T: ValueFrom<usize> + ... ... ans[k] = ans[k - 1] / (k + 1).value_as::< T >().unwrap(); ... |
免责声明:我是有关箱子的作者。
您可以使用
1 | let num: f64 = 12 as f64 ; |