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

能否用float类型存储millis()函数返回值?附代码咨询

关于使用float存储millis()返回值的可行性咨询

我想咨询是否可以如代码中所示,使用float数据类型存储millis()函数的返回值。我了解通常会用unsigned int类型来存储,但由于需要将millis()返回的毫秒值转换为小时,因此尝试用float存储,附上相关C++代码,不确定这样是否可行。

#include<Servo.h>
#include<math.h>
Servo mark1;
float dur = 2.30, del_dur = 0 ;
float sys_strt = (millis()/3600000), curr_tim = (millis()/3600000), del_strt = 0;
float inc_val;
const int relay_on = 8;

//2, output = 9;

void setup()
{
    digitalWrite(8, HIGH);
    mark1.attach(9);
    mark1.write(110);//servo on
    Serial.begin(9600);
    // pinMode(switch_on, INPUT);
    // pinMode(output, OUTPUT);
}


void loop()
{
    if(Serial.available() > 0)
    { 
        inc_val = Serial.read();
        Serial.print("\n");
        
        if(inc_val == 'D') // D = DURATION
        {
            delay(2000); 
            dur = Serial.read();
            sys_strt = (millis()/3600000);
            //mark1.write(on);
        }
        
        else if(inc_val == 'd') // d = delay_duration_for_future_turn_on
        {
            mark1.write(158);// servo off
            delay(2000);
            del_dur = Serial.read();
            Serial.print("\n");
            delay (5000);
            dur = (Serial.read() + del_dur);
            del_strt = (curr_tim + del_dur);
            sys_strt = del_strt;
            //curr_tim = (millis()/1000);
        } 
    }  
    if((millis()/3600000) >= 5)
    {
        digitalWrite( 8, LOW);
    }
         
    if(((millis()/3600000) - del_strt) >= 0 && ((millis()/3600000) - del_strt) <=10 )    // statement for delay duration process
    {
        mark1.write(110);// servo on
    }
         
    if(((millis()/3600000)-sys_strt) >= dur)
    {
        mark1.write(158);//servo off
    }    
}

可行性分析与建议

可以用float存储millis()返回值,但不推荐,核心问题是精度丢失:

  • millis()返回的是unsigned long类型(4字节,最大约49.7天的毫秒数),而32位单精度float的整数精度只能精确到2^24(约1677万毫秒,对应4.66小时)。当系统运行时间超过这个阈值后,float无法精确表示所有整数毫秒值,会导致时间计算出现误差,且误差会随时间累计。
  • 代码中millis()/3600000是整数除法,会先将毫秒数截断为整数小时再转float,进一步放大精度损失。正确的转换方式应为先转float再计算:(float)millis() / 3600000.0f。

更优方案:
保留unsigned long存储原始毫秒值,仅在需要计算小时数时再转换为float:

// 存储原始毫秒值
unsigned long sys_strt = millis();
// 需要计算小时差时再转换
float hours_elapsed = (float)(millis() - sys_strt) / 3600000.0f;

这种方式既能保留时间的精确性,又能满足小时数的计算需求。

代码其他问题提示

  • dur = Serial.read();直接将读取的字符ASCII值赋值给float,比如输入'2'会得到50.0而非2.0,需转换为数值:dur = (Serial.read() - '0');,如果需要支持小数,还需处理多字符输入逻辑。
  • delay()会阻塞程序运行,导致millis()计时逻辑无法响应其他操作,建议改用非阻塞式计时(基于millis()差值判断)替代delay。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 03:10:56