float a = 6378388.0;
float b = 6356911.94613;
float e = sqrt(sq(a) - sq(b))/a;
println("e =", e);
float e2 = sqrt(sq(a) - sq(b))/b;
println("e' =", e2);
This code prints some values that, even thought they are similar to the expected ones, differ a bit on the last numbers. This could seem unsignificant, but I’m working with coordinates and I need the highest precission possible. Here there is a table with the values given by the example I’m following, the values that Python printed (because I made a test with Python to see if other programming languages could do it well) and the values Processing did:
Source
e
e’
Example
0.08199189
0.08226889
Python
0.08199188997511561
0.08226888960338334
Processing
0.08199162
0.08226862
As you can see, they are similar, but Processing’s last numbers make no sense. I don’t know why do this happen, and I couldn’t find any information about it.
This is the Python code I used, if you think it can be useful to solve the problem with Processing:
import math
a = 6378388.0
b = 6356911.94613
e = math.sqrt(a**2-b**2)/a
e2 = math.sqrt(a**2-b**2)/b
print(e, e2)
Processing uses the 32-bit float primitive datatype as its default floating-point precision:
For 64-bit floating-point precision we use double instead:
However, it’s not enough to simply declare variables w/ primitive datatype double!
We also must suffix any floating-point literal w/ a d, so it uses a 64-bit storage: 6356911.94613d
Without it, 6356911.94613 would be coerced to 6356912.0 due to 32-bit storage constraint!
Plus all Processing’s math functions need to be replaced w/ their corresponding Java’s Math class version:
final double a = 6378388;
final double b = 6356911.94613d;
final double ab = Math.sqrt(a*a - b*b);
final double e1 = ab / a;
println("e1 =", e1);
final double e2 = ab / b;
println("e2 =", e2);
Well spotted and I have corrected the code in my post. Although not needed for a I have added it anyway to indicate to the coder that a literal double value is expected here. Useful if the value has to be edited later.
The issue was the internal (invisible) conversion of the number to String performed by the text() command (or the println() command). So even when the program got it right, the output was wrong.
To avoid this, glv suggested Long.toString(number) which was great.
The only overloading datatype version missing for both println() & print() is short; which would be auto-coerced to int anyways:
Therefore both printing functions should have no problem at all console-logging whatever datatype argument we pass to them; with the notably only exception for short[] arrays!
BtW, datatype short[] is the only datatype Processing functions can’t properly deal with at all!
On the other hand, method text() is indeed more restrictive for the available overloading datatype signatures for its parameters.
Besides the obviously String datatype, it has overloaded signatures for int, float, char and even char[] datatypes.
Arguments of primitive datatypes byte & short would be nicely auto-coerced to int.
However, we wouldn’t be able to pass arguments of primitive datatypes boolean, long and double; neither for any non-primitive datatypes apart from String!
All of those non-supported datatypes would need to be converted to String before invoking text(), as you have already found out.
But a much simpler "" + arg would coerce any of those argument datatypes to String just fine, as long as they’re not arrays.
In the Java class libraries all internal math calculations are done using the double data type but when Processing was first created they decided to use float as the default data type for the Processing language.
So when the Processing executes the statement float v = sqrt(3.14159);
it calls the equivalent Java method parameter value is passed to the Java method Math.sqrt(3.14059);
but this method returns a double which has to be cast to a float. Using the Processing sqrt method involves
an extra function call
a cast of the Java result back to a float
Personally I think using float instead of double was a mistake, it has 2 adverse consequences
Decreases performance. With modern processors and JVM optimisation this should not be a major problem, certainly it has never impacted me but might be an issue for others.
Some problems require the use of the double data type because they cannot be solved using float variables. For me this is the more critical issue and all my Processing libraries use the double data type internally because of this.
Though I’m intrigued by your “float was a mistake” statement.
In my mind, close to all discussions on limitations and underperformance in Processing can be answered with “it’s a deliberate compromise in service of our core target audience”.
My theory on why float made it over double; Put yourself in the mind of that coding newbie, starting out with drawing a few basic shapes onto the screen. As if grokking the concept of a variable wasn’t enough, they’re also dealing with a typed programming language. The first variable types they’ll encounter are most likely int and float. The good thing is, there are number analogues they know already – “whole numbers” and “numbers with a decimal point”. Being able to fall back on these real world analogues in an otherwise alien programming environment is super valuable.
Imagine now that the next type after int is a double. “It’s a number with a decimal point, but in fact you need to think of two different types of decimal point numbers, float and double, and you want to use one for tasks X and the other for tasks Y and in Processing we are using the more advanced version”. That’s immediately a bigger hurdle to deal with. And if you can consciously hide away that complexity by way of simplification, then I’m all for it, even if it means to let go of the advantages double can offer.
But maybe those arguments are irrelevant to one of the major user groups in Processing? Truth be told, I’ve never written a sketch that required double and I’m pretty sure I went 10+ years fuzzing around in Processing before even becoming aware that there’s an “older sibling to float”.
All this being said, I’m fully willing to accept that I’m way off with my “core target audience” argument. Possibly I’m sorely underestimating what you can expect a newbie to understand. But I’ve seen so many newcomer questions trip over such banal topics, that I feel the decision to err on the side of simplicity over power is the correct one.
Consider metallurgists, doctors, engineers, artists, footballers, actors, builders, plumbers … every specialist discipline has its own ‘vocabulary’. This is essential because it allows specialists to communicate complex details, information and ideas accurately and rapidly; thereby making it easier to improve and enhance their specialism.
As pre-school infants we are exposed to whole numbers but once at school we learn to use fractions followed by decimals. It allowed us to count and share the sweets out equally Later we would be introduced to new words like integer numbers and floating point numbers.
Now consider the newbie to Processing which is basically a wrapper framework built around Java which is a strongly-typed language. The newbie has to learn a new ‘vocabulary’ and my contention is we could teach either
float is the data type to be used for decimal numbers, or
double is the data type to be used for decimal numbers
From a teaching and learning perspective I do not see the problem with going with (2). After all the newbie is going to have a lot more complex concepts to master if they want to get on.
Did you know that Processing created the keyword color as an alias to int
int c = color(255, 128, 128);
color c = color(255, 128, 128);
Both of these statements do the same thing but in the second line color represents both a data type and a function name. Personally I think this was their second and last mistake when they created Processing.
Don’t get me wrong, I think Processing is a wonderful way to get started in programming but the newbie must be prepared to learn the vocabulary of the computer programmer.
Finally the creators of Processing must be congratulated on making the object orientated language Java look like a procedural language and thereby making it accessible to all.
Hmm… I fell for what the Germans call Gefährliches Halbwissen. I assumed that in programming languages float was always the “general use” type and double the “speciality case” type. Hence my “Why apply the more advanced type as default?” stance. Turns out this differentation ain’t necessarily so. Goes to show that I need to understand more and better, before digging my heels in.
static is a Java keyword that is used to declare fields, methods and classes which can be accessed w/o instantiating the class they belong to; meaning they are independent from a particular instance of its class.
So the method PApplet.sqrt() can be invoked w/o requiring to instantiate its PApplet class.
The keyword final when used to declare fields, variables & parameters, it disallows them to be re-assigned w/ another value; although mutable objects they refer to can still be changed.
final methods can’t be @override by subclasses; and final classes themselves can’t be subclassed at all.