Avoid division in string-to-unsigned conversions (KT-26309)

This commit is contained in:
Abduqodiri Qurbonzoda
2019-09-18 03:17:32 +03:00
parent d66f07a84e
commit 2819ab4ae9
@@ -198,14 +198,26 @@ public fun String.toUIntOrNull(radix: Int): UInt? {
start = 0
}
val limitForMaxRadix = 119304647u // limit / 36
var limitBeforeMul = limitForMaxRadix
val uradix = radix.toUInt()
val limitBeforeMul = limit / uradix
var result = 0u
for (i in start until length) {
val digit = digitOf(this[i], radix)
if (digit < 0) return null
if (result > limitBeforeMul) return null
if (result > limitBeforeMul) {
if (limitBeforeMul == limitForMaxRadix) {
limitBeforeMul = limit / uradix
if (result > limitBeforeMul) {
return null
}
} else {
return null
}
}
result *= uradix
@@ -251,14 +263,26 @@ public fun String.toULongOrNull(radix: Int): ULong? {
}
val uradix = radix.toUInt()
val limitBeforeMul = limit / uradix
val limitForMaxRadix = 512409557603043100uL // limit / 36
var limitBeforeMul = limitForMaxRadix
val uradix = radix.toULong()
var result = 0uL
for (i in start until length) {
val digit = digitOf(this[i], radix)
if (digit < 0) return null
if (result > limitBeforeMul) return null
if (result > limitBeforeMul) {
if (limitBeforeMul == limitForMaxRadix) {
limitBeforeMul = limit / uradix
if (result > limitBeforeMul) {
return null
}
} else {
return null
}
}
result *= uradix