[英]value of f32::NAN rust closure for omitting 'NaN' values
I have the following closure. 我有以下关闭。
let ss = aa.iter().fold(0., |sum: f32,x| if *x != f32::NAN { sum + e } else { sum + 0. })
I am trying to sum all the values omitting f32::NAN
if any in the vector(I have couple of NaN
values in the vector). 我试图对所有省略向量f32::NAN
的值求和(如果向量中有几个NaN
值)。
But, My return gives me NaN
value because my condition if *x != f32::NAN
does not seem to be valid. 但是,我的返回给了我NaN
值,因为if *x != f32::NAN
条件似乎无效, if *x != f32::NAN
我的条件。 Because, the following closure yields the original vector instead of omitting NaN
value. 因为,以下闭包将产生原始向量,而不是忽略NaN
值。
let bb = aa.iter().filter(|x| **x != f32::NAN).map(|x| x)
My question is, how do I match f32::NAN
value in a if
condition? 我的问题是,如何在if
条件下匹配f32::NAN
值? In a broader perspective, How do I omit NaN
values in a vector? 从更广泛的角度来看,如何在向量中忽略NaN
值?
You cannot check for NaN that way, since NaN == NaN
evaluates to false
. 您不能以这种方式检查NaN,因为NaN == NaN
值为false
。 Use f32::is_nan
instead. 使用f32::is_nan
代替。 Furthermore, you can use Iterator::filter
to filter out elements of an iterator and Iterator::sum
to sum all values. 此外,您可以使用Iterator::filter
过滤掉迭代器的元素,并使用Iterator::sum
求和所有值。
This results in this code ( Playground ): 这将产生以下代码( Playground ):
let aa = [3.14f32, std::f32::NAN, 2.71, 27.99];
let ss = aa.iter()
.filter(|n| !n.is_nan())
.sum::<f32>();
println!("{}", ss);
With the right directional help of Warren Weckesser
Managed to make the closure work. 在Warren Weckesser
的正确指导下, Warren Weckesser
使封堵工作。
Here is the solution for those who might need. 这是针对可能需要的人的解决方案。
let ss = aa.iter().fold(0., |sum: f32, x| if x.is_nan() { sum + 0. } else { sum + x });
Alternatively, 或者,
let ss = aa.iter().fold(0., |sum: f32, x| if x.is_nan() { sum } else { sum + x });
if one cares about a unnecessary +
operation. 如果有人关心不必要的+
操作。
Performance Comparison 性能比较
extern crate rand;
use rand::Rng;
fn main() {
let mut a [f32; 1000] = [0.; 1000];
for i in 0..1000 {
a[i] = rand::thread_rng().gen_range(1,11);
}
}
Approach-I: 方法-I:
let ss = a.iter()
.filter(|n| !n.is_nan())
.sum::<f32>();
Callgrind Callgrind
>> cargo profiler callgrind -n 10
Compiling playground in debug mode...
Profiling playground with callgrind...
Total Instructions...3,959,454
177,532 (4.5%) isaac64.rs:rand::prng::isaac64::Isaac64Rng::isaac64
-----------------------------------------------------------------------
121,742 (3.1%) memmove-vec-unaligned-erms.S:memcpy@GLIBC_2.2.5
-----------------------------------------------------------------------
104,224 (2.6%) dl-lookup.c:do_lookup_x
-----------------------------------------------------------------------
102,982 (2.6%) ptr.rs:core::ptr::swap_nonoverlapping_one
-----------------------------------------------------------------------
99,660 (2.5%) intrinsics.rs:core::intrinsics::copy_nonoverlapping
-----------------------------------------------------------------------
76,555 (1.9%) strcmp.S:strcmp
-----------------------------------------------------------------------
72,997 (1.8%) local.rs:_..std..thread..local..LocalKey..T....::try_with
-----------------------------------------------------------------------
72,063 (1.8%) ptr.rs:_..core..ptr..NonNull..T....::as_ref
-----------------------------------------------------------------------
70,028 (1.8%) rc.rs:alloc::rc::RcBoxPtr::strong
-----------------------------------------------------------------------
62,000 (1.6%) ptr.rs:core::ptr::swap_nonoverlapping_one
-----------------------------------------------------------------------
Approach-II: 方法-II:
let ss = a.iter()
.fold(0., |sum: f32, x| if x.is_nan() { sum } else { sum + x });
Callgrind Callgrind
>> cargo profiler callgrind -n 10
Compiling playground in debug mode...
Profiling playground with callgrind...
Total Instructions...3,938,312
177,532 (4.5%) isaac64.rs:rand::prng::isaac64::Isaac64Rng::isaac64
-----------------------------------------------------------------------
121,766 (3.1%) memmove-vec-unaligned-erms.S:memcpy@GLIBC_2.2.5
-----------------------------------------------------------------------
104,224 (2.6%) dl-lookup.c:do_lookup_x
-----------------------------------------------------------------------
102,982 (2.6%) ptr.rs:core::ptr::swap_nonoverlapping_one
-----------------------------------------------------------------------
99,660 (2.5%) intrinsics.rs:core::intrinsics::copy_nonoverlapping
-----------------------------------------------------------------------
76,555 (1.9%) strcmp.S:strcmp
-----------------------------------------------------------------------
72,997 (1.9%) local.rs:_..std..thread..local..LocalKey..T....::try_with
-----------------------------------------------------------------------
72,063 (1.8%) ptr.rs:_..core..ptr..NonNull..T....::as_ref
-----------------------------------------------------------------------
70,028 (1.8%) rc.rs:alloc::rc::RcBoxPtr::strong
-----------------------------------------------------------------------
62,000 (1.6%) ptr.rs:core::ptr::swap_nonoverlapping_one
-----------------------------------------------------------------------
Looking at the Total Instructions , Approach-II fares well in terms of run-time performance with ~20,000
instructions less than Approach-I for 1000
element array. 从总指令来看,对于1000
元素数组, 方法II在运行时性能方面要好得多,比方法I少~20,000
条指令。 Anticipating this difference will positively translate in to enhanced run-time performance for Approach-II . 预期这种差异将积极地转化为方法II的增强的运行时性能。 Investigating, from where the difference stem from. 调查,差异源自何处。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.