将大浮点数转换为整数索引时,矢量索引"超出范围"

loc*_*kie 1 rust

我一直在尝试使用以下函数在m和n之间生成素数:

//the variable sieve is a list of primes between 1 and 32000
//The primes up to 100 are definitely correct
fn sieve_primes(sieve: &Vec<usize>, m: &usize, n: &usize) -> Vec<usize> {
    let size: usize = *n - *m + 1;
    let mut list: Vec<usize> = Vec::with_capacity(size);

    for i in *m..(*n + 1) {
        list.push(i);
    }   
    for i in sieve {
        for j in ( ((*m as f32) / (*i as f32)).ceil() as usize)..( (((*n as f32) / (*i as f32)).floor() + 1.0) as usize) {
                println!("{} ",j);
                if j != 1 {list[i * j - *m] = 0;} 
        }
    }   

    let mut primes: Vec<usize> = Vec::new();
    for num in &list{
        if *num >= 2 {primes.push(*num);}
    }   
    primes
}
Run Code Online (Sandbox Code Playgroud)

这适用于m和n的较小(小于1000000-ish)值,但在运行时它对于数十亿/数百万的数字失败.

m = 99999999,n = 100000000的输出为:

33333334
线程''惊慌失措'指数超出界限:len为2但指数为3'

如果你看一下数字,这没有任何意义.首先,它似乎跳过素数列表中的数字2.其次,当i = 3时,for语句应该简化为for j in 33333333..333333334,由于某种原因,它开始于33333334.

sta*_*lue 7

f32只能完全代表所有24位整数,相当于大约1600万(实际上是16777216).除此之外还有差距,最高可达33554432,只能表示偶数.因此,在您的示例中,33333333无法表示为f32并且舍入为33333334.

您不需要使用float来舍入整数除法的结果.直接使用整数既快又没有精度问题.对于非负整数,您可以执行以下操作:

fn main() {
    let a = 12;
    let b = 7;
    println!("rounded down: {}", a / b);
    println!("rounded:      {}", (a + b / 2) / b);
    println!("rounded up:   {}", (a + b - 1) / b);
}
Run Code Online (Sandbox Code Playgroud)