i cant figure out how to round up decimals in kotlin calculator - kotlin

I just started coding in android studio and was creating calculator but now I'm stuck on one problem.
after struggling a lot I figured out how to make so u can use one dot but now I came across another problem which is after addition I cant seem to round up the decimals. when I do additions in decimals sometimes it gives me something like 1.9999999998 and I cant seem to round it up. for the reference I used Table Row in xml. if necessary I can show you what I have written so far. Thanks in advance.

You need String.format(".1f", value). 1,99999 -> 1.99. If you need to round to higher value, please use ceil: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.math/ceil.html

For formatting numbers, you should always be using NumberFormat or similar.
NumberFormat lets you set a RoundingMode which will do what you want.
Or you could be like me and write your own formatter for numbers because the built-in one didn't do what I wanted.

If you care about exact decimal values, then don't use floating-point. Instead, use a type that's intended for storing exact decimal values, such as BigDecimal.
(Floating-point types such as Kotlin's Float and Double can hold numbers across a huge range of magnitude, and store and calculate with them efficiently. But they use binary floating-point, not decimal. So they're great when you care about doing calculations efficiently and flexibly — but not when you need to store exact decimal values. Most of the questions about floating-point on this site seem to be for the latter cases, unfortunately…)
Kotlin has lots of extensions making it almost as easy to handle BigDecimals as the native types. They're a little less efficient, but not by anywhere near enough to be significant in a calculator project. And they do exactly what you want here: storing and manipulating decimal numbers exactly.
And because they're exact, you shouldn't need to do any rounding — and probably won't need to do any formatting either.
(Just make sure you create them directly from strings, not from floats/doubles — which will already have been rounded to the nearest binary floating-point number.)

Related

Why kotlin.math functions does not have implementation of Long

I have been working with kotlin for little over 2 years now.
Looking over what I learned in these 2 years, I noticed that I have been using(num.toDouble()).toLong() for kotlin.math functions a bit too much. For example, Math.sqrt(num.toDouble()).toLong(). Two of my projects have extension function sumByLong() inside util created by team, because kotlin libs only have sumBy:Int and sumByDouble:Double and a lot of work in the project, uses Long.
In short, Mathematical operations using Long is more common than using Double or Float, yet Long has a very small footprint in kotlin standard library. And since kotlin.math is different than java.lang.Math, mixed usage is not a recommended practice.
Going over docs of kotlin.math, all functions except for abs, min, max, only have implementation for Float and Double only.
Can someone Explain like I am 5 the possible reasoning behind this. Something real, not silly stuff like devs were lazy, or more code means more work, which is all I could find in search engine results.
--
Update: Some Clarification
1. I can understand that in most cases, return types will contain floating point numbers. I am also talking about parameters lacking long counterpart. Maybe using Math.sqrt wasn't the best example, something like math.log, math.cos, etc would be better example, where floating return type us expected, but parameters doesn't even support Int
2. When I said "Long is more common than using Double", I was not talking about public at large, but was looking over my past two years working with kotlin. I am sorry if my phrasing wasn't clear.
Disclaimer: this answer may be a little opinionated, but I believe it is according to general consensus and best practices of using maths in computer science.
Mathematics for integers and for real numbers (floats) are really two much different math "sub-worlds". They're pretty separate, they have different uses and we usually don't mix them.
If we work on some physics, we do real-world simulations, we operate on units like temperature or speed, we use doubles. If we have identifiers (bank account number), we count something (number of bank accounts) or we operate on a discrete values with 100% precision (bank account value) we always use integers and never doubles.
Operations like sinus, square root or logarithm make perfect sense for physics, but not really for bank account values. They very often produce either very small or very large numbers that can't be safely represented as integers. They operate on approximations and don't really provide 100% precise results. They are continuous by nature while integers are discrete.
What is the point of using integers with sqrt() or log() if they almost always return a floating point result? What is the point of passing an integer to sin() if e.g. there are only 2 distinct angles smaller than square angle that can be represented as an integer: 0 and 1? Using integers with these functions is unnatural and impractical.
I can't think of a case where we have to often convert between longs and doubles. Usually, we operate either on longs or on doubles top to bottom and we don't convert between them too often. By converting we lose advantages of these specific "math sub-worlds", we sum their disadvantages. Maybe you should just keep using doubles in your application and don't convert to/from longs? Why do you use longs?
BTW, you mentioned that you can't/shouldn't use java.lang.Math in the Kotlin application. Well, if you look into java.lang.Math you will notice that... it supports only doubles :-)
In the case of ceil, it returns a Double because a Double has a bigger range of values than Long. Consider, for example:
ceil(Long.MAX_VALUE.toDouble() * 1000)
What would you expect it to return if it returned a Long? For further discussion, see Why does Math.ceil return a double?
In the case of log and trigonometric functions, the use cases requiring Long parameters are rare and the requirements varied. For example, should it round up, down, or to the nearest integral value? These are decisions that should be made for your particular project, and therefore can't be made in the stdlib.
In your project, you can simply define your required functions in a single, small source file, making your project's choice of rounding method, and then use it everywhere instead of converting at each call site, e.g.:
fun cos(n: Long): Long = cos(x.toDouble()).roundToLong()

Round SQL String Data to correct decimal place, then return string data without floating point errors

We are trying to implement a reporting system using software that queries our SQL database. Due to a variety of circumstances, we have a need to round data within the SQL queries. Our goal is to avoid floating point errors, unwanted trailing zeros, and complexity of nested functions (if possible).
The incoming data is always type nvarchar(...) and needs to remain in a string format, which is causing problems for us. Here is an example of what I mean (tested using w3schools.com):
SELECT
STR(235.415, 10, 2) AS StringValue1,
STR('235.415', 10, 2) AS StringValue2,
STR(ROUND(235.415, 2),10,2) AS RoundValue1,
STR(ROUND('235.415', 2),10,2) AS RoundValue2,
STR(CAST('235.415' As NUMERIC(8,2)),10,2) As CastValue1
And, the result:
I know that the issue is a conversion to floating point data type when handling strings. I think the last option, i.e. casting to numeric, is the answer to my issue. However, I can't tell if this output is correct because the CAST guarantees there will not be an error, or because I got lucky for this specific instance.
Is there any type of SQL round function (or combination of functions) that takes string input, outputs string data, and doesn't involve floating point arithmetic? -- Thanks in advance!
NUMERIC/DECIMAL and MONEY don´t uses floating point arithmetic. The are in fact integers with a fixed comma.
Be aware that if you have large sums or do some calculations with these values, your rounding error can get pretty big, pretty fast. So it is advisable to take some moments to think about where you store a value with which precision and when you want to round.

Math.Net Complex32 Division giving NaN

Alright, so i have two large complex values. Top, and Bottom:
Top = 4.0107e+030
Bot = 5.46725E26 -2.806428e26i
when i divide these two numbers in Math.Net's Complex32, it gives me a NaN for both the real and imaginray. I am assuming that it has smething to do with the precision.
When i use Matlab i get the following:
Top/Bot = 5.8060e+003 +2.9803e+003i
When i use System.Numerics i get something very close to matlabs, at least in the correct order of magnitute:
Top/Bot = +5575.19343780947 +2676.09270239214i System.Numerics.Complex
i wonder, which one is the right one? and why is Math.Net giving me a wrong answer
I am running simulations and i very much care about the accuracy of the numerics?
Anyway to fix this? i will be dealing with a lot of large complex numbers.
Plus, if anyone knows of a good Complex library for .net with support for special functions such as the complemetary error function and the error function of Complex parameters, that would be great.
As i found out that Math.Net doesn't support cerf of a complex32
If you care about accuracy you should obviously use the double precision/64 bit type, not the single precision/32 bit one. Note that we only provide a Complex32 but no Complex (64) type in the normal package because we want you to use the Complex type provided in System.Numerics for compatibility - we only provide an equivalent Complex (64) type in the portable build as System.Numerics is not available there.
But in this specific case, this is not a problem of precision (or accuracy), but about range. Remember that 32 bit floating point numbers can not be larger than ~3.4e+38. Computing a complex division in normal direct form requires computing the square of both real and imaginary components of the denominator, which in your case will get out of range and become "infinity" and thus NaN in the final result.
Now, it might be possible to implement the division in a form that avoids computing the square when the denominator is larger than about 1e+19, but we have not done that yet in Math.NET Numerics (as there was no demand for it up to now). This would also not be a problem if the complex type would implement the polar form, but that is quite uncommon.

Exponents in Genetic Programming

I want to have real-valued exponents (not just integers) for the terminal variables.
For example, lets say I want to evolve a function y = x^3.5 + x^2.2 + 6. How should I proceed? I haven't seen any GP implementations which can do this.
I tried using the power function, but sometimes the initial solutions have so many exponents that the evaluated value exceeds 'double' bounds!
Any suggestion would be appreciated. Thanks in advance.
DEAP (in Python) implements it. In fact there is an example for that. By adding the math.pow from Python in the primitive set you can acheive what you want.
pset.addPrimitive(math.pow, 2)
But using the pow operator you risk getting something like x^(x^(x^(x))), which is probably not desired. You shall add a restriction (by a mean that I not sure) on where in your tree the pow is allowed (just before a leaf or something like that).
OpenBeagle (in C++) also allows it but you will need to develop your own primitive using the pow from <math.h>, you can use as an example the Sin or Cos primitive.
If only some of the initial population are suffering from the overflow problem then just penalise them with a poor fitness score and they will probably be removed from the population within a few generations.
But, if the problem is that virtually all individuals suffer from this problem, then you will have to add some constraints. The simplest thing to do would be to constrain the exponent child of the power function to be a real literal - which would mean powers would not be allowed to be nested. It depends on whether this is sufficient for your needs though. There are a few ways to add constraints like these (or more complex ones) - try looking in to Constrained Syntactic Structures and grammar guided GP.
A few other simple thoughts: can you use a data-type with a larger range? Also, you could reduce the maximum depth parameter, so that there will be less room for nested exponents. Of course that's only possible to an extent, and it depends on the complexity of the function.
Integers have a different binary representation than reals, so you have to use a slightly different bitstring representation and recombination/mutation operator.
For an excellent demonstration, see slide 24 of www.cs.vu.nl/~gusz/ecbook/slides/Genetic_Algorithms.ppt or check out the Eiben/Smith book "Introduction to Evolutionary Computing Genetic Algorithms." This describes how to map a bit string to a real number. You can then create a representation where x only lies within an interval [y,z]. In this case, choose y and z to be the of less magnitude than the capacity of the data type you are using (e.g. 10^308 for a double) so you don't run into the overflow issue you describe.
You have to consider that with real-valued exponents and a negative base you will not obtain a real, but a complex number. For example, the Math.Pow implementation in .NET says that you get NaN if you attempt to calculate the power of a negative base to a non-integer exponent. You have to make sure all your x values are positive. I think that's the problem that you're seeing when you "exceed double bounds".
Btw, you can try the HeuristicLab GP implementation. It is very flexible with a configurable grammar.

Objective C Math Formula Fail

noob here wants to calculate compound interest on iPhone.
float principal;
float rate;
int compoundPerYear;
int years;
float amount;
formula should be: amount = principal*(1+rate/compoundPerYear)^(rate*years)
I get slightly incorrect answer with:
amount = principal*pow((1+(rate/compoundPerYear)), (compoundPerYear*years));
I'm testing it with rate of .1, but debugger reports .100000001 .
Am I doing it wrong? Should I use doubles or special class (e.g., NSNumber)?
Thanks for any other ideas!
After further research it seems that the NSDecimalNumber class may be just what I need. Now I just have to figure out how to use this bad boy.
double will get you closer, but you can't represent 1/10 exactly in binary (using IEEE floating point notation, anyway).
If you're really interested, you can look at What Every Computer Scientist Should Know About Floating-Point Arithmetic. Link shamefully stolen from another SO thread.
The quick and dirty explanation is that floating point is stored in binary with bits that represents fractional powers of 2 (1/2, 1/4, 1/8, ...). There is simply no mathematical way to add up these fractions to exactly 1/10, thus 0.1 is not able to be exactly represented in IEEE floating point notation.
double extends the accuracy of the number by giving you more numerals before/after the radix, but it does not change the format of the binary in a way that can compensate for this. You'll just get the extra bit somewhere later down the line, most likely.
See also:
Why can’t decimal numbers be represented exactly in binary?
What’s wrong with using == to compare floats in Java?
and other similar threads.
Further expansion that I mulled over on the drive home from work: one way you could conceivably handle this is by just representing all of the monetary values in cents (as an int), then converting to a dollars.cents format when displaying the data. This is actually pretty easy, too, since you can take advantage of integer division's truncating when you convert:
int interest, dollars, cents;
interest = 16034; //$160.34, in cents
dollars = value / 100; //The 34 gets truncated: dollars == 160
cents = value % 100; //cents == 34
printf("Interest earned to date: $%d.%d\n", dollars, cents);
I don't know Objective-C, but hopefully this C example makes sense, too. Again, this is just one way to handle it. It would also be improved by having a function that does the string formatting whenever you need to show the data.
You can obviously come up with your own (even better!) way to do it, but maybe this will help get you started. If anyone else has suggestions on this one, I'd like to hear them, too!
Short answer: Never use floating point numbers for money.
The easy way that works across most platforms is to represent money as integer amounts of its smallest unit. The smallest unit is often something like a cent, although often 1/10 or 1/100 of a cent are the real base units.
On many platforms, there are also number types available that can represent fixed-point decimals.
Be sure to get the rounding right. Financial bookkeeping often uses banker's rounding.