Math.ttrunk()未正确舍入值



我知道在JavaScript中肯定有更好的方法可以做到这一点,但我只是在做一些我知道的事情。我正在进行另一个代码战争挑战,似乎在本应获得12:34:56的时候获得了12:34:55

对于挑战,函数以秒的格式输入,例如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}`
}

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

在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分钟左右的错误!

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

该代码中的除法结果将始终是"0";整数";只是,因为一旦你去掉模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

您应该尝试使用Modulus来获得每个数字除法后的余数,如下代码片段所示。

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);