rust 从标准正态分布生成随机浮点数并乘以另一个浮点数

nvbavucw  于 2022-12-23  发布在  其他
关注(0)|答案(1)|浏览(168)

尝试从标准正态分布生成一个随机数。需要将值乘以0.1以获得我正在寻找的数字范围。我尝试使用rand_dist的文档,您可以在这里找到:https://docs.rs/rand_distr/0.3.0/rand_distr/struct.StandardNormal.html
我的货物. toml如下:

[package]
name = "test_rng"
version = "0.1.0"
authors = ["Jack"]
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
rand = "0.7.3"
rand_distr = "0.3.0"

起始rust代码是上述rand_dist文档中提供的示例:

use rand::prelude::*;
use rand_distr::StandardNormal;

fn main() {
    let val: f64 = thread_rng().sample(StandardNormal);
    println!("{}", val);
}

当我运行这个程序时,它按预期工作,输出为:

C:\Users\Jack\Desktop\projects\software\rust\test_rng>cargo run
   Compiling test_rng v0.1.0 (C:\Users\Jack\Desktop\projects\software\rust\test_rng)
    Finished dev [unoptimized + debuginfo] target(s) in 2.11s
     Running `target\debug\test_rng.exe`
0.48398855288705356

C:\Users\Jack\Desktop\projects\software\rust\test_rng>

这就是我遇到问题的地方,当我在下面的代码中尝试将该数字乘以0.1时,我得到了结果错误:
一个三个三个一个
我尝试将0.1更改为0.1_f64,但出现了相同的错误。我尝试使用as f64将随机数转换为f64(它应该已经是),但结果如下:

fn main() {
    let val: f64 = 0.1 * thread_rng().sample(StandardNormal) as f64;
    println!("{}", val);
}
C:\Users\Jack\Desktop\projects\software\rust\test_rng>cargo run
   Compiling test_rng v0.1.0 (C:\Users\Jack\Desktop\projects\software\rust\test_rng)
error[E0282]: type annotations needed
 --> src\main.rs:5:39
  |
5 |     let val: f64 = 0.1 * thread_rng().sample(StandardNormal) as f64;
  |                                       ^^^^^^ cannot infer type for type parameter `T` declared on the associated function `sample`
  |
  = note: type must be known at this point
help: consider specifying the type arguments in the method call
  |
5 |     let val: f64 = 0.1 * thread_rng().sample::<T, D>(StandardNormal) as f64;
  |                                             ^^^^^^^^

error: aborting due to previous error

For more information about this error, try `rustc --explain E0282`.
error: could not compile `test_rng`.

To learn more, run the command again with --verbose.

C:\Users\Jack\Desktop\projects\software\rust\test_rng>

认为这是一个优先级问题,所以我尝试将后半部分用括号括起来,但得到了同样的错误。
我可以通过使变量可变并将行分成如下两个操作来使它工作:

fn main() {
    let mut val: f64 = thread_rng().sample(StandardNormal);
    val *= 0.1;
    println!("{}", val);
}
C:\Users\Jack\Desktop\projects\software\rust\test_rng>cargo run
   Compiling test_rng v0.1.0 (C:\Users\Jack\Desktop\projects\software\rust\test_rng)
    Finished dev [unoptimized + debuginfo] target(s) in 1.62s
     Running `target\debug\test_rng.exe`
-0.034993448117065

C:\Users\Jack\Desktop\projects\software\rust\test_rng>

知道f64与随机数的输出相乘是怎么回事吗?

cngwdvgl

cngwdvgl1#

您可以使用以下方法:

fn main() {
    let val: f64 = 0.1 * thread_rng().sample::<f64,_>(StandardNormal);
    println!("{}", val);
}

这显式地强制sample函数返回f64,可能的原因是rust类型推断没有意识到RHS必须是f64,尽管我不确定确切的原因。
编辑:我认为这要归咎于sample的定义,因为它使用了一个不受限制的类型参数。

pub trait Marker{}

impl Marker for f64{}
impl Marker for f32{}

fn does_not_work<T>() -> T{
    unimplemented!()
}

fn does_work<T: Marker>() -> T{
    unimplemented!()
}

fn main() {
    let val: f64 = 0.1 * does_work();
    let val: f64 = 0.1 * does_not_work();
}

编译器不能推断does_not_work的类型是可以理解的,b/c知道每一个可能与f64相乘的类型意味着什么?然而,如果我们将事情限制在只有某些具有trait的类型,那么可能的类型列表就变得有限,类型推断又可以工作了。

相关问题