Kotlin Training Program

DOWNLOAD APP

FEEDBACK

Parsing numbers

Parsing Int

Following is the algorithm to parse Int from a String :

Example

 Input = "  123 " = "123"
num = 0
'1' -> num = num * 10 + 1 = 0*10 + 1 = 0 + 1 = 1
'2' -> num = num * 10 + 2 = 1*10 + 2 = 10 + 2 = 12
'3' -> num = num * 10 + 3 = 12*10 + 3 = 120 + 3 = 123
num = 123
 

Implementation

 fun String.toIntOrNull(): Int? {
    // Trim the input
    val input = trim()

    // Empty input
    if (input.isEmpty()) return null

    // Create the number
    var num = 0

    // Parse each digit
    input.forEach { c ->
        if (c in '0'..'9') {
            val digit = c.code - '0'.code
            num = (num * 10) + digit
        } else {
            return null
        }
    }

    return num
}
 

Parsing Float

Parsing a floating point number is little more complicated than parsing Int. A floating point number has two parts - decimal part (before the decimal point) & fractional part (after the decimal point). The algorithm to parse decimal part is similar to that of parsing Int. For parsing the fractional part & forming the floating point number, we have two approaches :

Using formula

Algorithm

  • Perform Trim & empty check
  • If input does not contain a decimal point . invoke & return toIntOrNull()
  • Split the input by . into before and after sub strings
  • Parse before as Int using toIntOrNull() and assign it to int variable
  • For after substring,
    • Initialize fractional variable to 0 for storing the fractional part
    • Iterate over after substring in reverse order and for each Char,
      • If it is digit Char, update fractional as fractional / 10 + digit
      • Else (non digit Char), return null
  • return int + fractional / 10 as the result

Example

 Input = "3.14"
Split : before = "3", after = "14"

int = before.toIntOrNull() = 3

fractional = 0
'4' -> 0/10 + 4 = 0 + 4 = 4
'1' -> 4/10 + 1 = 0.4 + 1 = 1.4

result = 3 + 1.4/10 = 3.14
 

Implementation

 fun String.toFloatOrNull(): Float? {
    // Trim the input
    val input = trim()

    // Empty input
    if (input.isEmpty()) return null

    // Check for decimal point
    if (!input.contains(".")) return toIntOrNull()?.toFloat()

    // Split by decimal point
    val (before, after) = input.split(".")

    // Create the integer part
    val int = before.toIntOrNull() ?: return null

    // Create the fractional part
    var fractional = 0f
    after.reversed()
        .forEach { c ->
            if (c in '0'..'9') {
                val digit = c.code - '0'.code
                fractional = (fractional / 10) + digit
            } else {
                return null
            }
        }

    // Return the final number
    return int + fractional / 10
}
 

Using parse Int

Instead of parsing fractional part using a different formula, we can parse both before and after substrings using toIntOrNull(). Then to form the result, we divide fractional part with 10^^(no of digits in fractional part)^^ and add it to the int part.

Example

 Input = "3.14"
Split : before = "3", after = "14"

int = before.toIntOrNull() = 3
fractional = after.toIntOrNull() = 14

result = fractional / 10^2 + int = 0.14 + 3 = 3.14
 

Implementation

 fun String.toFloatOrNullAlt(): Float? {
    // Trim the input
    val input = trim()

    // Empty input
    if (input.isEmpty()) return null

    // Check for decimal point
    if (!input.contains(".")) return toIntOrNull()?.toFloat()

    // Split by decimal point
    val (before, after) = input.split(".")

    // Create the integer part
    val int = before.toIntOrNull() ?: return null

    // Create the fractional part
    val fractional = if (after.isEmpty()) {
        0
    } else {
        after.toIntOrNull() ?: return null
    }

    // Return the final number
    return int + fractional / 10.0.pow(after.length).toFloat()
}
 

Note :

  • The in-built pow function is defined for Double only, so we have used 10.0 (Double) instead of 10 (Int).
  • To find out number of digits in fractional part, after.length is used.
  • Because pow is a Double function it returns Double as output, so we have used toFloat() to convert it to Float.