dennischen / daily-money

a daily expense tracking android app
64 stars 53 forks source link

Issue#61: Uses double for currency #5

Closed LancelotLiu closed 12 years ago

LancelotLiu commented 12 years ago

http://code.google.com/p/daily-money/issues/detail?id=61

By this modification, it will store TEXT type amount in database (*1) and transfer TEXT to java BigDecimal at runtime to keep precision of amounts.

Besides integer, all data types will transfer to double in sqlite sum() function. This will also cause precision problem. So I select data and sum by java BigDecimal rather than using sum() function.

*1 http://sqlite.org/datatype3.html "For conversions between TEXT and REAL storage classes, SQLite considers the conversion to be lossless and reversible if the first 15 significant decimal digits of the number are preserved. If the lossless conversion of TEXT to INTEGER or REAL is not possible then the value is stored using the TEXT storage class."

根據 sqlite 官網針對資料型別的描述,若數值的前 15 位數可以進行無損轉換,便會以 INTEGER 或 REAL 的資料型別儲存,否則就會以 TEXT 型別儲存。 意即,若要確保數值能精確地被保存,應直接以 TEXT 型別儲存。 因此在 TB_ACC、TB_DET 新增 TEXT 欄位儲存金額資料(原欄位保留)。 在 java 程式裡使用 BigDecimal 取代 double/Double 的型態,動態將 TEXT 格式資料轉換為 BigDecimal 進行運算。

另外在 sqlite 的 sum() 功能中,除了 INTEGER 型別的資料外,其他型別均會被轉換為 double 再進行運算,因此也會有精確度的問題。 所以改為查出資料後,在 java 中使用 BigDecimal 進行加總,而不直接使用 sum()。