我正在开发Vue应用程序,其中一项功能涉及重量值。我目前将它们以克的形式存储在数据库中,然后将其转换为磅。最终,我希望能够让用户在度量和标准计算之间进行选择。我创建了一个函数,该函数返回四个计算,但是它们似乎不能正确地相加。
export const convertToPounds = weight => {
return (Math.round((weight / 453.592) * 10) / 10).toFixed(2);
};
此功能运行四次。一次为总计,三次根据项目过滤到哪个类别。
Total - 4170 grams converts to 9.20 lbs
ValueA - 2700 grams converts to 6.00 lbs
ValueB - 1400 grams converts to 3.10 lbs
ValueC - 70 grams converts to 0.20 lbs
不过,从最终转换来看,这三个值总计为9.30,而不是应返回的9.20。
我的问题是,转换方法是否太不准确,无法处理这些类型的转换?还是以克存储重量不是解决这种情况的最佳方法?
答案 0 :(得分:1)
我认为您的问题是,您首先要对其进行四舍五入,然后再进行toFixed(2)来进一步对其进行四舍五入。我在google上进行了简短检查,它显示出正确的计算结果:https://www.google.com/search?q=4170+grams+to+pounds
const convertToPounds = weight => {
return (weight / 453.592).toFixed(2);
};
// Total - 4170 grams converts to 9.20 lbs
console.log(convertToPounds(4170));
// ValueA - 2700 grams converts to 6.00 lbs
console.log(convertToPounds(2700));
// ValueB - 1400 grams converts to 3.10 lbs
console.log(convertToPounds(1400));
// ValueC - 70 grams converts to 0.20 lbs
console.log(convertToPounds(70));
答案 1 :(得分:1)
要长时间发表评论:
不可能提供诸如9.20
之类的精确数字。它们用二进制四舍五入到最接近的可能数字,这里是9.19999999999999929
。这就是原因,toFixed()
返回的是字符串而不是数字。
此处提供作为答案的函数或表达式也无济于事:
value = Math.round(value * Math.pow(10, decimals)) / Math.pow(10, decimals);
如果您通过console.log(value.toPrecision(18))
证明结果,则该函数将失败。所有返回数字的舍入函数都将失败。
为什么toPrecision(18)
?浮点数通常以IEEE 754的形式实现。JavaScript使用double floats
约有16个十进制数字。因此18位数字是内部数字的非常精确的十进制表示形式。
最后的注释:toFixed()
仅用于最终打印。
答案 2 :(得分:0)
您正在四舍五入。你为什么要四舍五入?是不是这样,UI不会显示长十进制?如果是这样,则应考虑在UI级别进行舍入。如您所知,在这样的数据级别四舍五入是很危险的。事情不会在内部累加,如果您在另一次计算中使用该结果,那么它将漂移并且变得更加不准确。
请考虑使用过滤器来执行此操作,例如以下要点(https://gist.github.com/belsrc/672b75d1f89a9a5c192c#file-gistfile1-js-L92):
Vue.filter('round', function(value, decimals) {
if(!value) {
value = 0;
}
if(!decimals) {
decimals = 0;
}
value = Math.round(value * Math.pow(10, decimals)) / Math.pow(10, decimals);
return value;
});