kotlin - calculate Compound Interest in years - kotlin

I am using Kotlin and running into a problem while calculating Compound Interest after three years.
I've tried:
fun accountInThreeYears(initial: Int, percent: Int): Double = initial + (initial * percent / 100.toDouble()) * 3
However, using an online calculator i get a different answer, what am I doing wrong?

You are missing the right formula:
value after n years = (initial value) x (1 + interest)^n
so your function should look like this:
fun accountInThreeYears(initial: Int, percent: Int): Double = initial * (1 + percent / 100.toDouble()).pow(3)
use this import for the pow() method:
import kotlin.math.pow

Related

kotlin rem operator doesn't give me correct answer

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.

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 autogenerate array in kotlin similar to numpy?

hello let me do a demonstration in python about what I want to achieve in kotlin:
np.linspace(start = 0, stop = 100, num = 5)
This results:
-------------------------
|0 | 25 | 50 | 75 | 100 |
-------------------------
Now in Kotlin how can I get the same result? Is there a similar library?
This should work exactly like linspace (not handling cases when num is 0 or 1):
fun linspace(start: Int, stop: Int, num: Int) = (start..stop step (stop - start) / (num - 1)).toList()
It makes use of the rangestart..stop (a range in kotlin is inclusive) and the function step lets us define how far the steps in this ranges should be.
EDIT
As #forpas suggested in the comments the step should be calculated using (stop - start) and not only stop. Using stop alone would only work if the start was 0.
#Alexey Romanov correctly said that unless you explicitly need a List as return type you should return the IntProgression (it does not hold all the elements in memory like a list does) since its also Iterable.
Thank you both for your input!
Not exactly the same, but it generates an array with 5 integers, multiples of 25 starting from 0:
val array = Array(5) { it * 25 }
the result is:
[0, 25, 50, 75, 100]
You can create a function simulating what you need:
fun linspace(start: Int, stop: Int, num: Int) = Array(num) { start + it * ((stop - start) / (num - 1)) }
DoubleProgression used to exist but was removed, because it raises rounding issues; you can copy the sources from that commit as a starting point if you really need it. Or consider converting it to a BigDecimalProgression instead. Of course, you need division to get the step from your arguments, which isn't exact even for BigDecimal.
You can also use sequences:
fun linspaceD(start: Double, stop: Double, num: Double): Sequence<Double> {
val step = (stop - start) / (num - 1)
return sequence {
for i in 0 until num yield(start + step*i)
}
}
Note that this resolves rounding in a specific way, by always yielding num values even if the last one is slightly greater than stop.

Kotlin is ignoring expression

I'm wondering why the below code generates the strange results, and compiler doesn't show any error or warning. This looks like an extremely efficient source of bugs.
val a = 10 * 20 +
10 * 30
val b = 10 * 20
+ 10 * 30
val c = (
(10 * 20)
+ (10 * 30)
)
val d = (10 * 20)
+ (10 * 30)
println(a)
println(b)
println(c)
println(d)
And the output is:
500
200
500
200
Kotlin has optional semicolons, it allows and encourages source code to omit a statement separator (i.e. semicolon ;). As a result, it can get hard for the compiler to guess what you, as a programmer, actually intend to do:
val b = 10 * 20
+ 10 * 30
Will be compiled to an assignment of b = 500 and a second statement that results in 300 but never gets assigned to anything (same with d). How would you consider the compiler to know that the second line is actually part of the first expression? It's valid on its own.
This thread gives further details.
I looks like I was lucky to use an operator which also has unary version +.
The problem is that Kotlin allows for a kind of expressions which do nothing in fact like this:
12345
I can also have:
- 12345
which is just a negative number. I can also have positive number:
+ 12345
So in this case:
val a = 20 +
30
I have one expression, as the + requires another argument, which can be found in the next line.
However here I have two expressions
val a = 20
+ 30
The variable a will have value 20 and the second expression will do nothing.
However there is no unary version of *, so this works:
val a = 10 *
20
and a == 200, and this makes a compilation error:
val a = 10
* 20
Error:(397, 17) Kotlin: Expecting an element
Adding semicolons doesn't change anything, as the last expression is still not valid, and causes the compilation error.
And you can always use brackets:
val x = (10
+ 20)

How would I do this in a program? Math question

I'm trying to make a generic equation which converts a value. Here are some examples.
9,873,912 -> 9,900,000
125,930 -> 126,000
2,345 -> 2,400
280 -> 300
28 -> 30
In general, x -> n
Basically, I'm making a graph and I want to make values look nicer. If it's a 6 digit number or higher, there should be at least 3 zeros. If it's a 4 digit number or less, there should be at least 2 digit numbers, except if it's a 2 digit number, 1 zero is fine.
(Ignore the commas. They are just there to help read the examples). Anyways, I want to convert a value x to this new value n. What is an equation g(x) which spits out n?
It is for an objective-c program (iPhone app).
Divide, truncate and multiply.
10**x * int(n / 10**(x-d))
What is "x"? In your examples it's about int(log10(n))-1.
What is "d"? That's the number of significant digits. 2 or 3.
Ahhh rounding is a bit awkward in programming in general. What I would suggest is dividing by the power of ten, int cast and multiplying back. Not remarkably efficient but it will work. There may be a library that can do this in Objective-C but that I do not know.
if ( x is > 99999 ) {
x = ((int)x / 1000) * 1000;
}
else if ( x > 999 ) {
x = ((int) x / 100) * 100;
}
else if ( x > 9 ) {
x = ((int) x / 10) * 10;
}
Use standard C functions like round() or roundf()... try man round at a command line, there are several different options depending on the data type. You'll probably want to scale the values first by dividing by an appropriate number and then multiplying the result by the same number, something like:
int roundedValue = round(someNumber/scalingFactor) * scalingFactor;