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

Rust中如何将f64类型变量转换为usize类型?

Rust实现中位数计算:f64转usize问题及代码修复

核心问题:f64转usize的正确方式

Rust中f64没有直接的to_usize()方法,因为浮点数可能包含小数部分,转换时需要明确处理逻辑:

  • 若确定浮点数为整数(或需截断小数):直接用as转换,比如n as usize,但会直接丢弃小数部分。
  • 需安全转换(检查范围、是否为整数):可手动实现校验逻辑,示例:
fn f64_to_usize(n: f64) -> Result<usize, &'static str> {
    if n.is_nan() || n.is_infinite() {
        return Err("Invalid float value");
    }
    let n_int = n.round() as usize;
    if (n_int as f64) != n {
        return Err("Float is not an integer");
    }
    Ok(n_int)
}

不过在中位数计算场景中,完全不需要用浮点数计算索引,直接用整数除法更高效且避免转换问题,后续会详细说明。

代码中的其他问题及修复

1. 输入处理逻辑错误

输入"d"时,原代码中break会直接跳出循环,后续的打印和中位数计算代码永远不会执行,修复后:

// 原错误分支
Err(_) => if inp.trim() == String::from("q") {
    break;
} else if inp.trim() == String::from("d"){
    break
    {
        println!("Done!");
        calc_med();
    }
} else {
    continue;
}
// 修复后分支
Err(_) => {
    match inp.trim() {
        "q" => break,
        "d" => {
            println!("Done!");
            calc_med();
            break;
        }
        _ => continue,
    }
}

2. Mutex访问错误

v1是Mutex<Vec<f64>>,不能直接用v1[n2]访问元素,必须先获取锁的Guard:

// 原错误代码
let median: f64 = v1[n2];
// 修复后
let vec = v1.lock().unwrap();
let median = vec[n2];

3. 重复加锁降低性能

main函数中多次调用v1.lock().unwrap(),可合并为一次加锁,操作完成后自动释放:

// 原代码
v1.lock().unwrap().push(upd_inp);
v1.lock().unwrap().sort_by(|a, b| a.partial_cmp(b).unwrap());
// 修复后
let mut vec = v1.lock().unwrap();
vec.push(upd_inp);
vec.sort_by(|a, b| a.partial_cmp(b).unwrap());

4. 中位数计算逻辑错误

当前n = (len +1)/2的计算不符合中位数规则:

  • 列表长度为奇数时,中位数是中间位置元素,索引为len / 2(整数除法)
  • 列表长度为偶数时,中位数是中间两个元素的平均值:(v[len/2 -1] + v[len/2]) / 2.0

完全不需要用浮点数计算索引,直接用整数操作即可。

修正后的完整代码

use std::io;
use std::sync::Mutex;

#[macro_use]
extern crate lazy_static;

lazy_static! {
    static ref v1: Mutex<Vec<f64>> = Mutex::new(Vec::new());
}

fn main() {
    loop {
        println!("Enter a number, or 'q' to quit, 'd' to calculate median: ");

        let mut inp: String = String::new();

        io::stdin().read_line(&mut inp).expect("Failed to read input");
        
        let upd_inp: Result<f64, _> = inp.trim().parse();
        match upd_inp {
            Ok(num) => {
                let mut vec = v1.lock().unwrap();
                vec.push(num);
                vec.sort_by(|a, b| a.partial_cmp(b).unwrap());
                println!("Current list: {:?}", vec);
            }
            Err(_) => {
                match inp.trim() {
                    "q" => break,
                    "d" => {
                        println!("Done!");
                        calc_med();
                        break;
                    }
                    _ => {
                        println!("Invalid input, please enter a number or 'q'/'d'");
                        continue;
                    }
                }
            }
        };
    }
}

fn calc_med() {
    let vec = v1.lock().unwrap();
    let len = vec.len();
    if len == 0 {
        println!("List is empty, no median");
        return;
    }
    
    let median = if len % 2 == 1 {
        // 奇数长度,取中间元素
        vec[len / 2]
    } else {
        // 偶数长度,取中间两个的平均值
        (vec[len/2 - 1] + vec[len/2]) / 2.0
    };

    println!("Median: {}", median);
}

说明

  • 移除不必要的浮点数转换,用整数索引直接计算中位数,彻底避免f64转usize的问题
  • 修复输入处理逻辑错误,确保输入d时能正确触发中位数计算
  • 合并Mutex重复加锁操作,提升程序性能
  • 添加空列表的边界处理,避免索引越界

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 19:25:19