Convert String which is "float" to Integer - kotlin

How to convert a string value which contains float representation to integer in kotlin?
I tried to convert string to float with .toFloat() and then converted it to an integer using toInt() and it works flawlessly.
But how to convert such string to integer directly?
val strDemo = "42.22"
val intDemo = strDemo.toInt()
snippet above throws NumberFormatException because it is not correct number representaion of Integer.
But, when I try
val strDemo = "42.22"
val intDemo = strDemo.toFloat().toInt()
it converts the data with no exception because string gets converted to float first. And there is a correct number representation for a Float value.
Now how to bypass the toFloat() method and convert strDemo to Integer directly?

There's no magic function that will convert a decimal/float string numbers to integer directly. It has to be done this way. Even if you found one, I'm sure that the process toFloat().toInt() still happen on that function.
So the solution that you can do is to create an extension of String like this:
StringExt.kt
fun String.floatToInt(): Int {
return this.toFloat().toInt()
}
You can use it like this:
val strDemo = "42.22"
val intDemo = strDemo.floatToInt()

Related

Most idiomatic way to convert a Float value to a string without a decimal point in Kotlin

I'd like to convert a Float value to a String, but without a decimal point. For example, for the following code:
fun toDecimalString(value: Float): String {
// TODO
}
fun main() {
println("Result: ${toDecimalString(1.0f)}")
println("Result: ${toDecimalString(1.999999f)}")
println("Result: ${toDecimalString(20.5f)}")
}
I'd like the expected output to be:
1
1
20
As #Tenfour04 said, the answer is to first convert to an integer, by using .toInt(), which only leaves the digits left of the decimal point, and then convert to string using .toString().
.toInt().toString()
By converting to an Int before turning the input to a string, all decimal point values are dropped, e.g.:
fun toDecimalString(value: Float): String = "${value.toInt()}"

Input out of range for Int datatype, not passing a testcase

I am trying to solve the following question on LeetCode; Write a function that takes an unsigned integer and returns the number of '1' bits it has. Constraints: The input must be a binary string of length 32.
I have written the following code for that which works fine for inputs 00000000000000000000000000001011 and 00000000000000000000000010000000 (provided internally by the website) but give output 0 for input 11111111111111111111111111111101 and in my local compiler for the last input it says "out of range"
class Solution {
// you need treat n as an unsigned value
fun hammingWeight(n:Int):Int {
var num = n
var setCountBit = 0
while (num > 0) {
setCountBit++
num= num and num-1
}
return setCountBit
}
}
To correctly convert binary string to Int and avoid "out of range error", you need to do the following (I believe LeetCode does the same under the hood):
fun binaryStringToInt(s: String): Int = s.toUInt(radix = 2).toInt()
"11111111111111111111111111111101" is equivalent to 4294967293. This is greater than Int.MAX_VALUE, so it will be represented as negative number after .toInt() convertion (-3 in this case).
Actually, this problem could be solved with one-liner in Kotlin 1.4:
fun hammingWeight(n: Int): Int = n.countOneBits()
But LeetCode uses Kotlin 1.3.10, so you need to adjust your solution to handle negative Ints as well.
Please change the type of your input variable from Int to a type like Double .At the moment The given value is bigger than the maximum value that a type Int number can store.

NumberFormatException in converting string to byte

I am trying to get the MD5 format of string
Code:
fun getEncodedData(data: String): String? {
val MD5 = "MD5"
// Create MD5 Hash
val digest = java.security.MessageDigest
.getInstance(MD5)
digest.update(data.toByte())
val messageDigest = digest.digest()
// Create Hex String
val hexString = StringBuilder()
for (aMessageDigest in messageDigest) {
var h = Integer.toHexString(0xFF and aMessageDigest.toInt())
while (h.length < 2)
h = "0$h"
hexString.append(h)
}
return hexString.toString()
}
There is a crash at: digest.update(data.toByte()). I get number format Exception
Input I am passing for data: oEXm43
There is no crash if I pass ex: 11 as a string for input data
Should the input always should be integer in the string or can it be a mixture of number and characters.
You're trying to call the update method that takes a single byte parameter, and using toByte which converts the entire string's numerical value to a single byte. This conversion method is what fails on non-numerical values inside a String.
Instead, you can use the variant of update with a byte[] parameter, and convert your String to an array of bytes (one per character) with toByteArray:
digest.update(data.toByteArray())

What happens with toInt()

I currently start to learn Kotlin and I was making this code
val a = "1"
val b = a[0]
val c = b.toInt()
println(c)
When I run the code, the result is 49. What really happened? Because I think the result will be 1.
a is a String, which is a CharSequence. That is why you can access a[0] in the first place. a.get(0) or a[0] then returns a Char. Char on the other hand returns its character value when calling toInt(), check also the documentation of toInt().
So your code commented:
val a = "1" // a is a String
val b = a[0] // b is a Char
val c = b.toInt() // c is (an Int representing) the character value of b
If you just want to return the number you rather need to parse it or use any of the answers you like the most of: How do I convert a Char to Int?
(one simple way being b.toString().toInt()).
a is String,
when you get a[index] return type is char,
in kotlin char.toInt method return ASCII code of the character and it's 49
if you want to get the integer value of "1" just use toString method
val a = "1"
val b = a[0].toString()
val c = b.toInt()
println(c)
prints:1
In your example a is a String, but String. String is under the hood an Array of Char. And by accessing your String using a[0] operator, you get first element of this Char Array. So you get Char '1', not String "1". And now, when you run '1'.toInt() function on Char - it will return ASCII code of that Char. When you run "1".toInt() on String - it will convert this String into Int "1". When you need to get Int value of first letter in your String, you need to convert it first into String:
val a = "123"
val b = a[0].toString() // returns first Char of String "123" and converts to String
val c = b.toInt() // returns Int: 1
or in one line:
"123"[0].toString().toInt()

How to convert String to Long in Kotlin?

So, due to lack of methods like Long.valueOf(String s) I am stuck.
How to convert String to Long in Kotlin?
1. string.toLong()
Parses the string as a [Long] number and returns the result.
#throws NumberFormatException if the string is not a valid
representation of a number.
2. string.toLongOrNull()
Parses the string as a [Long] number and returns the result or null
if the string is not a valid representation of a number.
3. string.toLong(10)
Parses the string as a [Long] number and returns the result.
#throws NumberFormatException if the string is not a valid
representation of a number.
#throws IllegalArgumentException when
[radix] is not a valid radix for string to number conversion.
public inline fun String.toLong(radix: Int): Long = java.lang.Long.parseLong(this, checkRadix(radix))
4. string.toLongOrNull(10)
Parses the string as a [Long] number and returns the result or null
if the string is not a valid representation of a number.
#throws IllegalArgumentException when [radix] is not a valid radix for string
to number conversion.
public fun String.toLongOrNull(radix: Int): Long? {...}
5. java.lang.Long.valueOf(string)
public static Long valueOf(String s) throws NumberFormatException
String has a corresponding extension method:
"10".toLong()
Extension methods are available for Strings to parse them into other primitive types. Examples below:
"true".toBoolean()
"10.0".toFloat()
"10.0".toDouble()
"10".toByte()
"10".toShort()
"10".toInt()
"10".toLong()
Note: Answers mentioning jet.String are outdated. Here is current Kotlin (1.0):
Any String in Kotlin already has an extension function you can call toLong(). Nothing special is needed, just use it.
All extension functions for String are documented. You can find others for standard lib in the api reference
Actually, 90% of the time you also need to check the 'long' is valid, so you need:
"10".toLongOrNull()
There is an 'orNull' equivalent for each 'toLong' of the basic types, and these allow for managing invalid cases with keeping with the Kotlin? idiom.
It's interesting. Code like this:
val num = java.lang.Long.valueOf("2");
println(num);
println(num is kotlin.Long);
makes this output:
2
true
I guess, Kotlin makes conversion from java.lang.Long and long primitive to kotlin.Long automatically in this case. So, it's solution, but I would be happy to see tool without java.lang package usage.
In Kotlin, to convert a String to Long (that represents a 64-bit signed integer) is simple.
You can use any of the following examples:
val number1: Long = "789".toLong()
println(number1) // 789
val number2: Long? = "404".toLongOrNull()
println("number = $number2") // number = 404
val number3: Long? = "Error404".toLongOrNull()
println("number = $number3") // number = null
val number4: Long? = "111".toLongOrNull(2) // binary
println("numberWithRadix(2) = $number4") // numberWithRadix(2) = 7
With toLongOrNull() method, you can use let { } scope function after ?. safe call operator.
Such a logic is good for executing a code block only with non-null values.
fun convertToLong(that: String) {
that.toLongOrNull()?.let {
println("Long value is $it")
}
}
convertToLong("123") // Long value is 123
One good old Java possibility what's not mentioned in the answers is java.lang.Long.decode(String).
Decimal Strings:
Kotlin's String.toLong() is equivalent to Java's Long.parseLong(String):
Parses the string argument as a signed decimal long. ... The
resulting long value is returned, exactly as if the argument and the
radix 10 were given as arguments to the parseLong(java.lang.String, int) method.
Non-decimal Strings:
Kotlin's String.toLong(radix: Int) is equivalent to Java's eLong.parseLong(String, int):
Parses the string argument as a signed long in the radix specified by
the second argument. The characters in the string must all be digits of the specified radix ...
And here comes java.lang.Long.decode(String) into the picture:
Decodes a String into a Long. Accepts decimal, hexadecimal, and octal
numbers given by the following grammar: DecodableString:
(Sign) DecimalNumeral | (Sign) 0x HexDigits | (Sign) 0X HexDigits | (Sign) # HexDigits | (Sign) 0 OctalDigits
Sign: - | +
That means that decode can parse Strings like "0x412", where other methods will result in a NumberFormatException.
val kotlin_toLong010 = "010".toLong() // 10 as parsed as decimal
val kotlin_toLong10 = "10".toLong() // 10 as parsed as decimal
val java_parseLong010 = java.lang.Long.parseLong("010") // 10 as parsed as decimal
val java_parseLong10 = java.lang.Long.parseLong("10") // 10 as parsed as decimal
val kotlin_toLong010Radix = "010".toLong(8) // 8 as "octal" parsing is forced
val kotlin_toLong10Radix = "10".toLong(8) // 8 as "octal" parsing is forced
val java_parseLong010Radix = java.lang.Long.parseLong("010", 8) // 8 as "octal" parsing is forced
val java_parseLong10Radix = java.lang.Long.parseLong("10", 8) // 8 as "octal" parsing is forced
val java_decode010 = java.lang.Long.decode("010") // 8 as 0 means "octal"
val java_decode10 = java.lang.Long.decode("10") // 10 as parsed as decimal
If you don't want to handle NumberFormatException while parsing
var someLongValue=string.toLongOrNull() ?: 0
Actually, there are several ways:
Given:
var numberString : String = "numberString"
// number is the Long value of numberString (if any)
var defaultValue : Long = defaultValue
Then we have:
+—————————————————————————————————————————————+——————————+———————————————————————+
| numberString is a valid number ? | true | false |
+—————————————————————————————————————————————+——————————+———————————————————————+
| numberString.toLong() | number | NumberFormatException |
+—————————————————————————————————————————————+——————————+———————————————————————+
| numberString.toLongOrNull() | number | null |
+—————————————————————————————————————————————+——————————+———————————————————————+
| numberString.toLongOrNull() ?: defaultValue | number | defaultValue |
+—————————————————————————————————————————————+——————————+———————————————————————+
string.toLong()
where string is your variable.