hello @all,

!!! --- sorry, i wrote too fast, rechecking unveiled that it wasn't 'pow' but 'exp10l' being 'clean' with intel compiler, sorry. --- !!!

find attached the program to recheck.

i can't say why it is, may be they just use the same algo for 'exp10l(x)' and '1Ex'?? or use another definition of 'long', e.g. QUADS?? can't even say if the results are accurate (nearest acc. IEEE)? such is stuff for better experienced people.

what i can say is 'for a consistent math near to humans decimals we need good powers of ten'. 'good' means consistent and correct. in that sense the icpx and dpcpp compilers with long doubles were the first to fulfill 'consistent'. that's a step forward.

(not being able to decide if a value is below, above or exact 100.000.000.000.000.000.000.000 because 10^23 is 'fuzzy' renders striving for precision gaming.)

it's not sure if the intel compilers are really 'better',  just to widen my horizon and have more options to compare against each other i'd still like to give it a try to compile gnumeric with 'intel'. any suggestions for that?

Best Regards,



b.

---

question in short: is there an easy / prepared way to compile gnumeric with another compiler? For example with 'clang' or 'intel'?
 
i have a little issue that POW or scientific strings are imprecise, they don't match for e.g. 10^23 and 1E23 in gnumeric with doubles.

it's less a gnumeric but a compiler / library problem, Morten filed a bug for it <https://sourceware.org/bugzilla/show_bug.cgi?id=28472>

set up and compiled for 'long doubles' there are many more deviations in gnumeric and with the test program.

just poking around i tried the intel compiler (oneAPI suite, based on clang / LLVM, free) and found:

with doubles plenty of fails, except with '-O0', there it's only one ( 10^23 ).

but! with 'long' error free from 10^-4953 .. 10^4933 ... ('error free': consistent between '10^x' and '1Ex' ).

even with '-Ofast'

i'm astonished,

can someone retest? intel oneAPI download and install, needs setting the environment with 'setvars.sh', and compile with 'icpx ....', names and options i left as for gcc.

try any steps to compare '1Ex' to '10^x' or 'POW( 10, x )', e.g. take the test program from Morten and adapt for long doubles and negative powers.

Best Regards,



b.

P.S. please be tolerant, I'm not a professional but just look, poke and try around, sometimes it results in good new things ... but not always ;-)

/* 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 <math.h>       // reg. e. g. 'pow( x, y )', 
#include <stdlib.h>     // reg. e. g. 'atof( s )', 
#include <stdio.h>      // 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");
                }
        }
}
_______________________________________________
gnumeric-list mailing list
gnumeric-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gnumeric-list

Reply via email to