kotlin rem operator doesn't give me correct answer - kotlin

I use remainder inside my code with kotlin in android project but with this value I don't get the correct answer.
variable is :
val vv = 1529.71
val ratio = 0.01
val remainder = vv.rem(ratio)
it's must be zero but remainder value is :
4.5363018896793506E-15
I don't understand why this happened.

The answer is because vv isn't actually 1529.71 but the closest possible Double, the exact value is 1529.7100000000000363797880709171295166015625 (the easiest way to see it is println(java.math.BigDecimal(vv))). If you want to represent decimal numbers exactly, use BigDecimal and pass the fraction as a string:
val vv = BigDecimal("1529.71")
val ratio = BigDecimal("0.01")
val remainder = vv.rem(ratio)
Read more about floating point here: https://floating-point-gui.de/

In my case, i had to get only the exact digits of two numbers after the decimal point.
I achieved it by doing this:
val input = 30.47f
val remainder = (input * 100).toInt() - (input.toInt() * 100)
// remainder = 47 exactly, and not 469999999...
Hope this would be helpful for someone.

Related

Kotlin. How to convert string to Int without loosing precision?

I'm trying to convert String to Int. The String can contain number as Int or as Double. But I need to convert string to Int anyway.
Here is my code:
val str = "999.13"
val number = str.toDoubleOrNull()?.roundToInt() ?: 0 // number will be 999
It works but there is one problem. If the source string will contain a very large number, for example 99999999999, then I get an incorrect number. After casting the string to a double, I lose precision.
What is the best way to perform such a manipulation without loss of precision? I would like to refrain from using BigDecimal, BigInteger etc.
Perhaps there is a more elegant solution for kotlin, please help me.
There's no way for Double and Long to hold bigger values than their largest possible values, so of course you will lose precision. That's why BigDecimal/BigInteger exist. They are the only ways to handle numbers that are bigger than the largest values Double and Long can handle, unless you want to handle parsing of the String yourself (note, you are parsing with toDoubleOrNull(), not casting).
I'm not sure why you'd want to avoid BigDecimal, but you could split the number at the decimal place, use toIntOrNull() or toLongOrNull() on the first part of the String and use toFloatOrNull() on the second part so you can round it to either 0 or 1 and add that to the first part to do the rounding:
val result = if ("." !in input)
input.toIntOrNull()
else {
val (firstPart, secondPart) = input.split(".")
val integerPart = firstPart.toIntOrNull()
integerPart?.let { it + (".$secondPart".toFloatOrNull()?.roundToInt() ?: 0) }
}
It would be a bit easier to use BigDecimal.
val result = runCatching {
BigDecimal(input).setScale(0, RoundingMode.HALF_UP).toInt()
}.getOrNull()
Both of the above would be simpler if you already know your input is valid.

How would i separate an answer in Kotlin do print 2 different types

Hi this is my first ever program I'm tryin to write in android studio/Kotlin and I'm not sure how to proceed.
so in my program i have a few math tasks to do and it does it fine but what I need to do now is separate part of the answer then covert it then print out both parts
for example if my answer was 1.5232 i would like to convert the decimal part of the answer to a string that matches a range if its in it. the ranges I have are in the .0000 area so I would like to limit the decimal range too.
so final result would look like this
1 (whatever my string in range is)
I hope I included enough info thank you in advance.
The first part of the task is to split the number into the integer and fractional components:
val input = 1.5232
val integer = input.toInt() // rounds DOWN to nearest smaller Int
val fractional = input % 1.0 // The remainder when dividing by 1.0 is the fraction
The strategy I would use to round to the nearest fractional value given a certain precision is to multiply by that precision, and round to the nearest integer. That would give you the numerator, and the precision would be the denominator:
val denominator = 8 // fractional precision
val numerator = (fractional * denominator).roundToInt() // rounds up or down to nearest Int
Then to put it together, you can use a string template:
val result = "$integer $numerator/$denominator"
println(result)
Simplifying the fraction would be another task if you need that. You can find various algorithms for finding greatest common divisor of two numbers. Use one of those and divide the numerator and denominator by that value.

Kotlin line break in sums — result depends on operator placement

today I've encountered a strange behaviour in Kotlin that I cannot explain. Given the following code:
data class Data(
val v1: Int,
val v2: Int,
val v3: Int)
fun main() {
val d = Data(1,1,1)
val sum1 = d.v1 + d.v2 + d.v3
println("Oneliner: $sum1") // prints: Oneliner: 3
val sum2 = d.v1
+ d.v2
+ d.v3
println("OperatorFirst: $sum2") // prints: OperatorFirst: 1
val sum3 = d.v1 +
d.v2 +
d.v3
println("OperatorLast: $sum3") // prints: OperatorLast: 3
}
(Testable at: https://pl.kotl.in/gMjif_6FO)
Now it seems to depend on where you place the + operator to get the correct result of 3. However, the IDE doesn't show that anything might be wrong with the second version and i couldn't find any information of why this case would behave differently.
A question on the software engineering space also says that several coding guidelines suggest to put the operator at the beginning of the line: https://softwareengineering.stackexchange.com/questions/93670/line-break-before-after-operator
Also, the only explanation I could find for this behaviour is that the + at the line beginnings is interpreted as a unary plus operator. https://www.programiz.com/kotlin-programming/operators#unary
However, even this makes no sense to me on a val
That's the price you pay for optional semicolons. Andrey Breslav said in one of his lectures that it is intended behavior. Binary operators like + or * should be placed on the top line, not the bottom line. If you want to place them on bottom line, use parentheses:
val sum = (1
+ 1
+ 1)
println(sum) // prints: 3

How to divide two Int a get a BigDecimal in Kotlin?

I want to divide two Integers and get a BigDecimal back in Kotlin.
E.g. 3/6 = 0.500000.
I've tried some solutions, like:
val num = BigDecimal(3.div(6))
println("%.6f".format(num))
// The result is: 0.000000
but none of them solve my problem.
3 and 6 are both Int, and dividing one Int by another gives an Int: that's why you get back 0. To get a non-integer value you need to get the result of the division to be a non-integer value. One way to do this is convert the Int to something else before dividing it, e.g.:
val num = 3.toDouble() / 6
num will now be a Double with a value of 0.5, which you can format as a string as you wish.
You might have better luck with:
val num = 3.toBigDecimal().divide(6.toBigDecimal())
println(num)
// prints 0.5
You have to convert both numbers to BigDecimal for the method to work. This will show the exact quotient, or throw an exception if the exact quotient cannot be represented (ie a non-terminating decimal).
You can set the scale and rounding mode as follows:
val num = 3.toBigDecimal().divide(6.toBigDecimal(), 4, RoundingMode.HALF_UP)
println(num)
// prints 0.5000
Link to reference article
Dividing Int by Int will give Int result only. To get float result , you need to convert one of the number to float.
You can use toFloat() function also.
var result = Int.toFloat() / Int

How to combine 2 different integers to create a single float (or a double)

I'm Cesare from Italy (please excuse my english), this is my first question posted on StackOverflow and I'm pretty new to Objective-C... I hope I won't make a mess on my first try.
I would like to "combine" two integers that I already have to create a new float (or a double).
By "combine", I mean that I'd like to have the first int before the point and the second int after the point, I'm not trying to convert from int to float. Maybe an example could explain better what I'm trying to do:
First int: 7
Second int: 92
The float I'm trying to get: 7.92
I looked for a previous question like mine but I haven't found anything, maybe because what I'm trying to do is pretty dumb (I have a UIPickerView with 2 components, each containing hundreds of integers, and I'm trying to create a float or double variable that has the selection of the first component before the point and the selection of the second component after the point).
Thanks in advance for your help,
Cesare
Just think about what the definition and/or the purpose of the decimal point is. It separates the part of the number which is less than one from the part greater than or equal to one.
So, keep dividing the part after the decimal point until it's less than 1:
int firstPart = 7;
int secondPart = 92; // or whatever
float f = secondPart;
while (f >= 1) {
f /= 10;
}
f += firstPart;
I know this is later, but came across a similar situation. Maybe this is more efficient.
Take the second number, 92 and divide it by 100. That gives you .92. Add that to the first number. That can give you 7.92. However, since you're adding integers that you want converted to a float, you'll need to cast the numbers when adding them. Like this:
int firstPart = 7;
int secondPart = 92;
float afterDecimalPlace = (float)secondPart/100.0;
float numberAsFloat = (float)firstPart + afterDecimalPlace;
essentially that is:
92/100 = .92
7 + .92 = 7.92