2016-06-14 57 views
1

我们有猫鼬架构下面的代码试图将资金转换成整数MongoDB中保存:节省金钱作为整数

amount: { type: Number, get: getAmount, set: setAmount, required: true} 

function setAmount(num) { 
    return num * 100; 
} 

function getAmount(num) { 
    return (num/100).toFixed(2); 
} 

但是节省64.49我们还是结束了这个MongoDB中的文件:

"amount": 6448.999999999999 

我们如何解决这个问题?

+0

相同数量的我不一定确定这可能是你问题的原因。你在哪里检索数字并将它们写入你的数据库?因为'(num/100).toFixed(2)'应该总是返回一个数字,比如'6449.00' – Adjit

+0

使用npm库[mongoose-currency](https://www.npmjs.com/package/mongoose-currency) – chridam

+0

上面代码后64.99最后在MongoDB中是6448.999999999999。 – krl

回答

0

考虑使用BigNumber:​​

小例子(控制台):

> 0.2 * 0.4 
< 0.08000000000000002 

而且随着BigNumber

> var a = new BigNumber(0.2); 
> var b = new BigNumber(0.4); 
> var c = a.times(b); 
> c.valueOf(); 
< "0.08" 
+0

使用BigNumber,你并没有真正解决“舍入值”问题,只是将它推得更远 – Aurelien

+0

我明白你的意思,但我不同意。在这一天结束时,JS使用IEEE 754标准,我们需要了解这一点。如果突然间想要存储达到1/10的精度,会发生什么情况? –

+0

我认为这是一个“功能性”问题(我不知道英文中的这个词,对不起):我需要用1/10的预分存储,你不应该担心写“6448.999999999999 “在你的文件中。因为你在任何地方都使用浮点数值,这就是你的应用程序的重点。 – Aurelien

3

为了避免这些类型的精度问题对 “钱”变量,我总是使用“美分”作为单位。

不要存储15.24美元,在你的代码中存储1524美分。

然后使用整数进行所有操作。

然后使用美分=>美元转换只显示,通过添加“。”最后两个字符前的分隔符。

+0

这正是我们正在做的 – krl

+1

那么为什么你在文档中存储“num/100”呢? – Aurelien

+0

使用整数字符串,然后添加“。”最后两位数字之前的分隔符 – Aurelien

0

这是否满足您的需求?

function convert(number) { 
    const [i, d] = ('' + number).split(/\./); 
    const a = +i * 100; 
    const b = +(d || '0').slice(0, 2); 
    const c = +(d || '0').slice(2)? 1 : 0; 
    return a + b + c; 
} 

这里是旧版本,并没有全面上涨后.0099999

function convert(number) { 
    const [a, b] = ('' + number).split(/\./); 
    return +a * 100 + +(b || '0').slice(0, 2); 
} 

它接收1号和返回乘以100