/* Check different calculations for powers of ten */ /* e.g. sometimes 'POW( 10, x )' != '1Ex' */ // this program is part of my 'deco-Math' project, // - WIP! -, striving for DEcimal COrrect calculations // (also with FP numbers acc. IEEE 754) // general idea and base program for this check: Morten Welinder, 'gnumeric', // Copyright this version (c) 2021 ... Bernhard Samtleben, Hamburg, Germany, // all rights reserved. // different compilers and options: // compile as: 'compiler' 'options' 'name' -o 'executeable name' **'-lm'** // reg. pow( x, y ), // icpx -Wall -Ofast -march=native mw_powers_10_t1_long.c -o mw_powers_10_t1_long -lm // -> "clang++: warning: treating 'c' input as 'c++' when in C++ mode, this behavior is deprecated [-Wdeprecated]" // -> clean execution, // dpcpp -Wall -Ofast -march=native mw_powers_10_t1_long.c -o mw_powers_10_t1_long -lm // -> silent compile and clean execution, // gcc -Wall -Ofast -march=native mw_powers_10_t1_long.c -o mw_powers_10_t1_long -lm // -> "mw_powers_10_t1_long.c:97:7: warning: incompatible implicit declaration of built-in function ‘exp10l’" // -> plenty deviations and clear fails in output, e.g. a = 0.000~ for high powers, // warning off with '__builtin_exp10l' but faults remain (less?), // gcc -Wall -O3 -march=native mw_powers_10_t1_long.c -o mw_powers_10_t1_long -lm // -> "mw_powers_10_t1_long.c:97:7: warning: incompatible implicit declaration of built-in function ‘exp10l’" // -> plenty deviations and clear fails in output, e.g. a = 0.000~ for high powers, // warning off with '__builtin_exp10l' but faults remain (less?), // gcc -O0 - faults and 'silent crash' at ~ i=70 // g++ - similar / identic? to gcc, #include // reg. e. g. 'pow( x, y )', #include // reg. e. g. 'atof( s )', #include // reg. e. g. 'printf( s )', static void compare_ab (const char *a, const char *b) { if( a[ 0 ] != '0' || b[ 0 ] != '0' ) { printf ("a = %s\n", a); int a_above = (a[0] == '1'); int b_above = (b[0] == '1'); a += a_above; b += b_above; int j = 0; while (*a && *b) { int da = a_above ? (*a - '0') : ('9' - *a); int db = b_above ? (*b - '0') : ('9' - *b); if (da != db) { // printf (" da %.d \n db %.d \n", da, db); if (a[1] == 0 && b[1] == 0) printf ("Midpoint\n"); else if (da < db) printf ("a is best after %d digits\n", j); else printf ("b is best after %d digits\n", j); return; } a++; b++; j++; } }else{ printf ("a = %s\n", a); int j = 0; while( ( a[ j ] == '0' && b [ j ] == '0' ) || ( a[ j ] == '.' && b [ j ] == '.' ) ) j++; // printf ("string identic for %d digits\n", j); int a_above = ( a[ j ] == '1'); int b_above = ( b[ j ] == '1'); // printf ("a[ j ] %c \n", a[ j ] ); // printf ("b[ j ] %c \n", b[ j ] ); // printf ("a_above %d b_above %d \n", a_above, b_above ); // printf ("a %s \nb %s \n", a, b ); j++; while( a[ j ] && b[ j ] ) { // is the comparison 'clean' for the last digit? int da = a_above ? ( a[ j ] - '0') : ('9' - a[ j ]); int db = b_above ? ( b[ j ] - '0') : ('9' - b[ j ]); // printf (" da %.d \n db %.d \nj %.d \n", da, db, j); // printf ("a[ j ] %c \n", a[ j ] ); // printf ("b[ j ] %c \n", b[ j ] ); // int db = b_above ? (*b - '0') : ('9' - *b); if (da != db) { // printf (" da %.d \n db %.d \nj %.d \n", da, db, j); // printf (" a[ j ] %.c \n b[ j ] %.c \n", a[ j ], b[ j ] ); if ( da < db ) printf ("a is best after %d digits\n", j); else printf ("b is best after %d digits\n", j); return; } // a++; // b++; j++; } printf ("Midpoint\n"); printf ("How did we get here?\n"); } } int main (int argc, char **argv) { // printf ("working ... \n"); int i; // running counter 'cases', for (i = -4952; i < 4933; i++) { // range to check, // for (i = 302; i < 330; i++) { // range to check, reduced against too much output, // for (i = -50; i < 50; i++) { // range to check, reduced against too much output, // for (i = 4932; i < 4933; i++) { // range to check, reduced against too much output, long double a, b; // working variables char btxt[5000], atxt[5000]; // arrays, // a = __builtin_exp10l( i ); // pow, other function, no warning from gcc, a = exp10l( i ); // pow, other function, this 'clean' with icpx, // a = __builtin_pow10l( i ); // 'undefined reference', // a = pow10l( i ); // 'not declared', // a = __builtin_powil( 10L, i ); // pow, other function, 'gcc', // a = powl( 10L, i ); // pow, sprintf (btxt, "1e%d", i); // scientific string, b = strtold( btxt, NULL ); // value of scientific string, seems not needing 'L' suffix, printf (" i = %d btxt = %s\n", i, btxt); // printf ("a = %.5000Lf\n", a ); // printf ("b = %.5000Lf\n", b ); if (a != b) { printf (" i = %d\n a = %.350Lf\n b = %.350Lf\n", i, a, b); printf ("btxt = %s\n", btxt); sprintf (atxt, "%.4990Lf", a); sprintf (btxt, "%.4990Lf", b); compare_ab (atxt, btxt); printf ("\n"); } } }