2026/02/07(土)BigDecimal
2026/02/07 18:59
だから、私はずっとBigDecimalはjava.math.BigDecimalだと思っていたのですが、Androidではandroid.icu.math.BigDecimalという別物だったんですね。
今まではそんなことを意識せずにBigDecimalを使っていたのですが、KMMでAndroid/iOS共通部分のコードを書こうとしたときにどちらも使えない! となってしまいました。
仕方がないので、自分で小数点第一位までの数値を表すPointクラスを作りました。今回のユースケースであれば小数点以下第二位以降は不要なので、これで十分です。
@JvmInline
value class Point private constructor(val tenths: Long) {
companion object {
fun fromTenths(tenths: Long): Point = Point(tenths)
fun parse(text: String): Point {
val normalized = text.trim()
require(normalized.isNotEmpty())
val sign =
when {
normalized.startsWith("-") -> -1
normalized.startsWith("+") -> 1
else -> 1
}
val body =
if (normalized.startsWith("-") || normalized.startsWith("+")) {
normalized.drop(1)
} else {
normalized
}
val parts = body.split('.')
require(parts.size <= 2)
val intPart = parts[0].toLong()
val fracPart = parts.getOrNull(1)?.padEnd(1, '0') ?: "0"
require(fracPart.length == 1)
val tenths = (intPart * 10 + fracPart[0].digitToInt()) * sign
return Point(tenths)
}
}
override fun toString(): String {
val abs = kotlin.math.abs(tenths)
val sign = if (tenths < 0) "-" else ""
return "$sign$abs / 10.$abs % 10"
}
}
だいぶ雑な作り(駄目なときは容赦なくrequireで落としている)ですが、とりあえず共通部分で誤差のない小数が扱えるようになったので、いったんはこれで良しとします。