<rust>在rust中,实现32位浮点数与16进制之间的转换

前言

本文是基于rust,对16进制、32位浮点数之间的互相转换的一个简单示例。

环境配置

系统:windows

平台:visual studio code

语言:rust

库:hex

关键依赖

rust 复制代码
hex="0.4.3"

对于字符串与16进制之间的互相转换,我们使用hex这个crate。所以需要添加hex依赖,在toml文件中手动添加,如上,或者使用cargo添加:
cargo add hex

也可以指定版本:
cargo add [email protected]

数字字符串转字节数组

为了方便管理,我们可以新建一个rust文件,命名为hexconvert.rs。然后我们在其中编写功能函数,首先是string_to_hex:

rust 复制代码
///
/// 字符串转16进制
/// 
/// 例:'01030002' -> [0x01,0x03,0x00,0x02]
pub fn string_to_hex(s:String) -> Vec<u8> {
    let input_re=hex::decode(s);
    if let Ok(input_hex) = input_re{
        return  input_hex
    } else {
        return vec![]
    }
}

hex的函数decode的作用是解码字符串,将对应的数字字符串解码为字节数组,字节数组就是我们所需要的原始数据,可以显示为各种进制的数值,当然也包括16进制。

字节数组转32位浮点数

rust中有自带的处理数值的函数,对于32位浮点数即f32数值类型,可以使用from_be_bytes或者from_le_bytes来从字节数组转换。

rust 复制代码
///
/// 16进制转32位浮点数
/// 
/// Example 1:  
/// 
/// [0x41,0x48,0x00,0x00] -> 12.5(mode is "big endian")
/// 
/// [0x00,0x00,0x48,0x41] -> 12.5(mode is "little endian")
/// 
/// Example 2:
/// 
/// [0x41,0x48,0x00,0x00,...] -> ???(长度判断)
/// 
/// 
pub fn hex_to_float_frombytes<T: AsRef<[u8]>>(hex: T, mode: Option<&str>) -> Option<f32> {
    let bytes = hex.as_ref();
    if bytes.len() == 4 {
        let mut array = [0u8; 4];
        array.copy_from_slice(bytes);
        match mode.unwrap_or("big") {
            "big" => Some(f32::from_be_bytes(array)),
            "little" => Some(f32::from_le_bytes(array)),
            _ => {
                Some(f32::from_ne_bytes(array))
            }
        }
    } else {
        println!("err:数组长度异常");
        None
    }
}

在上面的函数中,我们对传入的字节数组进行了简单判断,因为32位浮点数,长度是4个字节,所以字节长度如果不对,那么转换的数值显然也是错误的。另外,不同的终端控制器或者发送设备,其字节端序也不一定一样,有大端和小端之分,即big endian和little endian,也就是be和le。

所以,我们还添加了一个mode参数,用于判断端序。

浮点数转字符串

将一个浮点型数值转为等值的字符串或者16进制字符串,我们可以使用hex的encode函数。

rust 复制代码
///
/// 32位浮点数转字符串
/// 
/// 例:12.5 -> "12.5"(to_hex is false)
/// 
/// 例:12.5 -> "0x41,0x48,0x00,0x00"(to_hex is true)
#[allow(unused)]
pub fn float_to_string(f:f32,mode:Option<&str>,to_hex:bool) -> String {
    let mut s:String=String::new();
    if to_hex == false {
        s=format!("{}",f)
    } else {
        match mode.unwrap_or("big") {
            "big" => {
                let hex=hex::encode(f.to_be_bytes());
                s=format!("{}",hex)
            },
            "little" => {
                let hex=hex::encode(f.to_le_bytes());
                s=format!("{}",hex)
            },
            _ => {
                let hex=hex::encode(f.to_ne_bytes());
                s=format!("{}",hex)
            }
        }
    }
    
    return s
}

此处我们增加了to_hex来选择是直接转为等值字符还是转为等值16进制字符。

下面是一个实例演示,我们将通过终端输入一个字符串:00004841,这是小端序的浮点数:12.5。

我们使用小端序解码,然后是大端序再转会字符串,看看效果:

rust字符串与字节数组转换演示

相关推荐
六bring个六21 分钟前
文件系统交互实现
开发语言·c++·qt·交互
jingyu飞鸟27 分钟前
Centos7系统(最小化安装)安装zabbix7版本详细文章、nginx源代码配置、php源代码、mysql-yum安装
开发语言·php
dhxhsgrx36 分钟前
PYTHON训练营DAY27
开发语言·python
小山菌36 分钟前
mac中加载C++动态库文件
开发语言·c++·macos
獨枭1 小时前
使用 163 邮箱实现 Spring Boot 邮箱验证码登录
java·spring boot·后端
维基框架1 小时前
Spring Boot 封装 MinIO 工具
java·spring boot·后端
秋野酱1 小时前
基于javaweb的SpringBoot酒店管理系统设计与实现(源码+文档+部署讲解)
java·spring boot·后端
关于不上作者榜就原神启动那件事1 小时前
Java基础学习
java·开发语言·学习
橙子199110161 小时前
在 Kotlin 中,什么是解构,如何使用?
android·开发语言·kotlin
☞无能盖世♛逞何英雄☜1 小时前
Flask框架搭建
后端·python·flask