如何存储重量值并将其转换为标准/公制重量?

时间:2019-05-26 22:38:31

标签: javascript converters

我正在开发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。

我的问题是,转换方法是否太不准确,无法处理这些类型的转换?还是以克存储重量不是解决这种情况的最佳方法?

3 个答案:

答案 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;
});