Hi... Whenever possible I investigated pow() more the last days. I calculated billions of pow() values on windows/linux/mac and compared them.
First one my main test code. I did let it run in variety of numeric ranges. // powtest2.c // gcc -O3 -fno-builtin powtest2.c -o powtest (-lm) #include <stdio.h> #include <math.h> static printhexDouble(double val) { unsigned char *pointer = (char *)&val; int i; for (i = sizeof(double) - 1;i >= 0;i--) printf("%02x",pointer[i]); } int main(int argc,const char **argv) { double startPoint = 0.0; double endPoint = 3.0; int numPows = 100000000; int i = -numPows/2; int count = 0; double result,eps = 1.0; while (1.0 + eps > 1) eps = eps/2; eps = 1 + eps*2; double delta = (endPoint - eps) / (double)numPows; startPoint = eps; while (startPoint < endPoint) { // printhexDouble(startPoint); // printf(" %d ",i); result = pow(startPoint,i++); // printhexDouble(result); // printf("\n"); startPoint += delta; count++; } return 0; } Here are my results - both in regard of speed and accuraccy. When doing speed tests I used it in this way (with commented prints). When I did accurray test I had the prints enabled and redirected the output. With the given range for X^Y in this example: epsilon <= X < 3.0 -50000000 <= Y < 50000000 the code calculates 100 million pow()s. As Y always is non float powi() is used internally on windows when using mingw-w64 trunk code. For windows I did a test with this stock implementation and a patched version not using powi() at all. Hardware: Linux/Windows both are 100% identical machines running Core i7-3770. Mac: XServe3,1 with Xeon E5462 Accurraccy: =========== All implementations (mingw-w64/linux/mac) had differences in their results. For linux/mac the are neglectable. For mingw-w64 using powi() they are more severe. When using always pow() for mingw-w64 the differences also become neglectable. Number of different results: linux pow() <-> mac pow() : 92 Diffs only at the last digit mingw-w64 pow() <-> mingw-w64 powi(): 2752 Diff 8th-12th digit after dot mingw-w64 pow() <-> mac pow() : 83 Diffs only at the last digit mingw-w64 pow() <-> linux pow() : 127 Diffs only at the last digit The problem with powi() on mingw is that it is starting to produce non accurate results in a much higher number and already starting from the 8th digit after the dot this can severly impact calculation results if you use these results as component of subsequent other calculations (eg. image processing). We got different images on windows as on linux/mac. When avoiding powi() on windows our pictures became binary identical(!) on all 3 platforms. I was able to improve powi() a little bit by using long double calculations instead of double calculations. This improved accuraccy by ~2 digits. For very small X it did even solve the inaccuraccy at all - BUT was IMHO not changing the overall picture. Speed: ====== On Linux and Windows I am fortunate to have the exact same compiler version and the exact same hardware. It did execute the test code 10 times for each version and took the average. Execution time for 100 million different pow() calls: mingw-w64-crt-trunk (using powi()): 7.748s (+/- 16ms) mingw-w64-crt-trunk (no powi()) : 10.941s (+/- 15ms) linux : 5.783s (+/- 8ms) As one can see: Linux is superior in perfomance. 2nd best (in regard of speed) is the inaccurate powi() implementation. (Due to the different CPU type I did not conduct a speed test for mac as I could not compare it to a similar machine running linux/windows. I executed the test noncompetitive. On my machine it was around 21s.) MY conclusion: ============== For many people the accuraccy of powi() of mingw-w64 might be good enough, but when it comes to quality this is no longer true. I have changed pow() in our self build toolchain to no longer use powi(). QUALITY FIRST! Maybe it is better for mingw-w64 crt to also switch to plain pow() as default and to clearly state that powi() is possibly inaccurate! Have a nice weekend, Roland ------------------------------------------------------------------------------ _______________________________________________ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public