【问题标题】:Math.trunc() not rounding values properlyMath.trunc() 没有正确舍入值
【发布时间】:2021-10-20 17:28:17
【问题描述】:

我知道在 JavaScript 中肯定有更好的方法来做到这一点,但我只是在做一些我知道的事情。我正在做另一个 Code Wars 挑战,我应该得到 12:34:55 时似乎得到了 12:34:56

对于挑战,函数以仅几秒的格式输入,例如。 86399,然后输出应该是人类可读的格式。

我真的不知道这里出了什么问题,我觉得这与 Math.trunc() 有关,因为我的数学是有道理的。

我会解释数学,但它在代码中很容易解释。唯一的问题似乎是秒数。

function humanReadable(seconds) {
    const hour = Math.trunc((seconds / 60) / 60);
    const mins = Math.trunc((((seconds / 60) / 60) - hour) * 60); 
    const secs = Math.trunc(((seconds / 60) - Math.trunc(seconds / 60)) * 60);

    return `${hour < 10 ? `0${hour}` : hour}:${mins < 10 ? `0${mins}` : mins}:${secs < 10 ? `0${secs}` : secs}`
}

【问题讨论】:

  • 你应该只截断除法的结果,而不是在相乘之后。
  • 肯定有更好的方法,你应该使用模数来获得每次除法后的余数。
  • 24 小时有 86400 秒 - 我希望结果是 23:59:59。你得到的原始价值是什么?

标签: javascript math truncate


【解决方案1】:

您应该尝试使用模数来获得每个数字除法后的余数,如下面的代码 sn-p 所示。

let d = 86399;
var h = Math.floor(d / 3600);
var m = Math.floor(d % 3600 / 60);
var s = Math.trunc(d % 60);
var result = `${h < 10 ? `0${h}` : h}:${m < 10 ? `0${m}` : m}:${s < 10 ? `0${s}` : s}`
console.log(result);

【讨论】:

  • d % 3600 % 60 ???真的???你知道那只是d % 60
【解决方案2】:

问题是由于浮点数不能准确表示数字

在 45296 的情况下 - 即 12:34:56

A: seconds / 60                    = 754.9333333333333
B: Math.trunc(seconds / 60)        = 754
A - B (should be 0.9333333333333)  =   0.9333333333332803

你可以看到,它比它应该的要少,但即使 0.9333333333333 * 60 也是 55.999999999998 ...截断它,你会得到 55

修复它的一种方法是

const secs = Math.round(((seconds / 60) - Math.trunc(seconds / 60)) * 60);

也许还有

const mins = Math.trunc((((seconds / 60) / 60) - hour) * 60); 

有超过 600 次会议记录“失败”

其实,不要那样做,它并不能解决分钟错误的600左右!

更简单的方法是使用模 % 运算符

此代码中除法的结果将始终仅为“整数”,因为一旦您去掉 mod 60,除数将始终是 60 的精确倍数(因为这只是除以 60 后的余数) - 数学! :p

function humanReadable(seconds) {
    const ss = seconds % 60;
    seconds = (seconds - ss) / 60;
    const mm = seconds % 60;
    const hh = (seconds - mm) / 60;
    return [hh,mm,ss].map(v => (''+v).padStart(2, 0)).join(':');
}


console.log(humanReadable(45296))

或者,您可以只使用一个日期对象,让它为您完成所有工作

function humanReadable(seconds) {
    const d = new Date(0);
    d.setUTCSeconds(seconds);
    const hh = d.getUTCHours().toString().padStart(2, '0');
    const mm = d.getUTCMinutes().toString().padStart(2, '0');
    const ss = d.getUTCSeconds().toString().padStart(2, '0');
    return `${hh}:${mm}:${ss}`;
}

console.log(humanReadable(45296))

我还提供了一种获取前导零的替代方法 - 这只是我的习惯,这些说使用 padStart 等

在 padStart 之前,而不是

hour < 10 ? `0${hour}` : hour

我愿意

`0${hour}`.substr(-2)

但是由于您使用的是模板文字,因此您肯定有 padStart :p

【讨论】:

    猜你喜欢
    • 2010-09-08
    • 1970-01-01
    • 2014-03-08
    • 2012-03-07
    • 1970-01-01
    • 2019-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多