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

Lua数字比较返回错误结果:Hammerspoon定时器逻辑异常

浮点数精度问题导致Hammerspoon定时器无法正确停止

你遇到的问题核心是浮点数精度误差:Lua使用双精度浮点数存储数值,而0.1这类十进制小数无法被二进制浮点数精确表示。每次执行i = i + .1时,都会积累微小的误差,最终i的实际值会是类似4.999999999999999或5.000000000000001的数值,和整数5直接用==比较自然会返回false——哪怕5 == 5.0本身是成立的。

修复方案1:用整数计数彻底规避浮点数问题

既然定时器每次触发间隔是0.1秒,总时长5秒,那总触发次数就是50次,用整数计数可以完全避免精度问题:

local function startTimer()
  local totalTicks = 50 -- 5秒 ÷ 0.1秒/次 = 50次
  local i = 0
  local function onTimeout()
    i = i + 1
    local stopTimer = i == totalTicks
    print('stopTimer:', stopTimer)
    print(i, totalTicks, type(i), type(totalTicks))
    if stopTimer then 
      timer:stop()
    end
  end
  local timer = hs.timer.new(.1, onTimeout)
  timer:start()
end

修复方案2:用近似相等判断

如果必须保留秒数累加的逻辑,可以通过判断两个数值的差值绝对值是否小于一个极小值(比如1e-9)来近似判断相等:

local function startTimer()
  local totalSeconds = 5
  local i = 0
  local function onTimeout()
    i = i + .1
    -- 当差值小于1e-9时,认为两个数值相等
    local stopTimer = math.abs(i - totalSeconds) < 1e-9
    print('stopTimer:', stopTimer)
    print(i, totalSeconds, type(i), type(totalSeconds), 5 == 5.0)
    if stopTimer then 
      timer:stop()
    end
  end
  local timer = hs.timer.new(.1, onTimeout)
  timer:start()
end

两种方案里,方案1的可靠性更高,完全规避了浮点数带来的精度风险;方案2适合需要直接处理秒数的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 05:32:31