2016-06-14 60 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