将数字基元(i32,f64等)转换为字节表示

问题描述 投票:18回答:5

我正在编写一个库,用于对二进制格式的数据进行编码/解码。部分格式是数字,我正在使用Rust的原生原始类型(如i8i64f32等)。

是否有一种简单的内置方法可以将这些数据类型转换为二进制数据,即转换为f64 / f32 / i64 /等。成为Vec<u8>?同样有没有办法将4个u8s(在Vec<u8>中说)转换为f32

types rust
5个回答
19
投票

不幸的是,目前还没有安全的内置支持从Rust中读取/写入一个字节数组的原语。有几个社区库,但是,byteorder是最常用的:

extern crate byteorder;

use byteorder::{LittleEndian, WriteBytesExt};
use std::mem;

fn main() {
    let i: i64 = 12345;
    let mut bs = [0u8; mem::size_of::<i64>()];
    bs.as_mut()
        .write_i64::<LittleEndian>(i)
        .expect("Unable to write");

    for i in &bs {
        println!("{:X}", i);
    }
}

当然,你总是可以投射原始指针。例如,您可以将*const i64转换为*const i8,然后将其转换为适当的字节切片&[u8]。但是,由于endiannness,这很容易出错,unsafe和平台依赖,所以它应该只作为最后的手段使用:

use std::{mem, slice};

fn main() {
    let i: i64 = 12345;
    let ip: *const i64 = &i;
    let bp: *const u8 = ip as *const _;
    let bs: &[u8] = unsafe { slice::from_raw_parts(bp, mem::size_of::<i64>()) };

    for i in bs {
        println!("{:X}", i);
    }
}

14
投票

可以使用std::mem::transmute,虽然它是unsafe

fn main() {
    let var1 = 12345678_i64;
    let raw_bytes: [i8; 8] = unsafe { std::mem::transmute(var1) };
    for byte in &raw_bytes {
        println!("{}", byte);
    }
}

注意:请确保两个变量的大小完全相等。


10
投票

从Rust 1.32开始,你可以使用{to,from}_{ne,le,be}_bytes作为整数类型。

let begin = 1234_i32;
let bytes = begin.to_ne_bytes();
let and_back = i32::from_ne_bytes(bytes);

对于浮点数,您仍然需要依赖于先前的方法。


3
投票

建立Nicholas Rishel's answer

Rust 1.32有:{to,from}_{ne,le,be}_bytesto_bitsfrom_bits

将整数转换为字节然后返回:

let x = 65535_i32;
let x_bytes = x.to_ne_bytes();                  // x_bytes = [255, 255, 0, 0]
let original_x = i32::from_ne_bytes(x_bytes);   // original_x = 65535 = x

将float转换为字节然后返回:

let y = 255.255_f64;
let y_bytes = y.to_bits().to_ne_bytes();
let original_y = f64::from_bits(u64::from_ne_bytes(y_bytes)); // original_y = 255.255 = y

根据Rust文档,from_bits可以有portability issues


-1
投票

如果您的目标是打印字节或将它们放在str表示中,只需在格式括号中使用:b表示法

fn main() {
    println!("This is the binary of int {:b}", 4 as i32);
}

这打印

This is the binary of int 100

© www.soinside.com 2019 - 2024. All rights reserved.