diff --git a/bn_mp_get_double.c b/bn_mp_get_double.c index 6a4f2a5fe..a50effd3e 100644 --- a/bn_mp_get_double.c +++ b/bn_mp_get_double.c @@ -24,6 +24,7 @@ double mp_get_double(const mp_int *a) } return (a->sign == MP_NEG) ? -d : d; } + #endif /* ref: $Format:%D$ */ diff --git a/bn_mp_set_double.c b/bn_mp_set_double.c index c96a3b353..25bb6d7c0 100644 --- a/bn_mp_set_double.c +++ b/bn_mp_set_double.c @@ -13,6 +13,7 @@ */ #if defined(__STDC_IEC_559__) || defined(__GCC_IEC_559) +/* defined by GNU C, SAS/C, and Stratus VOS C -- in that order */ int mp_set_double(mp_int *a, double b) { uint64_t frac; diff --git a/demo/demo.c b/demo/demo.c index 642eab73f..23ed99c37 100644 --- a/demo/demo.c +++ b/demo/demo.c @@ -98,6 +98,36 @@ static void _cleanup(void) #endif } #if LTM_DEMO_TEST_VS_MTEST == 0 + +#if ((defined __m68k__) || (defined __MC68K__) || (defined M68000)) +/* VERY simpel comparing function, for use in this case and this case only! */ +/* MIN() macro is in tommath_private.h */ +#ifndef MIN +#define MIN(x, y) (((x) < (y)) ? (x) : (y)) +#endif +/* avoid libmath */ +static double s_abs(double s_d){ + return (s_d < 0.0)?-s_d:s_d; +} +#include +/* check relative error against DBL_EPSILON. Input numbers are big enough to do so */ +static int s_compare_doubles(double s_a, double s_b){ + double abs_a, abs_b, delta; + + /* NaN, inf's, small numbers, and subnormals ignored, not needed in this case */ + if (s_a == s_b) { + return 1; + } + abs_a = s_abs(s_a); + abs_b = s_abs(s_b); + delta = s_abs(s_a - s_b); + + return ( (delta/MIN(abs_a, abs_b)) < DBL_EPSILON ); +} +#define S_COMPARE_DOUBLES(x,y) s_compare_doubles( (x), (y)) +#else +#define S_COMPARE_DOUBLES(x,y) ( (x) == (y)) +#endif struct mp_sqrtmod_prime_st { unsigned long p; unsigned long n; @@ -166,6 +196,8 @@ int main(void) unsigned long long q, r; mp_digit mp; int i, n, err, should, cnt; + double dbl_count; + #endif if (mp_init_multi(&a, &b, &c, &d, &e, &f, NULL)!= MP_OKAY) @@ -483,6 +515,9 @@ int main(void) /* test mp_get_double/mp_set_double */ #if defined(__STDC_IEC_559__) || defined(__GCC_IEC_559) printf("\n\nTesting: mp_get_double"); + + /*printf(" with a m86k cpu ");*/ + if (mp_set_double(&a, +1.0/0.0) != MP_VAL) { printf("\nmp_set_double should return MP_VAL for +inf"); return EXIT_FAILURE; @@ -500,28 +535,86 @@ int main(void) return EXIT_FAILURE; } +#include + if (mp_set_double(&a, DBL_MAX) != MP_OKAY) { + printf("\nmp_set_double(DBL_MAX) failed"); + return EXIT_FAILURE; + } + if (DBL_MAX != mp_get_double(&a)) { + printf("\nmp_get_double(DBL_MAX) bad result! %20.2f != %20.2f \n", DBL_MAX, mp_get_double(&a)); + return EXIT_FAILURE; + } + if (mp_set_double(&a, DBL_MIN) != MP_OKAY) { + printf("\nmp_set_double(DBL_MIN) failed"); + return EXIT_FAILURE; + } + if (0.0 != mp_get_double(&a)) { + printf("\nmp_get_double(DBL_MIN) bad result! %20.2f != %20.2f \n", DBL_MAX, mp_get_double(&a)); + return EXIT_FAILURE; + } + + dbl_count = 2.0; + for (i = 0; i < 301; ++i) { + if (mp_set_double(&a, -dbl_count) != MP_OKAY) { + printf("\nmp_set_double(dbl_count) failed"); + return EXIT_FAILURE; + } + if (-dbl_count != mp_get_double(&a)) { + printf("\nmp_get_double(+dbl_count) at i = %d bad result! %20.20f != %20.20f\n", + i, -dbl_count, mp_get_double(&a) ); + return EXIT_FAILURE; + } + dbl_count = (dbl_count * 2.0); + } + + dbl_count = 2.0; + for (i = 0; i < 301; ++i) { + if (mp_set_double(&a, dbl_count) != MP_OKAY) { + printf("\nmp_set_double(+dbl_count - 1) failed"); + return EXIT_FAILURE; + } + if ( !S_COMPARE_DOUBLES(dbl_count, mp_get_double(&a)) ) { + printf("\nmp_get_double(+dbl_count - 1) at i = %d bad result! %20.20f != %20.20f\n", + i, dbl_count, mp_get_double(&a) ); + return EXIT_FAILURE; + } + dbl_count = (dbl_count * 2.0) -1; + } + dbl_count = 2.0; + for (i = 0; i < 301; ++i) { + if (mp_set_double(&a, -dbl_count) != MP_OKAY) { + printf("\nmp_set_double((-dbl_count) - 1) failed"); + return EXIT_FAILURE; + } + if ( !S_COMPARE_DOUBLES(-dbl_count, mp_get_double(&a)) ) { + printf("\nmp_get_double((-dbl_count) - 1) at i = %d bad result! %20.20f != %20.20f\n", + i, -dbl_count, mp_get_double(&a) ); + return EXIT_FAILURE; + } + dbl_count = (dbl_count * 2.0) -1; + } + for (i = 0; i < 1000; ++i) { int tmp = rand(); - double dbl = (double)tmp * rand() + 1; + double dbl = (double) tmp * rand() + 1.0; if (mp_set_double(&a, dbl) != MP_OKAY) { printf("\nmp_set_double() failed"); return EXIT_FAILURE; } - if (dbl != mp_get_double(&a)) { - printf("\nmp_get_double() bad result!"); + if ( !S_COMPARE_DOUBLES(dbl, mp_get_double(&a))) { + printf("\nmp_get_double() bad result! %20.2f != %20.2f \n", dbl, mp_get_double(&a)); return EXIT_FAILURE; } if (mp_set_double(&a, -dbl) != MP_OKAY) { printf("\nmp_set_double() failed"); return EXIT_FAILURE; } - if (-dbl != mp_get_double(&a)) { - printf("\nmp_get_double() bad result!"); + if ( !S_COMPARE_DOUBLES(-dbl, mp_get_double(&a))) { + printf("\nmp_get_double() bad result! %20.2f != %20.2f \n", dbl, mp_get_double(&a)); return EXIT_FAILURE; } } #endif - /* test mp_get_int */ printf("\n\nTesting: mp_get_int"); for (i = 0; i < 1000; ++i) { diff --git a/makefile.shared b/makefile.shared index 78b383a70..6ed2c89a9 100644 --- a/makefile.shared +++ b/makefile.shared @@ -17,6 +17,9 @@ ifndef LIBTOOL LIBTOOL:=libtool endif endif + +# PIE and PIC do not play well together in a shared library +ADDITIONAL_LDFLAGS= -Wl,--warn-shared-textrel -Wl,--fatal-warnings -fno-PIE -no-pie LTCOMPILE = $(LIBTOOL) --mode=compile --tag=CC $(CC) LTLINK = $(LIBTOOL) --mode=link --tag=CC $(CC) @@ -56,12 +59,12 @@ bn_s_mp_mul_high_digs.o bn_s_mp_sqr.o bn_s_mp_sub.o bncore.o objs: $(OBJECTS) .c.o: - $(LTCOMPILE) $(CFLAGS) $(LDFLAGS) -o $@ -c $< + $(LTCOMPILE) $(CFLAGS) $(LDFLAGS) $(ADDITIONAL_LDFLAGS) -o $@ -c $< LOBJECTS = $(OBJECTS:.o=.lo) $(LIBNAME): $(OBJECTS) - $(LTLINK) $(LDFLAGS) $(LOBJECTS) -o $(LIBNAME) -rpath $(LIBPATH) -version-info $(VERSION_SO) $(LIBTOOLFLAGS) + $(LTLINK) $(LDFLAGS) $(ADDITIONAL_LDFLAGS) $(LOBJECTS) -o $(LIBNAME) -rpath $(LIBPATH) -version-info $(VERSION_SO) $(LIBTOOLFLAGS) install: $(LIBNAME) install -d $(DESTDIR)$(LIBPATH)