科特林.如何在不丢失精度的情况下将字符串转换为Int



我正在尝试将String转换为IntString可以包含作为Int或作为Double的数字。但无论如何,我都需要将字符串转换为Int

这是我的代码:

val str = "999.13"
val number = str.toDoubleOrNull()?.roundToInt() ?: 0 // number will be 999

它有效,但有一个问题。如果源字符串包含一个很大的数字,例如99999999999,那么我得到的数字不正确。把绳子铸成双精度后,我就失去了精度。

在不损失精度的情况下进行这种操作的最佳方法是什么?我想避免使用BigDecimal,BigInteger等

也许还有一个更优雅的解决方案,请帮助我。

Double和Long无法保持比其最大可能值更大的值,因此您当然会失去精度。这就是BigDecimal/BigInteger存在的原因。它们是处理大于Double和Long可以处理的最大值的数字的唯一方法,除非您想自己处理字符串的解析(注意,您正在使用toDoubleOrNull()而不是强制转换解析(。

我不知道你为什么要避免使用BigDecimal,但你可以在小数点处拆分数字,在字符串的第一部分使用toIntOrNull()toLongOrNull(),在第二部分使用toFloatOrNull(),这样你就可以将其四舍五入到0或1,并将其添加到第一部分以进行四舍五进:

val result = if ("." !in input)
input.toIntOrNull()
else {
val (firstPart, secondPart) = input.split(".")
val integerPart = firstPart.toIntOrNull()
integerPart?.let { it + (".$secondPart".toFloatOrNull()?.roundToInt() ?: 0) }
}

使用BigDecimal会更容易一些。

val result = runCatching {
BigDecimal(input).setScale(0, RoundingMode.HALF_UP).toInt()
}.getOrNull()

如果您已经知道您的输入是有效的,那么以上两种方法都会更简单。

相关内容

最新更新