|
From: Richard C. W. <drsavage@q.com> - 2010-06-04 16:37:04
|
Kein-Hong and Ben, Thanks for your responses. Kein-Hong wrote: > A float has about 7 decimal digits of precision. For whatever > reasons, your result has a 1 plus 'a very small number'. So, > taking 8 digits of displayed result (since the '1' at the front > doesn't 'contribute' a full 1 digits of precision): > > 1.0000014 > 1.0000015 > 1.0000017 > > Nothing wrong with the compiler or the machine. and Ben added: > There is something very wrong somewhere because if you are performing > > x / 640.0 * 9e-6 > > For 0.0 <= x <= 640.0 > > Your results should be way less than 1. Then Kein-Hong correctly deduced: > Sounds like a throwaway test of some sort when zooming in failed > (or turned blocky) due to lack of numeric precision. Sorry, my description of my test wasn't clear. The results I posted were from a stand-alone, throw away test program that made the same calculation that I'm using in my main program. The calculation is: Domain_x = ((Pixel_x / 640.0) * 9.0e-6) + 1.0 I've run the same test using another programming language, on the very same machine. With the second programming language, I have full control over how the calculation is performed. In this case, I'm starting with the integer value Pixel_x, pushing it onto the FPU's stack, then pushing the other floating point values onto the stack and performing the math ops. The results are in the third column of numbers below. Pixel_x = 100 Domain_x = 1.00000143051147460000 1.000001406250000 Pixel_x = 101 Domain_x = 1.00000143051147460000 1.000001420312500 Pixel_x = 102 Domain_x = 1.00000143051147460000 1.000001434375000 Pixel_x = 103 Domain_x = 1.00000143051147460000 1.000001448437500 Pixel_x = 104 Domain_x = 1.00000143051147460000 1.000001462500000 Pixel_x = 105 Domain_x = 1.00000143051147460000 1.000001476562500 Pixel_x = 106 Domain_x = 1.00000154972076420000 1.000001490625000 Pixel_x = 107 Domain_x = 1.00000154972076420000 1.000001504687500 Pixel_x = 108 Domain_x = 1.00000154972076420000 1.000001518750000 Pixel_x = 109 Domain_x = 1.00000154972076420000 1.000001532812500 Pixel_x = 110 Domain_x = 1.00000154972076420000 1.000001546875000 Pixel_x = 111 Domain_x = 1.00000154972076420000 1.000001560937500 Pixel_x = 112 Domain_x = 1.00000154972076420000 1.000001575000000 Pixel_x = 113 Domain_x = 1.00000154972076420000 1.000001589062500 Pixel_x = 114 Domain_x = 1.00000154972076420000 1.000001603125000 Pixel_x = 115 Domain_x = 1.00000166893005370000 1.000001617187500 Pixel_x = 116 Domain_x = 1.00000166893005370000 1.000001631250000 Pixel_x = 117 Domain_x = 1.00000166893005370000 1.000001645312500 Pixel_x = 118 Domain_x = 1.00000166893005370000 1.000001659375000 Pixel_x = 119 Domain_x = 1.00000166893005370000 1.000001673437500 Note the difference in granularity. The third column changes with each different integer input, whereas the MinGW results are almost an average of the third-column result over their range, and change only after an integer difference of 9. I do a great deal of CFD and numerical modeling work, and the third-column results are the kind of precision I'm used to seeing from floating point on the PC. I hope that helps to better illustrate the problem. Any ideas? Regards, Rich Wagner |
|
From: Richard C. W. <drsavage@q.com> - 2010-06-04 17:02:35
|
Kein-Hong and Ben: Looking at the user's manual for the programming language of the second test, I see that the calculations were made using the PC's "80-bit, extended real" format. I believe that means that the mantissa is kept as an 80-bit number. It appears that the other formats available on the PC's FPU are 64-bit for "double precision" and 32-bit for "single precision". Using doubles instead of floats in the MinGW version of the test program, I get the following results: Pixel_X = 100 x = 1.00000140625000000000 1.000001406250000 Pixel_X = 101 x = 1.00000142031250010000 1.000001420312500 Pixel_X = 102 x = 1.00000143437500010000 1.000001434375000 Pixel_X = 103 x = 1.00000144843749990000 1.000001448437500 Pixel_X = 104 x = 1.00000146250000000000 1.000001462500000 Pixel_X = 105 x = 1.00000147656250000000 1.000001476562500 Pixel_X = 106 x = 1.00000149062500010000 1.000001490625000 Pixel_X = 107 x = 1.00000150468749990000 1.000001504687500 Pixel_X = 108 x = 1.00000151875000000000 1.000001518750000 Pixel_X = 109 x = 1.00000153281250000000 1.000001532812500 Pixel_X = 110 x = 1.00000154687500010000 1.000001546875000 Pixel_X = 111 x = 1.00000156093749990000 1.000001560937500 Pixel_X = 112 x = 1.00000157500000000000 1.000001575000000 Pixel_X = 113 x = 1.00000158906250000000 1.000001589062500 Pixel_X = 114 x = 1.00000160312500010000 1.000001603125000 Pixel_X = 115 x = 1.00000161718749990000 1.000001617187500 Pixel_X = 116 x = 1.00000163125000000000 1.000001631250000 Pixel_X = 117 x = 1.00000164531250000000 1.000001645312500 Pixel_X = 118 x = 1.00000165937500010000 1.000001659375000 Pixel_X = 119 x = 1.00000167343749990000 1.000001673437500 which are pretty much identical to the third column. So in this test case, it was just a difference in the precision of the calculations. In my Mandelbrot program, I actually rewrote it to use doubles, rather than floats, and I didn't see much difference. Perhaps I did something wrong, or perhaps it only makes a small difference. Regardless, mystery solved. Thanks for your help. Regards, Rich Wagner |
|
From: KHMan <kei...@gm...> - 2010-06-04 17:28:41
|
Richard C. Wagner wrote: > Kein-Hong and Ben: > Looking at the user's manual for the programming language of the second > test, I see that the calculations were made using the PC's "80-bit, > extended real" format. I believe that means that the mantissa is kept > as an 80-bit number. [snip] Nope, and at this point I'd recommend an hour or two of Googling and Wikipedia-ing on floating point number formats thereabouts. :-) > [snip] > which are pretty much identical to the third column. So in this test > case, it was just a difference in the precision of the calculations. In > my Mandelbrot program, I actually rewrote it to use doubles, rather than > floats, and I didn't see much difference. Perhaps I did something > wrong, or perhaps it only makes a small difference. Regardless, mystery > solved. Thanks for your help. doubles give another 29 bits of precision, about 9 decimal digits. You'd zoom in much more in the high-dwell areas. It's a big difference -- floats won't work at all at high zooms! You need doubles or better at high zooms. On most x86 CPUs today, I don't think floats is any faster than doubles, so you might as well stick to doubles. You should also try compiling for SSE2/3, I suspect there is a speed boost lurking in there somewhere... -- Cheers, Kein-Hong Man (esq.) Kuala Lumpur, Malaysia |
|
From: Steve C. <ste...@gm...> - 2010-06-04 16:48:42
|
On 06/04/2010 12:36 PM, Richard C. Wagner wrote: > Kein-Hong and Ben, > > Thanks for your responses. Kein-Hong wrote: > > >> A float has about 7 decimal digits of precision. For whatever >> reasons, your result has a 1 plus 'a very small number'. So, >> taking 8 digits of displayed result (since the '1' at the front >> doesn't 'contribute' a full 1 digits of precision): >> >> 1.0000014 >> 1.0000015 >> 1.0000017 >> >> Nothing wrong with the compiler or the machine. >> > and Ben added: > > >> There is something very wrong somewhere because if you are performing >> >> x / 640.0 * 9e-6 >> >> For 0.0<= x<= 640.0 >> >> Your results should be way less than 1. >> > Then Kein-Hong correctly deduced: > > >> Sounds like a throwaway test of some sort when zooming in failed >> (or turned blocky) due to lack of numeric precision. >> > > Sorry, my description of my test wasn't clear. The results I posted were > from a stand-alone, throw away test program that made the same calculation > that I'm using in my main program. The calculation is: > > Domain_x = ((Pixel_x / 640.0) * 9.0e-6) + 1.0 > > I've found that the problem is usually in the source code that *isn't* shown. Could you post a complete, self-contained, short program that illustrates the problem? |