Julia prints wrong Pi digits with #printf - printf

When I compare the output of #printf("%.50f", pi) with BigFloat(pi) the results are different from 16th places. This might be due to type inversion. But I like to go deeper to understands better what is happening here?
Julia> #printf("%.50f", pi)
3.14159265358979311599796346854418516159057617187500
julia> BigFloat(pi)
3.1415926535897932384626433832795028841971693993751058209749445923078164062861

pi, along with several other well-known irrational numbers, have their own special type Irrational. These are stored to Float64 precision, and I don't think there are any plans to change this going into v1.0.
If you want higher precision than that, use BigFloat(pi), as you have done in the question.
But the key point here is that #printf("%.50f", pi) does not automatically wrap a call to BigFloat(pi). To get that behaviour you would need #printf("%.50f", BigFloat(pi)). What you are actually running up against here has nothing to do with pi per se, but rather the manner in which floating point numbers are printed in Julia (in fact, in most programming languages). To see what I mean, try:
#printf("%.50f", rand())
which is essentially asking Julia to print a random Float64 from the [0,1] interval to 50 decimal places, which is obviously a nonsense request past about 16 decimal places. So why do you get a whole lot of random numbers after the 16th place?
Quickly and accurately printing Float64 in a nice human-readable format is a topic in its own right. If you are really interested in what is happening, then this article should get you started, but the simple answer is don't pay attention to anything after the usual floating point precision.
Also, AFAIK, this kind of behaviour is common to most programming languages. This is not Julia-specific behaviour you are observing, but rather behaviour at the processor level.

Related

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

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.)

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()

Excel 2007 VBA Calculations Wrong

When you run a VBA macro that performs numeric calculations which result in a decimal value, the result that is returned may be incorrect.
Here are a couple of examples:
Dim me_wrong as Double
me_wrong = 1000 - 999.59
RESULT = 0.409999999999968
Dim me_wrong_too as Double
me_wrong_too = 301.84 - 301
RESULT = 0.839999999999975
I have never ever noticed this before. What on earth is going on???
I have seen the following article about Office 97 but can't find anything about a bug in Excel 2007:
http://support.microsoft.com/default.aspx?scid=kb;en-us;165373
Plus it doesn't explain why I have never seen it before.
Please help!
The explanation for the problem from Office 97 and VBA is equally applicable going forward into Excel 2007. The core VBA system is largely unchanged despite the migration into later versions, hence the same kinds of accuracy gremlins that plague older VBA macros will persist.
The fundamental problem lies with the inherent inaccuracy in the representation of fractional numbers in binary, and how at least some effort to mitigate that inaccuracy was made with IEEE floating point representations. There is a very decent treatment of the subject of IEEE representation at this location.
*Edit: Just a minor bit of extra info for detail. *
For a very simple example that illustrates this issue in a trivial case, consider a situation in which decimals are represented as sums of inverse powers of two, eg 2-1, 2-2, 2-3, and so on. That ends up looking like .5, .25, .125, and so on. If you're representing exactly those numbers, all is good. However, consider a number like .761; 2-1+2-2 gets you to .750, but now you need .011. 2-3 (.125) is too big, but 2-4 (.0625) is too small...so you keep going to smaller powers of two, realizing you'll never quite represent the number precisely.
The choice becomes where you stop resolving and accept the inherent inaccuracy as being "good enough" for the problem you're solving/modeling.
It is, unfortunately, not a bug.
Double representation follows a fixed point notation, where the mantissa is a number "1,x" with "1" being implicit. There's an exponent and a sign, which makes the full representation in Base 2.
The pertinent issue is Base=2 which makes "x" in "1,x" to be a finite-precision (53bits of it) fractional binary. Think x= a52*1/2+a51*1/4+a50*1/8+...+a*1**1/(2^52)+a0*1/(2^53), where a< i > are the bits in the mantissa.
Try attaining 1,4 with this representation, and you hit the precision wall... there is no finite decomposition of 0.4 in binary weights. So the norm specifies you should represent the number immediately before the real one, which leaves you with 0,39999..9997346 (or whatever the tail is).
The "good" news is, and I've just burned four "c" coding days last week on that subject, you can do without Doubles if you represent your number using a very small scale (say 10^-9), store then in very large variables (long64), and do your display functions using nothing but integers (mathematically slicing away integral and fractional parts through integer division and their remainders). A treat, I tell you... not.

Why see -0,000000000000001 in access query?

I have an sql:
SELECT Sum(Field1), Sum(Field2), Sum(Field1)+Sum(Field2)
FROM Table
GROUP BY DateField
HAVING Sum(Field1)+Sum(Field2)<>0;
Problem is sometimes Sum of field1 and field2 is value like: 9.5-10.3 and the result is -0,800000000000001. Could anybody explain why this happens and how to solve it?
Problem is sometimes Sum of field1 and
field2 is value like: 9.5-10.3 and the
result is -0.800000000000001. Could
anybody explain why this happens and
how to solve it?
Why this happens
The float and double types store numbers in base 2, not in base 10. Sometimes, a number can be exactly represented in a finite number of bits.
9.5 → 1001.1
And sometimes it can't.
10.3 → 1010.0 1001 1001 1001 1001 1001 1001 1001 1001...
In the latter case, the number will get rounded to the closest value that can be represented as a double:
1010.0100110011001100110011001100110011001100110011010 base 2
= 10.300000000000000710542735760100185871124267578125 base 10
When the subtraction is done in binary, you get:
-0.11001100110011001100110011001100110011001100110100000
= -0.800000000000000710542735760100185871124267578125
Output routines will usually hide most of the "noise" digits.
Python 3.1 rounds it to -0.8000000000000007
SQLite 3.6 rounds it to -0.800000000000001.
printf %g rounds it to -0.8.
Note that, even on systems that display the value as -0.8, it's not the same as the best double approximation of -0.8, which is:
- 0.11001100110011001100110011001100110011001100110011010
= -0.8000000000000000444089209850062616169452667236328125
So, in any programming language using double, the expression 9.5 - 10.3 == -0.8 will be false.
The decimal non-solution
With questions like these, the most common answer is "use decimal arithmetic". This does indeed get better output in this particular example. Using Python's decimal.Decimal class:
>>> Decimal('9.5') - Decimal('10.3')
Decimal('-0.8')
However, you'll still have to deal with
>>> Decimal(1) / 3 * 3
Decimal('0.9999999999999999999999999999')
>>> Decimal(2).sqrt() ** 2
Decimal('1.999999999999999999999999999')
These may be more familiar rounding errors than the ones binary numbers have, but that doesn't make them less important.
In fact, binary fractions are more accurate than decimal fractions with the same number of bits, because of a combination of:
The hidden bit unique to base 2, and
The suboptimal radix economy of decimal.
It's also much faster (on PCs) because it has dedicated hardware.
There is nothing special about base ten. It's just an arbitrary choice based on the number of fingers we have.
It would be just as accurate to say that a newborn baby weighs 0x7.5 lb (in more familiar terms, 7 lb 5 oz) as to say that it weighs 7.3 lb. (Yes, there's a 0.2 oz difference between the two, but it's within tolerance.) In general, decimal provides no advantage in representing physical measurements.
Money is different
Unlike physical quantities which are measured to a certain level of precision, money is counted and thus an exact quantity. The quirk is that it's counted in multiples of 0.01 instead of multiples of 1 like most other discrete quantities.
If your "10.3" really means $10.30, then you should use a decimal number type to represent the value exactly.
(Unless you're working with historical stock prices from the days when they were in 1/16ths of a dollar, in which case binary is adequate anyway ;-) )
Otherwise, it's just a display issue.
You got an answer correct to 15 significant digits. That's correct for all practical purposes. If you just want to hide the "noise", use the SQL ROUND function.
I'm certain it is because the float data type (aka Double or Single in MS Access) is inexact. It is not like decimal which is a simple value scaled by a power of 10. If I'm remembering correctly, float values can have different denominators which means that they don't always convert back to base 10 exactly.
The cure is to change Field1 and Field2 from float/single/double to decimal or currency. If you give examples of the smallest and largest values you need to store, including the smallest and largest fractions needed such as 0.0001 or 0.9999, we can possibly advise you better.
Be aware that versions of Access before 2007 can have problems with ORDER BY on decimal values. Please read the comments on this post for some more perspective on this. In many cases, this would not be an issue for people, but in other cases it might be.
In general, float should be used for values that can end up being extremely small or large (smaller or larger than a decimal can hold). You need to understand that float maintains more accurate scale at the cost of some precision. That is, a decimal will overflow or underflow where a float can just keep on going. But the float only has a limited number of significant digits, whereas a decimal's digits are all significant.
If you can't change the column types, then in the meantime you can work around the problem by rounding your final calculation. Don't round until the very last possible moment.
Update
A criticism of my recommendation to use decimal has been leveled, not the point about unexpected ORDER BY results, but that float is overall more accurate with the same number of bits.
No contest to this fact. However, I think it is more common for people to be working with values that are in fact counted or are expected to be expressed in base ten. I see questions over and over in forums about what's wrong with their floating-point data types, and I don't see these same questions about decimal. That means to me that people should start off with decimal, and when they're ready for the leap to how and when to use float they can study up on it and start using it when they're competent.
In the meantime, while it may be a tad frustrating to have people always recommending decimal when you know it's not as accurate, don't let yourself get divorced from the real world where having more familiar rounding errors at the expense of very slightly reduced accuracy is of value.
Let me point out to my detractors that the example
Decimal(1) / 3 * 3 yielding 1.999999999999999999999999999
is, in what should be familiar words, "correct to 27 significant digits" which is "correct for all practical purposes."
So if we have two ways of doing what is practically speaking the same thing, and both of them can represent numbers very precisely out to a ludicrous number of significant digits, and both require rounding but one of them has markedly more familiar rounding errors than the other, I can't accept that recommending the more familiar one is in any way bad. What is a beginner to make of a system that can perform a - a and not get 0 as an answer? He's going to get confusion, and be stopped in his work while he tries to fathom it. Then he'll go ask for help on a message board, and get told the pat answer "use decimal". Then he'll be just fine for five more years, until he has grown enough to get curious one day and finally studies and really grasps what float is doing and becomes able to use it properly.
That said, in the final analysis I have to say that slamming me for recommending decimal seems just a little bit off in outer space.
Last, I would like to point out that the following statement is not strictly true, since it overgeneralizes:
The float and double types store numbers in base 2, not in base 10.
To be accurate, most modern systems store floating-point data types with a base of 2. But not all! Some use or have used base 10. For all I know, there are systems which use base 3 which is closer to e and thus has a more optimal radix economy than base 2 representations (as if that really mattered to 99.999% of all computer users). Additionally, saying "float and double types" could be a little misleading, since double IS float, but float isn't double. Float is short for floating-point, but Single and Double are float(ing point) subtypes which connote the total precision available. There are also the Single-Extended and Double-Extended floating point data types.
It is probably an effect of floating point number implementations. Sometimes numbers cannot be exactly represented, and sometimes the result of operations is slightly off what we may expect for the same reason.
The fix would be to use a rounding function on the values to cut off the extraneous digits. Like this (I've simply rounded to 4 significant digits after the decimal, but of course you should use whatever precision is appropriate for your data):
SELECT Sum(Field1), Sum(Field2), Round(Sum(Field1)+Sum(Field2), 4)
FROM Table
GROUP BY DateField
HAVING Round(Sum(Field1)+Sum(Field2), 4)<>0;

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.