We are about to switch to a new forum software. Until then we have removed the registration on this forum.
Hi. I wanted a "for" loop from 0 to 1 incrementing by 0.1. Sample code is shown below but the maths is so inaccurate it doesn't reach 1.0. This appears to be a fundamental defect. I can repeat this in Processing-3.02, Processing-2.2.1 and with different Java versions. I get the same result on my Windows laptop and on my iMac.
There is also some inaccuracy when I repeat this test in pure Java (1.7.0_79) using Eclipse (Mars) but it is not quite as inaccurate.
In either case I would expect to add 0.1 with better accuracy.
Processing code:
import processing.opengl.*;
void setup() {
size( 480, 360);
print("double ");
for (double d=0; d<=1.0 ; d+=0.1) {
print(" ",d);
}
println();
print("float ");
for (float f=0; f<=1.0 ; f+=0.1) {
print(" ",f);
}
println();
print("i/10.0 ");
for (int i=0; i<=10 ; i++) {
double d2 = i/10.0;
print(" ", d2);
}
println();
print("i/(float)10.0 ");
for (int i=0; i<=10 ; i++) {
float f2 = i/(float)10.0;
print(" ", f2);
}
}
Processing Results:
double 0.0 0.10000000149011612 0.20000000298023224 0.30000000447034836 0.4000000059604645 0.5000000074505806 0.6000000089406967 0.7000000104308128 0.800000011920929 0.9000000134110451
float 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.70000005 0.8000001 0.9000001
i/10.0 0.0 0.10000000149011612 0.20000000298023224 0.30000001192092896 0.4000000059604645 0.5 0.6000000238418579 0.699999988079071 0.800000011920929 0.8999999761581421 1.0
i/(float)10.0 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0
Java Code:
public class LoopTest {
public static void main(String[] args) {
System.out.print("double ");
for (double d=0; d<=1.0 ; d+=0.1) {
System.out.print(" "+d);
}
System.out.println();
System.out.print("float ");
for (float f=0; f<=1.0 ; f+=0.1) {
System.out.print(" "+f);
}
System.out.println();
System.out.print("i/10.0 ");
for (int i=0; i<=10 ; i++) {
double d2 = i/10.0;
System.out.print(" "+d2);
}
System.out.println();
System.out.print("i/(float)10.0 ");
for (int i=0; i<=10 ; i++) {
float f2 = i/ (float)10.0;
System.out.print(" "+f2);
}
System.out.println();
}
}
Java Results;
double 0.0 0.1 0.2 0.30000000000000004 0.4 0.5 0.6 0.7 0.7999999999999999 0.8999999999999999 0.9999999999999999
float 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.70000005 0.8000001 0.9000001
i/10.0 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0
i/(float)10.0 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0
Any thoughts as to why such a simple calculation is so inaccurate?
:-S
Answers
https://forum.Processing.org/two/discussion/16136/double-problem
https://Processing.org/reference/float.html
The accuracy is better than 0.0001% which is very, very good.
Java like many languages uses 4 bytes to store a float that 32 bits which gives just 4,294,967,296 different combinations to store an infinite number of floating point so some innacuracy is to be expected.
The float n.000000000r occurs because of rounding errors in the the mantissa IIRC. A floating point number is written by the machine as a scientific number like 123*10^7. Rounding errors make those weird artifacts with floats.
To not have errors, use BigDecimal.
Using BD for loops:
Thanks to you all for your answers.
I see that there is a general problem representing decimals, and I can see there is lots of information out there on this topic.
If I use
d += 0.1d
the Processing result is then the same as Java.I will use BigDecimal in future where I need accuracy.