You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Arduino Mega中Rust语言F32浮点数比较异常问题

AVR平台Rust代码中动态计算F32浮点数的比较异常问题

在Arduino Mega上基于Rust开发时,发现一个异常现象:通过加法或类型转换动态生成的F32浮点数,进行比较操作时结果完全错误;但直接使用固定字面量浮点数时,比较结果符合预期。

示例代码

#![no_std]
#![no_main]

use panic_halt as _;
use ufmt_float::uFmt_f32;

#[arduino_hal::entry]
fn main() -> ! {
    let dp = arduino_hal::Peripherals::take().unwrap();
    let pins = arduino_hal::pins!(dp);

    let mut serial = arduino_hal::default_serial!(dp, pins, 57600);
    
    loop {
        // let sample_rate = 280.0f32;
        let mut sample_rate = 100.0f32;
        for _ in 1..10 {
            sample_rate = sample_rate + 20.0f32;
        }
        
        let sample_rate_formatted = uFmt_f32::Five(sample_rate);

        ufmt::uwriteln!(&mut serial, "Sample rate: {}", sample_rate_formatted).unwrap();

        ufmt::uwriteln!(&mut serial, "sample_rate.to_bits() : {}",sample_rate.to_bits()).unwrap();
        ufmt::uwriteln!(&mut serial, "sample_rate.is_sign_negative() : {}",sample_rate.is_sign_negative()).unwrap();
        ufmt::uwriteln!(&mut serial, "sample_rate.is_sign_positive() : {}",sample_rate.is_sign_positive()).unwrap();
        ufmt::uwriteln!(&mut serial, "sample_rate.is_nan() : {}",sample_rate.is_nan()).unwrap();
        ufmt::uwriteln!(&mut serial, "sample_rate.is_finite() : {}",sample_rate.is_finite()).unwrap();
        ufmt::uwriteln!(&mut serial, "sample_rate.is_infinite() : {}",sample_rate.is_infinite()).unwrap();
        ufmt::uwriteln!(&mut serial, "sample_rate.is_normal() : {}",sample_rate.is_normal()).unwrap();
        ufmt::uwriteln!(&mut serial, "sample_rate.is_subnormal() : {}",sample_rate.is_subnormal()).unwrap();

        ufmt::uwriteln!(&mut serial, "sample_rate.lt(0.0) : {}", sample_rate.lt(&0.0)).unwrap();
        ufmt::uwriteln!(&mut serial, "sample_rate.gt(0.0) : {}", sample_rate.gt(&0.0)).unwrap();
        ufmt::uwriteln!(&mut serial, "sample_rate.eq(0.0) : {}", sample_rate.eq(&0.0)).unwrap();
        ufmt::uwriteln!(&mut serial, "sample_rate.lt(0.1) : {}", sample_rate.lt(&0.1)).unwrap();
        ufmt::uwriteln!(&mut serial, "sample_rate.gt(0.1) : {}", sample_rate.gt(&0.1)).unwrap();
        ufmt::uwriteln!(&mut serial, "sample_rate.eq(0.1) : {}", sample_rate.eq(&0.1)).unwrap();
        ufmt::uwriteln!(&mut serial, "sample_rate.lt(-0.1) : {}", sample_rate.lt(&-0.1)).unwrap();
        ufmt::uwriteln!(&mut serial, "sample_rate.gt(-0.1) : {}", sample_rate.gt(&-0.1)).unwrap();
        ufmt::uwriteln!(&mut serial, "sample_rate.eq(-0.1) : {}", sample_rate.eq(&-0.1)).unwrap();
        

        loop {

        }
    }

}

动态计算时的错误输出

Sample rate: 280.00000
sample_rate.to_bits() : 1133248512
sample_rate.is_sign_negative() : false
sample_rate.is_sign_positive() : true
sample_rate.is_nan() : false
sample_rate.is_finite() : true
sample_rate.is_infinite() : true
sample_rate.is_normal() : false
sample_rate.is_subnormal() : false
sample_rate.lt(0.0) : false
sample_rate.gt(0.0) : false
sample_rate.eq(0.0) : true
sample_rate.lt(0.1) : false
sample_rate.gt(0.1) : false
sample_rate.eq(0.1) : true
sample_rate.lt(-0.1) : false
sample_rate.gt(-0.1) : false
sample_rate.eq(-0.1) : true

使用字面量时的正确输出

取消注释代码中的let sample_rate = 280.0f32;并注释动态计算部分后,得到正常输出:

Sample rate: 280.00000
sample_rate.to_bits() : 1133248512
sample_rate.is_sign_negative() : false
sample_rate.is_sign_positive() : true
sample_rate.is_nan() : false
sample_rate.is_finite() : true
sample_rate.is_infinite() : false
sample_rate.is_normal() : false
sample_rate.is_subnormal() : false
sample_rate.lt(0.0) : false
sample_rate.gt(0.0) : true
sample_rate.eq(0.0) : false
sample_rate.lt(0.1) : false
sample_rate.gt(0.1) : true
sample_rate.eq(0.1) : false
sample_rate.lt(-0.1) : false
sample_rate.gt(-0.1) : true
sample_rate.eq(-0.1) : false

已尝试的解决方法

  • 截取浮点数的截断值
  • 将系统默认的avr-gcc 5.4.0升级为avr-gcc-12

项目Cargo.toml配置

[package]
name = "f32demo"
version = "0.1.0"
authors = ["thefoxrhythm"]
edition = "2021"
license = "MIT OR Apache-2.0"

[[bin]]
name = "f32demo"
test = false
bench = false

[dependencies]
panic-halt = "0.2.0"
ufmt = "0.2.0"
nb = "0.1.2"
embedded-hal = "0.2.3"
ufmt_float ="0.2.0"

[dependencies.avr-device]
version = "0.5.0"
features = ["atmega2560"]

[dependencies.arduino-hal]
git = "https://github.com/rahix/avr-hal"
rev = "4c9c44c314eb061ee20556ef10d45dea36e75ee4"
features = ["arduino-mega2560"]

# Configure the build for minimal size - AVRs have very little program memory
[profile.dev]
panic = "abort"
lto = true
opt-level = "s"

[profile.release]
panic = "abort"
codegen-units = 1
debug = true
lto = true
strip = true
opt-level = 1

内容的提问来源于stack exchange,提问作者Melody Fox

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 00:12:18