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

C语言中用float实现H.MMSS与十进制小时转换的问题排查

十进制小时与H.MMSS格式转换的float精度问题

我正在开发一组函数,用于在十进制小时(2小时30分钟为2.5小时)与H.MMSS格式(2.5小时表示为2.3000)之间进行转换。最初用double实现时一切正常,但嵌入式项目规模扩大后闪存不足,不得不改用float。

以下是复现问题的最小可执行示例(MWE):

#include <stdio.h>
#include <math.h>

float toHMS(float inputTime) {
    float hours = 0;
    float minutes = 0;
    float seconds = 0;
    // get integral part for the hours
    hours = (int)inputTime;
    // transform into decimal minutes
    inputTime -= hours;
    inputTime *= 60;
    // Get the minutes
    minutes = (int)inputTime;
    // Get the seconds
    inputTime -= minutes;
    seconds = (int)(100 * inputTime);
    return hours + minutes/100 + seconds/ 10000;
} 

float toHours (float inputTime) {
    float hours = 0;
    float minutes = 0;
    float seconds = 0;
    // get integral part for the hours
    hours = (int)inputTime;
    inputTime = 100 * (inputTime - hours);
    minutes = (int)inputTime;
    inputTime = inputTime - minutes;
    seconds = 100 * inputTime;
    // normalize to 60
    minutes = minutes / 60;
    seconds = seconds / 3600;
    return hours + minutes + seconds;
}

float toHours2 (float inputTime) {
    float hours = 0;
    float minutes = 0;
    float seconds = 0;
    // get integral part for the hours
    hours = (int)inputTime;
    inputTime = roundf(100 * (inputTime - hours));
    minutes = (int)inputTime;
    inputTime = inputTime - minutes;
    seconds = 100 * inputTime;
    // normalize to 60
    minutes = minutes / 60;
    seconds = seconds / 3600;
    return hours + minutes + seconds;
}

void main(void) {
    float hms = toHMS(2.5f);
    printf("toHMS(2.5f): %.9f\n", hms);
    printf("toHours(toHMS(2.5f)): %.9f\n", toHours(hms));
    printf("\n");
    printf("toHours(2.3f): %.9f\n", toHours(2.3f));
    printf("\n");
    printf("toHours2(2.3f): %.9f\n", toHours2(2.3f));
}

运行结果:

toHMS(2.5f): 2.299999952
toHours(toHMS(2.5f)): 2.511111021

toHours(2.3f): 2.511111021

toHours2(2.3f): 2.500000000

问题出在toHours()函数中,因为单精度float的2.3实际存储为2.299999952。在toHours2()中添加roundf()后问题得到解决,但不确定这是否是唯一所需的修复,是否存在其他输入会导致计算出错,无法证明该方案适用于所有情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 13:23:11