Cast &[f64] to &[f32]

If I have a slice of f64, what’s the best way to get a slice of f32 from that?

I guess there’s actually two use cases:

1. Where the size is unknown and I’ll need to get an intermediate Vec

If that’s the situation, is something like this the best way to do it?

let foo:Vec<f32> = values.iter().map(|n| *n as f32).collect();

2. Where the size is known

In this case, is there some sort of “memcpy with casting” builtin that lets me write to a stack-allocated array?

For example, instead of manually writing this:

let foo:[f32;4] = [
        values[0] as f32,
        values[1] as f32,
        values[2] as f32,
        values[3] as f32,
];

Building arrays with only std constructs is a bit unpleasant currently, in large part due to the absence of const generics (which are being worked on!). You may want to look into helper crates like stackvec and arrayvec which make the job easier, given the usual limitation to small arrays only.

3 Likes

Well, if you don’t mind some self-promotion, with https://docs.rs/arraytools/0.1.5/arraytools/trait.ArrayTools.html#method.map it’s

use arraytools::ArrayTools;
let foo = values.map(|x| x as f32);

assuming that values is an [f64; 4].

(Hopefully we’ll get something like this in core as const generics stabilize.)

3 Likes

hey scott,

i haven’t looked into your crate, but can you tell me how this solution is different from

// untested
values.iter().map(|n| n as f32).collect()

edit: ah, i think i get it, ArrayTools produces an array, and collect produces a Vec.

You cannot (infaillibly) collect an iterator into an array because the number of items which the iterator will produce is not known in advance and may be less than the size of the array.

Faillible collection is not provided by std yet, because it can’t be implemented in a general way yet due to lack of const generics. But the functionality is provided for small arrays by helper crates like stackvec.

Another track which I’m currently exploring is to provide a special kind of iterator that knows its length at compile-time.

1 Like

Yup! That’s right.

1 Like

If values is a Vec<f64> - don’t really have much of a choice right, gotta do it the manual one-at-a-time way?