我正在尝试将String
转换为Int
。String
可以包含作为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()
如果您已经知道您的输入是有效的,那么以上两种方法都会更简单。