首页 > 解决方案 > 为 f64 设置查找表的最佳方法

问题描述

我有一个函数多次使用 ln(i),其中 i 是 u32。在此函数中,我在该函数中创建了一个向量,该向量设置为

let mut lns = vec![0.0f64; 2 as usize] ;
for i in 2 ..= max_ln as usize {
    lns.push((i as f64).ln()) ;
}

前两个条目是 0.0,因此当我需要 ln(i) 时,我不需要继续调用 lns(i-1)。无论如何,这会在每次调用我的函数时完成。我只是想知道是否有一种方法可以生成一次并重用它(如果 max_ln 在调用之间发生变化,可以选择推送额外的值)。到目前为止,我想出的唯一选择是

const LNS: [f64; 128] = [0.0f64,
                        0.0f64,
                        0.693147180559945f64,
                        1.09861228866811f64,
                        1.38629436111989f64,
                        1.6094379124341f64,
                        1.79175946922805f64,

等在文件的顶部,但这并不理想,因为我需要用常量值而不是调用 ln() 来初始化它。

我见过类似的情况,人们使用 Lazy_Static 板条箱,但希望更简单一些,因为个人价值观永远不会改变。

谢谢

标签: rustlookup-tables

解决方案


我最终遵循了 kmdreko 的建议,但细节并没有立即清楚,所以一旦我知道去哪里看,在对 rust 文档进行了一些后续阅读之后,这就是最终为我工作的方法。

在项目的根目录下,

//build.rs
use std::io::{Result, Write} ;
use std::path::Path ;
use std::fs::File ;
use std::env ;

const MAX: usize = 128 ;

fn main() -> Result<()> {
    let out_dir = env::var("OUT_DIR").unwrap() ;
    let dest_path = Path::new(&out_dir).join("ln_int_const.rs") ;
    let mut f = File::create(&dest_path).unwrap() ;

    write!(f, "const BIGLNS: [f64; {}] = [\n",MAX+1)? ;
    write!(f, "  0.0f64,\n")? ;
    write!(f, "  0.0f64,\n")? ;
    for i in 2..=MAX {
        write!(f, "  {}f64,\n", (i as f64).ln())? ;
    }
    write!(f, "];\n")? ;

    Ok(())
}

然后,为了得到这个加载,需要在主文件的顶部添加一些代码:

//src/main.rs
...
include!(concat!(env!("OUT_DIR"), "/ln_int_const.rs")) ;

fn main() {
...

我没有意识到 build.rs 文件有多么强大。谢谢你的提示。


推荐阅读