更新文件:TWD 改為整數四捨五入的說明與 Kotlin 陷阱紀錄
This commit is contained in:
@@ -272,6 +272,60 @@ curl -X POST "http://.../api/v1/repos/timmy/bot-rates/releases/$ID/assets?name=B
|
||||
| 抓匯率耗時 | < 500ms |
|
||||
| Gitea release | v1.0 已上傳 APK |
|
||||
|
||||
## 階段 7:調整顯示為整數(v1.0.1)
|
||||
|
||||
需求:TWD 顯示不要小數,直接四捨五入到個位(例如 `3,162.50` → `3,163`)。
|
||||
|
||||
### Rust 端(macOS / Windows)
|
||||
|
||||
Rust 的 `f64::round()` 本身就是 ties away from zero(正數 `.5` 往上、負數 `-.5` 往下),符合中文「四捨五入」定義。改動只是把「×100 round ÷100 + `.xx` 格式化」簡化成 `v.round() as i64`:
|
||||
|
||||
```rust
|
||||
fn format_twd(v: f64) -> String {
|
||||
let rounded = v.round() as i64;
|
||||
// 手刻千分位逗號
|
||||
}
|
||||
|
||||
fn format_twd_raw(v: f64) -> String {
|
||||
format!("{}", v.round() as i64)
|
||||
}
|
||||
```
|
||||
|
||||
### Kotlin 端的陷阱
|
||||
|
||||
`kotlin.math.round(Double)` 是**銀行家捨入**(ties to even),例如 `316.5 → 316`、`317.5 → 318`。這跟 Rust 端行為不一致,而且不是台灣語境下「四捨五入」的常識定義。
|
||||
|
||||
**解法**:改用 `BigDecimal.setScale(0, RoundingMode.HALF_UP)`:
|
||||
|
||||
```kotlin
|
||||
private fun roundHalfUp(v: Double): BigDecimal =
|
||||
BigDecimal.valueOf(v).setScale(0, RoundingMode.HALF_UP)
|
||||
|
||||
private fun formatTwd(v: Double): String =
|
||||
DecimalFormat("#,##0").format(roundHalfUp(v))
|
||||
|
||||
private fun formatTwdRaw(v: Double): String =
|
||||
roundHalfUp(v).toPlainString()
|
||||
```
|
||||
|
||||
**為什麼 `BigDecimal.valueOf(v)` 而不是 `BigDecimal(v)`?**
|
||||
`BigDecimal(double)` 吃 IEEE 754 的尾數誤差,例如 `BigDecimal(0.1)` 會變 `0.1000000000000000055511151...`。`valueOf(double)` 走 `Double.toString` 路線,給你看起來「應該」的值,對使用者輸入的金額比較合理。
|
||||
|
||||
### 版號策略
|
||||
|
||||
行為變了(而且使用者肉眼可見),所以 bump `versionCode = 2 / versionName = "1.0.1"`,tag `v1.0.1`,在 Gitea 另開一個 release `BotRates-v1.0.1.apk`,不覆蓋 v1.0 的 asset。這樣歷史版本可追溯。
|
||||
|
||||
### 實機 install 踩到 INSTALL_FAILED_UPDATE_INCOMPATIBLE
|
||||
|
||||
先前裝過 debug 版(debug keystore 簽),現在要裝 release 版(自己的 keystore 簽),Android 拒絕覆蓋:
|
||||
|
||||
```
|
||||
Failure [INSTALL_FAILED_UPDATE_INCOMPATIBLE: Package tw.local.botrates
|
||||
signatures do not match previously installed version; ignoring!]
|
||||
```
|
||||
|
||||
**解法**:`adb uninstall tw.local.botrates` 先移除,再 `adb install`。之後都用同一把 release keystore 簽,就能持續覆蓋更新。
|
||||
|
||||
## 如果要擴充
|
||||
|
||||
- **相容 minSdk 21(Android 5.0)**:`compileOptions` 加 `isCoreLibraryDesugaringEnabled = true`,dependencies 加 `coreLibraryDesugaring`,讓 `java.time` 等新 API 降級。
|
||||
|
||||
Reference in New Issue
Block a user