repairs for MinGW builds
The changes make extflonums work when compiling with SSE arithmetic for `double's.
This commit is contained in:
parent
bace16a4ce
commit
a1dccb4aa8
13
src/README
13
src/README
|
@ -39,6 +39,13 @@ build, not a Windows-style build (e.g., Racket's `system-type' procedure
|
||||||
returns 'unix, not 'windows, and `racket/gui' uses Gtk instead of
|
returns 'unix, not 'windows, and `racket/gui' uses Gtk instead of
|
||||||
Win32).
|
Win32).
|
||||||
|
|
||||||
|
Beware that MinGW/Cygwin builds different from the MSVC build when
|
||||||
|
SSE-based floating-point math is enabled in the C compiler. In that
|
||||||
|
case, Racket includes sets the floating-point mode to extended
|
||||||
|
precision to support extflonums, and changing precision may affect
|
||||||
|
other libraries. To avoid the floating-point mode change, disable
|
||||||
|
extflonum support with `--disable-extflonum'.
|
||||||
|
|
||||||
========================================================================
|
========================================================================
|
||||||
Compiling for Mac OS X
|
Compiling for Mac OS X
|
||||||
========================================================================
|
========================================================================
|
||||||
|
@ -382,9 +389,9 @@ is compiling floating-point operations as SSE, so be sure to include
|
||||||
flags like "-mfpmath=sse" or "-mfpmath=387" in CPPFLAGS, and not just
|
flags like "-mfpmath=sse" or "-mfpmath=387" in CPPFLAGS, and not just
|
||||||
CFLAGS. See related configuration options below.
|
CFLAGS. See related configuration options below.
|
||||||
|
|
||||||
The Windows build enables extflonum support through a MinGW-compiled
|
The Windows build using MSVC enables extflonum support through a
|
||||||
"longdouble.dll", since MSVC does not support `long double' as
|
MinGW-compiled "longdouble.dll", since MSVC does not support `long
|
||||||
extended-precision floating point.
|
double' as extended-precision floating point.
|
||||||
|
|
||||||
Configuration Options
|
Configuration Options
|
||||||
---------------------
|
---------------------
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
|
|
||||||
|
|
||||||
(define url-host "download.racket-lang.org")
|
(define url-host "download.racket-lang.org")
|
||||||
(define url-path "/libs/12/")
|
(define url-path "/libs/13/")
|
||||||
(define url-base (string-append "http://" url-host url-path))
|
(define url-base (string-append "http://" url-host url-path))
|
||||||
(define architecture #f) ;; set in `do-download'
|
(define architecture #f) ;; set in `do-download'
|
||||||
|
|
||||||
|
@ -30,7 +30,20 @@
|
||||||
(parameterize ([current-directory path])
|
(parameterize ([current-directory path])
|
||||||
(for-each delete-path (directory-list)))
|
(for-each delete-path (directory-list)))
|
||||||
(delete-directory path)]
|
(delete-directory path)]
|
||||||
[(or (file-exists? path) (link-exists? path)) (delete-file path)]))
|
[(or (file-exists? path) (link-exists? path))
|
||||||
|
(if (eq? (system-type) 'windows)
|
||||||
|
;; Use a rename-and-delete dance that lets us replace
|
||||||
|
;; a DLL that might be in use by the Racket process
|
||||||
|
;; that is running the download:
|
||||||
|
(let ([new-path (path-add-suffix path #".del")])
|
||||||
|
(when (file-exists? new-path)
|
||||||
|
(delete-file new-path))
|
||||||
|
(rename-file-or-directory path new-path)
|
||||||
|
(with-handlers ([exn:fail:filesystem?
|
||||||
|
(lambda (exn)
|
||||||
|
(log-error (exn-message exn)))])
|
||||||
|
(delete-file new-path)))
|
||||||
|
(delete-file path))]))
|
||||||
|
|
||||||
(define (purify-port port)
|
(define (purify-port port)
|
||||||
(let ([m (regexp-match-peek-positions #rx#"^HTTP/.*?(?:\r\n\r\n|\n\n|\r\r)"
|
(let ([m (regexp-match-peek-positions #rx#"^HTTP/.*?(?:\r\n\r\n|\n\n|\r\r)"
|
||||||
|
@ -74,6 +87,7 @@
|
||||||
(when (> n 3) (raise-user-error 'download "could not retrieve ~a" file))
|
(when (> n 3) (raise-user-error 'download "could not retrieve ~a" file))
|
||||||
(when (zero? n) (printf " timeout,"))
|
(when (zero? n) (printf " timeout,"))
|
||||||
(loop (add1 n))))
|
(loop (add1 n))))
|
||||||
|
(when (file-exists? file) (delete-path file))
|
||||||
(rename-file-or-directory tmp file #t)
|
(rename-file-or-directory tmp file #t)
|
||||||
(define sz (file-size file))
|
(define sz (file-size file))
|
||||||
(unless (= size sz)
|
(unless (= size sz)
|
||||||
|
|
|
@ -17,12 +17,12 @@
|
||||||
["iconv.dll" 892928]
|
["iconv.dll" 892928]
|
||||||
["libeay32.dll" 1099776]
|
["libeay32.dll" 1099776]
|
||||||
["ssleay32.dll" 239104]
|
["ssleay32.dll" 239104]
|
||||||
["longdouble.dll" 113285]]
|
["longdouble.dll" 114786]]
|
||||||
[win32/x86_64
|
[win32/x86_64
|
||||||
["libiconv-2.dll" 1378028]
|
["libiconv-2.dll" 1378028]
|
||||||
["libeay32.dll" 1503232]
|
["libeay32.dll" 1503232]
|
||||||
["ssleay32.dll" 309760]
|
["ssleay32.dll" 309760]
|
||||||
["longdouble.dll" 123031]]]
|
["longdouble.dll" 125176]]]
|
||||||
;; Math Libraries
|
;; Math Libraries
|
||||||
'[math
|
'[math
|
||||||
[i386-macosx
|
[i386-macosx
|
||||||
|
|
|
@ -85,7 +85,6 @@
|
||||||
|
|
||||||
#ifdef MZ_LONG_DOUBLE
|
#ifdef MZ_LONG_DOUBLE
|
||||||
# if defined(_MSC_VER)
|
# if defined(_MSC_VER)
|
||||||
# define MZ_NEED_SET_EXTFL_MODE 1
|
|
||||||
# define BYTES_RESERVED_FOR_LONG_DOUBLE 16
|
# define BYTES_RESERVED_FOR_LONG_DOUBLE 16
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char bytes[BYTES_RESERVED_FOR_LONG_DOUBLE];
|
char bytes[BYTES_RESERVED_FOR_LONG_DOUBLE];
|
||||||
|
|
|
@ -627,7 +627,9 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
|
# define MZ_LONG_DOUBLE
|
||||||
# define IGNORE_BY_MS_CONTROL_87
|
# define IGNORE_BY_MS_CONTROL_87
|
||||||
|
# define MZ_NEED_SET_EXTFL_MODE
|
||||||
#endif
|
#endif
|
||||||
#if defined(__MINGW32__)
|
#if defined(__MINGW32__)
|
||||||
# define MZ_TRY_EXTFLONUMS
|
# define MZ_TRY_EXTFLONUMS
|
||||||
|
@ -640,7 +642,6 @@
|
||||||
# define USE_ICONV_DLL
|
# define USE_ICONV_DLL
|
||||||
# define NO_MBTOWC_FUNCTIONS
|
# define NO_MBTOWC_FUNCTIONS
|
||||||
|
|
||||||
# define MZ_LONG_DOUBLE
|
|
||||||
# ifdef _WIN64
|
# ifdef _WIN64
|
||||||
# define MZ_USE_JIT_X86_64
|
# define MZ_USE_JIT_X86_64
|
||||||
# else
|
# else
|
||||||
|
@ -1351,11 +1352,31 @@
|
||||||
converts (a == a) to TRUE, even if `a' is floating-point. Used
|
converts (a == a) to TRUE, even if `a' is floating-point. Used
|
||||||
only when USE_[SCO_]IEEE_FP_PREDS is not defined. */
|
only when USE_[SCO_]IEEE_FP_PREDS is not defined. */
|
||||||
|
|
||||||
|
/* C_COMPILER_USES_SSE indicates that the C compiler generates SSE
|
||||||
|
instructions for `double' arithmetic. This flag is turned on
|
||||||
|
automatically if __SSE_MATH__ is defined (usually by gcc). */
|
||||||
|
|
||||||
|
/* MZ_LONG_DOUBLE enables extflonum support. */
|
||||||
|
|
||||||
|
/* MZ_TRY_EXTFLONUMS turns on MZ_LONG_DOUBLE if C_COMPILER_USES_SSE. */
|
||||||
|
|
||||||
/* ASM_DBLPREC_CONTROL_87 uses inline assembly to set Intel '387
|
/* ASM_DBLPREC_CONTROL_87 uses inline assembly to set Intel '387
|
||||||
floating-point operations to double-precision instead of
|
floating-point operations to double-precision instead of
|
||||||
extended-precision arithmetic. This definition is turned off
|
extended-precision arithmetic. This definition is turned off if
|
||||||
if the C compiler and JIT use SSE, and ASM_EXTPREC_CONTROL_87
|
C_COMPILER_USES_SSE, and ASM_EXTPREC_CONTROL_87 is turned on
|
||||||
is turned on instead if extflonums are enabled. */
|
instead if C_COMPILER_USES_SSE and MZ_LONG_DOUBLE. */
|
||||||
|
|
||||||
|
/* ASM_EXTPREC_CONTROL_87 uses inline assembly to set Intel '387
|
||||||
|
floating-point operations to double-precision instead of
|
||||||
|
extended-precision arithmetic. */
|
||||||
|
|
||||||
|
/* MZ_NEED_SET_EXTFL_MODE causes JIT-generated extflonum instructions
|
||||||
|
to set the x87 control word to extended precision just before an
|
||||||
|
extflonum operation, and then set if back to double precision just
|
||||||
|
after. This is needed or Windows (where the default mode is double
|
||||||
|
precision, something about the x64 environment switches the mode
|
||||||
|
back if you try to change it permanently, and "longdouble.dll"
|
||||||
|
does the same switch for non-JITted operations). */
|
||||||
|
|
||||||
/* IGNORE_BY_BORLAND_CONTROL_87 turns off floating-point error for
|
/* IGNORE_BY_BORLAND_CONTROL_87 turns off floating-point error for
|
||||||
Intel '387 with Borlad-style _control87. DONT_IGNORE_PIPE_SIGNAL
|
Intel '387 with Borlad-style _control87. DONT_IGNORE_PIPE_SIGNAL
|
||||||
|
|
|
@ -201,7 +201,8 @@ fun.@LTO@: $(srcdir)/fun.c
|
||||||
$(CC) $(CFLAGS) -c $(srcdir)/fun.c -o fun.@LTO@
|
$(CC) $(CFLAGS) -c $(srcdir)/fun.c -o fun.@LTO@
|
||||||
future.@LTO@: $(srcdir)/future.c
|
future.@LTO@: $(srcdir)/future.c
|
||||||
$(CC) $(CFLAGS) -c $(srcdir)/future.c -o future.@LTO@
|
$(CC) $(CFLAGS) -c $(srcdir)/future.c -o future.@LTO@
|
||||||
gmp.@LTO@: $(srcdir)/gmp/gmp.c $(srcdir)/gmp/gmplonglong.h $(srcdir)/../include/schthread.h
|
gmp.@LTO@: $(srcdir)/gmp/gmp.c $(srcdir)/gmp/gmplonglong.h \
|
||||||
|
$(srcdir)/../include/schthread.h $(srcdir)/../sconfig.h
|
||||||
$(CC) $(CFLAGS) -c $(srcdir)/gmp/gmp.c -o gmp.@LTO@
|
$(CC) $(CFLAGS) -c $(srcdir)/gmp/gmp.c -o gmp.@LTO@
|
||||||
hash.@LTO@: $(srcdir)/hash.c
|
hash.@LTO@: $(srcdir)/hash.c
|
||||||
$(CC) $(CFLAGS) -c $(srcdir)/hash.c -o hash.@LTO@
|
$(CC) $(CFLAGS) -c $(srcdir)/hash.c -o hash.@LTO@
|
||||||
|
@ -365,7 +366,8 @@ network.@LTO@: $(COMMON_HEADERS) \
|
||||||
numarith.@LTO@: $(COMMON_HEADERS) \
|
numarith.@LTO@: $(COMMON_HEADERS) \
|
||||||
$(srcdir)/stypes.h $(srcdir)/nummacs.h
|
$(srcdir)/stypes.h $(srcdir)/nummacs.h
|
||||||
number.@LTO@: $(COMMON_HEADERS) \
|
number.@LTO@: $(COMMON_HEADERS) \
|
||||||
$(srcdir)/stypes.h $(srcdir)/nummacs.h
|
$(srcdir)/stypes.h $(srcdir)/nummacs.h \
|
||||||
|
$(srcdir)/longdouble/longdouble.c
|
||||||
numcomp.@LTO@: $(COMMON_HEADERS) \
|
numcomp.@LTO@: $(COMMON_HEADERS) \
|
||||||
$(srcdir)/stypes.h $(srcdir)/nummacs.h
|
$(srcdir)/stypes.h $(srcdir)/nummacs.h
|
||||||
numstr.@LTO@: $(COMMON_HEADERS) \
|
numstr.@LTO@: $(COMMON_HEADERS) \
|
||||||
|
|
|
@ -239,7 +239,7 @@ Scheme_Env *scheme_engine_instance_init()
|
||||||
printf("#if 0\nengine_instance_init @ %" PRIdPTR "\n", scheme_get_process_milliseconds());
|
printf("#if 0\nengine_instance_init @ %" PRIdPTR "\n", scheme_get_process_milliseconds());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef MZ_LONG_DOUBLE_API_IS_EXTERNAL
|
#if defined(MZ_LONG_DOUBLE_API_IS_EXTERNAL) || defined(LONG_DOUBLE_STRING_OP_API_IS_EXTERNAL)
|
||||||
scheme_load_long_double_dll();
|
scheme_load_long_double_dll();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -701,7 +701,7 @@ static int generate_float_point_arith(mz_jit_state *jitter, Scheme_Object *rator
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (arith) {
|
if (arith) {
|
||||||
#ifdef MZ_NEED_SET_EXTFL_MODE
|
#if defined(MZ_LONG_DOUBLE) && defined(MZ_NEED_SET_EXTFL_MODE)
|
||||||
int need_control_reset = 0;
|
int need_control_reset = 0;
|
||||||
if (extfl) {
|
if (extfl) {
|
||||||
switch (arith) {
|
switch (arith) {
|
||||||
|
@ -954,7 +954,7 @@ static int generate_float_point_arith(mz_jit_state *jitter, Scheme_Object *rator
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#ifdef MZ_NEED_SET_EXTFL_MODE
|
#if defined(MZ_LONG_DOUBLE) && defined(MZ_NEED_SET_EXTFL_MODE)
|
||||||
if (extfl && need_control_reset) {
|
if (extfl && need_control_reset) {
|
||||||
jit_set_fp_control(0x27f);
|
jit_set_fp_control(0x27f);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,11 @@
|
||||||
|
|
||||||
|
/* This file is really three implementations: the external API, glue
|
||||||
|
for the external API, and glue for just the string external API. */
|
||||||
|
|
||||||
|
/**********************************************************************/
|
||||||
|
/* External long_double implementation */
|
||||||
|
/**********************************************************************/
|
||||||
|
|
||||||
#ifdef IMPLEMENTING_MSC_LONGDOUBLE
|
#ifdef IMPLEMENTING_MSC_LONGDOUBLE
|
||||||
|
|
||||||
/* Implement the `long_double' API.
|
/* Implement the `long_double' API.
|
||||||
|
@ -25,118 +33,120 @@ LDBL_DLL_API int get_x87_control()
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ext_mode()
|
static int ext_mode()
|
||||||
{
|
{
|
||||||
|
int m = get_x87_control();
|
||||||
set_x87_control(0x37F);
|
set_x87_control(0x37F);
|
||||||
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void default_mode()
|
static void restore_mode(int m)
|
||||||
{
|
{
|
||||||
set_x87_control(0x27F);
|
set_x87_control(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
long_double get_long_double_infinity_val()
|
long_double get_long_double_infinity_val()
|
||||||
{
|
{
|
||||||
long_double result;
|
long_double result;
|
||||||
ext_mode();
|
int m = ext_mode();
|
||||||
result.val = 1.0L / get_long_double_zero().val;
|
result.val = 1.0L / get_long_double_zero().val;
|
||||||
default_mode();
|
restore_mode(m);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
long_double get_long_double_minus_infinity_val()
|
long_double get_long_double_minus_infinity_val()
|
||||||
{
|
{
|
||||||
long_double result;
|
long_double result;
|
||||||
ext_mode();
|
int m = ext_mode();
|
||||||
result.val = -get_long_double_infinity_val().val;
|
result.val = -get_long_double_infinity_val().val;
|
||||||
default_mode();
|
restore_mode(m);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
long_double get_long_double_zero()
|
long_double get_long_double_zero()
|
||||||
{
|
{
|
||||||
long_double result;
|
long_double result;
|
||||||
ext_mode();
|
int m = ext_mode();
|
||||||
result.val = 0.0L;
|
result.val = 0.0L;
|
||||||
default_mode();
|
restore_mode(m);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
long_double get_long_double_nzero()
|
long_double get_long_double_nzero()
|
||||||
{
|
{
|
||||||
long_double result;
|
long_double result;
|
||||||
ext_mode();
|
int m = ext_mode();
|
||||||
result.val = -1.0L / get_long_double_infinity_val().val;
|
result.val = -1.0L / get_long_double_infinity_val().val;
|
||||||
default_mode();
|
restore_mode(m);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
long_double get_long_double_nan()
|
long_double get_long_double_nan()
|
||||||
{
|
{
|
||||||
long_double result;
|
long_double result;
|
||||||
ext_mode();
|
int m = ext_mode();
|
||||||
result.val = get_long_double_infinity_val().val + get_long_double_minus_infinity_val().val;
|
result.val = get_long_double_infinity_val().val + get_long_double_minus_infinity_val().val;
|
||||||
default_mode();
|
restore_mode(m);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
long_double get_long_double_1()
|
long_double get_long_double_1()
|
||||||
{
|
{
|
||||||
long_double result;
|
long_double result;
|
||||||
ext_mode();
|
int m = ext_mode();
|
||||||
result.val = 1.0L;
|
result.val = 1.0L;
|
||||||
default_mode();
|
restore_mode(m);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
long_double get_long_double_minus_1()
|
long_double get_long_double_minus_1()
|
||||||
{
|
{
|
||||||
long_double result;
|
long_double result;
|
||||||
ext_mode();
|
int m = ext_mode();
|
||||||
result.val = -1.0L;
|
result.val = -1.0L;
|
||||||
default_mode();
|
restore_mode(m);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
long_double get_long_double_2()
|
long_double get_long_double_2()
|
||||||
{
|
{
|
||||||
long_double result;
|
long_double result;
|
||||||
ext_mode();
|
int m = ext_mode();
|
||||||
result.val = 2.0L;
|
result.val = 2.0L;
|
||||||
default_mode();
|
restore_mode(m);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
long_double get_long_double_one_half()
|
long_double get_long_double_one_half()
|
||||||
{
|
{
|
||||||
long_double result;
|
long_double result;
|
||||||
ext_mode();
|
int m = ext_mode();
|
||||||
result.val = 0.5L;
|
result.val = 0.5L;
|
||||||
default_mode();
|
restore_mode(m);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
long_double get_long_double_pi()
|
long_double get_long_double_pi()
|
||||||
{
|
{
|
||||||
long_double result;
|
long_double result;
|
||||||
ext_mode();
|
int m = ext_mode();
|
||||||
result.val = atan2l(0.0L, -1.0L);
|
result.val = atan2l(0.0L, -1.0L);
|
||||||
default_mode();
|
restore_mode(m);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
long_double get_long_double_half_pi()
|
long_double get_long_double_half_pi()
|
||||||
{
|
{
|
||||||
long_double result;
|
long_double result;
|
||||||
ext_mode();
|
int m = ext_mode();
|
||||||
result.val = atan2l(0.0L, -1.0L)/2.0L;
|
result.val = atan2l(0.0L, -1.0L)/2.0L;
|
||||||
default_mode();
|
restore_mode(m);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
long_double long_double_from_int(int a)
|
long_double long_double_from_int(int a)
|
||||||
{
|
{
|
||||||
long_double result;
|
long_double result;
|
||||||
ext_mode();
|
int m = ext_mode();
|
||||||
result.val = (long double) a;
|
result.val = (long double) a;
|
||||||
default_mode();
|
restore_mode(m);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,27 +154,27 @@ long_double long_double_from_int(int a)
|
||||||
long_double long_double_from_float(float a)
|
long_double long_double_from_float(float a)
|
||||||
{
|
{
|
||||||
long_double result;
|
long_double result;
|
||||||
ext_mode();
|
int m = ext_mode();
|
||||||
result.val = (long double) a;
|
result.val = (long double) a;
|
||||||
default_mode();
|
restore_mode(m);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
long_double long_double_from_double(double a)
|
long_double long_double_from_double(double a)
|
||||||
{
|
{
|
||||||
long_double result;
|
long_double result;
|
||||||
ext_mode();
|
int m = ext_mode();
|
||||||
result.val = (long double) a;
|
result.val = (long double) a;
|
||||||
default_mode();
|
restore_mode(m);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
long_double long_double_from_uintptr(uintptr_t a)
|
long_double long_double_from_uintptr(uintptr_t a)
|
||||||
{
|
{
|
||||||
long_double result;
|
long_double result;
|
||||||
ext_mode();
|
int m = ext_mode();
|
||||||
result.val = a;
|
result.val = a;
|
||||||
default_mode();
|
restore_mode(m);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,62 +195,62 @@ intptr_t int_from_long_double(long_double a)
|
||||||
long_double long_double_plus(long_double a, long_double b)
|
long_double long_double_plus(long_double a, long_double b)
|
||||||
{
|
{
|
||||||
long_double result;
|
long_double result;
|
||||||
ext_mode();
|
int m = ext_mode();
|
||||||
result.val = a.val + b.val;
|
result.val = a.val + b.val;
|
||||||
default_mode();
|
restore_mode(m);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
long_double long_double_minus(long_double a, long_double b)
|
long_double long_double_minus(long_double a, long_double b)
|
||||||
{
|
{
|
||||||
long_double result;
|
long_double result;
|
||||||
ext_mode();
|
int m = ext_mode();
|
||||||
result.val = a.val - b.val;
|
result.val = a.val - b.val;
|
||||||
default_mode();
|
restore_mode(m);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
long_double long_double_mult(long_double a, long_double b)
|
long_double long_double_mult(long_double a, long_double b)
|
||||||
{
|
{
|
||||||
long_double result;
|
long_double result;
|
||||||
ext_mode();
|
int m = ext_mode();
|
||||||
result.val = a.val * b.val;
|
result.val = a.val * b.val;
|
||||||
default_mode();
|
restore_mode(m);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
long_double long_double_mult_i(long_double a, int b)
|
long_double long_double_mult_i(long_double a, int b)
|
||||||
{
|
{
|
||||||
long_double result;
|
long_double result;
|
||||||
ext_mode();
|
int m = ext_mode();
|
||||||
result.val = a.val * b;
|
result.val = a.val * b;
|
||||||
default_mode();
|
restore_mode(m);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
uintptr_t uintptr_from_long_double(long_double a)
|
uintptr_t uintptr_from_long_double(long_double a)
|
||||||
{
|
{
|
||||||
uintptr_t result;
|
uintptr_t result;
|
||||||
ext_mode();
|
int m = ext_mode();
|
||||||
result = a.val;
|
result = a.val;
|
||||||
default_mode();
|
restore_mode(m);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
long_double long_double_div(long_double a, long_double b)
|
long_double long_double_div(long_double a, long_double b)
|
||||||
{
|
{
|
||||||
long_double result;
|
long_double result;
|
||||||
ext_mode();
|
int m = ext_mode();
|
||||||
result.val = a.val / b.val;
|
result.val = a.val / b.val;
|
||||||
default_mode();
|
restore_mode(m);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
long_double long_double_neg(long_double a)
|
long_double long_double_neg(long_double a)
|
||||||
{
|
{
|
||||||
long_double result;
|
long_double result;
|
||||||
ext_mode();
|
int m = ext_mode();
|
||||||
result.val = -a.val;
|
result.val = -a.val;
|
||||||
default_mode();
|
restore_mode(m);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -283,9 +293,9 @@ int long_double_is_1(long_double a)
|
||||||
int long_double_minus_zero_p(long_double a)
|
int long_double_minus_zero_p(long_double a)
|
||||||
{
|
{
|
||||||
int v;
|
int v;
|
||||||
ext_mode();
|
int m = ext_mode();
|
||||||
v = ((1.0L / a.val) < 0.0L);
|
v = ((1.0L / a.val) < 0.0L);
|
||||||
default_mode();
|
restore_mode(m);
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
int long_double_is_nan(long_double a)
|
int long_double_is_nan(long_double a)
|
||||||
|
@ -310,160 +320,160 @@ int long_double_is_infinity(long_double a)
|
||||||
long_double long_double_fabs(long_double a)
|
long_double long_double_fabs(long_double a)
|
||||||
{
|
{
|
||||||
long_double result;
|
long_double result;
|
||||||
ext_mode();
|
int m = ext_mode();
|
||||||
result.val = fabsl(a.val);
|
result.val = fabsl(a.val);
|
||||||
default_mode();
|
restore_mode(m);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
long_double long_double_modf(long_double a, long_double *b)
|
long_double long_double_modf(long_double a, long_double *b)
|
||||||
{
|
{
|
||||||
long_double result;
|
long_double result;
|
||||||
ext_mode();
|
int m = ext_mode();
|
||||||
result.val = modfl(a.val, &b->val);
|
result.val = modfl(a.val, &b->val);
|
||||||
default_mode();
|
restore_mode(m);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
long_double long_double_fmod(long_double a, long_double b)
|
long_double long_double_fmod(long_double a, long_double b)
|
||||||
{
|
{
|
||||||
long_double result;
|
long_double result;
|
||||||
ext_mode();
|
int m = ext_mode();
|
||||||
result.val = fmodl(a.val, b.val);
|
result.val = fmodl(a.val, b.val);
|
||||||
default_mode();
|
restore_mode(m);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
long_double long_double_trunc(long_double a)
|
long_double long_double_trunc(long_double a)
|
||||||
{
|
{
|
||||||
long_double result;
|
long_double result;
|
||||||
ext_mode();
|
int m = ext_mode();
|
||||||
result.val = truncl(a.val);
|
result.val = truncl(a.val);
|
||||||
default_mode();
|
restore_mode(m);
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
}
|
}
|
||||||
long_double long_double_floor(long_double a)
|
long_double long_double_floor(long_double a)
|
||||||
{
|
{
|
||||||
long_double result;
|
long_double result;
|
||||||
ext_mode();
|
int m = ext_mode();
|
||||||
result.val = floorl(a.val);
|
result.val = floorl(a.val);
|
||||||
default_mode();
|
restore_mode(m);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
long_double long_double_ceil(long_double a)
|
long_double long_double_ceil(long_double a)
|
||||||
{
|
{
|
||||||
long_double result;
|
long_double result;
|
||||||
ext_mode();
|
int m = ext_mode();
|
||||||
result.val = ceill(a.val);
|
result.val = ceill(a.val);
|
||||||
default_mode();
|
restore_mode(m);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
long_double long_double_sin(long_double a)
|
long_double long_double_sin(long_double a)
|
||||||
{
|
{
|
||||||
long_double result;
|
long_double result;
|
||||||
ext_mode();
|
int m = ext_mode();
|
||||||
result.val = sinl(a.val);
|
result.val = sinl(a.val);
|
||||||
default_mode();
|
restore_mode(m);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
long_double long_double_cos(long_double a)
|
long_double long_double_cos(long_double a)
|
||||||
{
|
{
|
||||||
long_double result;
|
long_double result;
|
||||||
ext_mode();
|
int m = ext_mode();
|
||||||
result.val = cosl(a.val);
|
result.val = cosl(a.val);
|
||||||
default_mode();
|
restore_mode(m);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
long_double long_double_tan(long_double a)
|
long_double long_double_tan(long_double a)
|
||||||
{
|
{
|
||||||
long_double result;
|
long_double result;
|
||||||
ext_mode();
|
int m = ext_mode();
|
||||||
result.val = tanl(a.val);
|
result.val = tanl(a.val);
|
||||||
default_mode();
|
restore_mode(m);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
long_double long_double_asin(long_double a)
|
long_double long_double_asin(long_double a)
|
||||||
{
|
{
|
||||||
long_double result;
|
long_double result;
|
||||||
ext_mode();
|
int m = ext_mode();
|
||||||
result.val = asinl(a.val);
|
result.val = asinl(a.val);
|
||||||
default_mode();
|
restore_mode(m);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
long_double long_double_acos(long_double a)
|
long_double long_double_acos(long_double a)
|
||||||
{
|
{
|
||||||
long_double result;
|
long_double result;
|
||||||
ext_mode();
|
int m = ext_mode();
|
||||||
result.val = acosl(a.val);
|
result.val = acosl(a.val);
|
||||||
default_mode();
|
restore_mode(m);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
long_double long_double_atan(long_double a)
|
long_double long_double_atan(long_double a)
|
||||||
{
|
{
|
||||||
long_double result;
|
long_double result;
|
||||||
ext_mode();
|
int m = ext_mode();
|
||||||
result.val = atanl(a.val);
|
result.val = atanl(a.val);
|
||||||
default_mode();
|
restore_mode(m);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
long_double long_double_log(long_double a)
|
long_double long_double_log(long_double a)
|
||||||
{
|
{
|
||||||
long_double result;
|
long_double result;
|
||||||
ext_mode();
|
int m = ext_mode();
|
||||||
result.val = logl(a.val);
|
result.val = logl(a.val);
|
||||||
default_mode();
|
restore_mode(m);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
long_double long_double_exp(long_double a)
|
long_double long_double_exp(long_double a)
|
||||||
{
|
{
|
||||||
long_double result;
|
long_double result;
|
||||||
ext_mode();
|
int m = ext_mode();
|
||||||
result.val = expl(a.val);
|
result.val = expl(a.val);
|
||||||
default_mode();
|
restore_mode(m);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
long_double long_double_ldexp(long_double a, int i)
|
long_double long_double_ldexp(long_double a, int i)
|
||||||
{
|
{
|
||||||
long_double result;
|
long_double result;
|
||||||
ext_mode();
|
int m = ext_mode();
|
||||||
result.val = ldexpl(a.val, i);
|
result.val = ldexpl(a.val, i);
|
||||||
default_mode();
|
restore_mode(m);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
long_double long_double_pow(long_double a, long_double b)
|
long_double long_double_pow(long_double a, long_double b)
|
||||||
{
|
{
|
||||||
long_double result;
|
long_double result;
|
||||||
ext_mode();
|
int m = ext_mode();
|
||||||
result.val = powl(a.val, b.val);
|
result.val = powl(a.val, b.val);
|
||||||
default_mode();
|
restore_mode(m);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
long_double long_double_sqrt(long_double a)
|
long_double long_double_sqrt(long_double a)
|
||||||
{
|
{
|
||||||
long_double result;
|
long_double result;
|
||||||
ext_mode();
|
int m = ext_mode();
|
||||||
result.val = sqrtl(a.val);
|
result.val = sqrtl(a.val);
|
||||||
default_mode();
|
restore_mode(m);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
long_double long_double_frexp(long_double a, int* i)
|
long_double long_double_frexp(long_double a, int* i)
|
||||||
{
|
{
|
||||||
long_double result;
|
long_double result;
|
||||||
ext_mode();
|
int m = ext_mode();
|
||||||
result.val = frexpl(a.val, i);
|
result.val = frexpl(a.val, i);
|
||||||
default_mode();
|
restore_mode(m);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void long_double_sprint(char* buffer, int digits, long_double d)
|
void long_double_sprint(char* buffer, int digits, long_double d)
|
||||||
{
|
{
|
||||||
ext_mode();
|
int m = ext_mode();
|
||||||
__mingw_sprintf(buffer, "%.*Lg", digits, d.val);
|
__mingw_sprintf(buffer, "%.*Lg", digits, d.val);
|
||||||
default_mode();
|
restore_mode(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
long_double long_double_array_ref(void *pointer, int index)
|
long_double long_double_array_ref(void *pointer, int index)
|
||||||
|
@ -484,9 +494,9 @@ long_double long_double_from_string(char* buff, char** p)
|
||||||
long_double result;
|
long_double result;
|
||||||
char* ptr, one_char;
|
char* ptr, one_char;
|
||||||
int n;
|
int n;
|
||||||
ext_mode();
|
int m = ext_mode();
|
||||||
n = __mingw_sscanf(buff, "%Lf%c", &result.val, &one_char);
|
n = __mingw_sscanf(buff, "%Lf%c", &result.val, &one_char);
|
||||||
default_mode();
|
restore_mode(m);
|
||||||
if (n == 1) {
|
if (n == 1) {
|
||||||
/* all characters consumed for the number */
|
/* all characters consumed for the number */
|
||||||
*p = &buff[strlen(buff)];
|
*p = &buff[strlen(buff)];
|
||||||
|
@ -498,9 +508,18 @@ long_double long_double_from_string(char* buff, char** p)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
void long_double_from_string_indirect(char* buff, char** p, long_double *_ld)
|
||||||
|
{
|
||||||
|
*_ld = long_double_from_string(buff, p);
|
||||||
|
}
|
||||||
|
|
||||||
/* Glue code */
|
#endif
|
||||||
|
|
||||||
|
/**********************************************************************/
|
||||||
|
/* Glue for external long_double implementation */
|
||||||
|
/**********************************************************************/
|
||||||
|
|
||||||
|
#ifdef MZ_LONG_DOUBLE_API_IS_EXTERNAL
|
||||||
|
|
||||||
#ifdef MZ_PRECISE_GC
|
#ifdef MZ_PRECISE_GC
|
||||||
START_XFORM_SKIP;
|
START_XFORM_SKIP;
|
||||||
|
@ -597,7 +616,7 @@ static long_double fail_from_string(char* buff, char** p)
|
||||||
double d;
|
double d;
|
||||||
long_double ld;
|
long_double ld;
|
||||||
|
|
||||||
d = strtod(buff, p, 0);
|
d = strtod(buff, p);
|
||||||
memcpy(&ld, &d, sizeof(double));
|
memcpy(&ld, &d, sizeof(double));
|
||||||
|
|
||||||
return ld;
|
return ld;
|
||||||
|
@ -779,3 +798,89 @@ END_XFORM_SKIP;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**********************************************************************/
|
||||||
|
/* Glue for external long_double string-op implementation */
|
||||||
|
/**********************************************************************/
|
||||||
|
|
||||||
|
#ifdef LONG_DOUBLE_STRING_OP_API_IS_EXTERNAL
|
||||||
|
|
||||||
|
/* Like regular glue mode, but only for the string operations.
|
||||||
|
|
||||||
|
It may seem strage to resort to a MinGW-compiled DLL to implement
|
||||||
|
functionality when compiling with MinGW, but the MinGW version has
|
||||||
|
to be recent enough to get __mingw_sscanf, so we do things this
|
||||||
|
way to allow building with older MinGWs (such as the default MinGW
|
||||||
|
release at the time of writing). */
|
||||||
|
|
||||||
|
#ifdef MZ_PRECISE_GC
|
||||||
|
START_XFORM_SKIP;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int long_double_dll_available;
|
||||||
|
|
||||||
|
typedef union dll_long_double
|
||||||
|
{
|
||||||
|
char bytes[SIZEOF_LONGDOUBLE];
|
||||||
|
long double val;
|
||||||
|
} dll_long_double;
|
||||||
|
|
||||||
|
/* pointers to dynamically loaded functions */
|
||||||
|
#define DECLARE_LDBL(res, name, args) \
|
||||||
|
typedef res (* name ## _t)args; \
|
||||||
|
static name ## _t _imp_ ## name;
|
||||||
|
DECLARE_LDBL(void, long_double_sprint, (char* buffer, int digits, dll_long_double ld))
|
||||||
|
DECLARE_LDBL(void, long_double_from_string_indirect, (char* buff, char** p, dll_long_double *_ld))
|
||||||
|
|
||||||
|
static void fail_from_string_indirect(char* buff, char** p, dll_long_double *_ld)
|
||||||
|
{
|
||||||
|
double d;
|
||||||
|
|
||||||
|
d = strtod(buff, p);
|
||||||
|
memcpy(_ld, &d, sizeof(double));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fail_sprint(char* buffer, int digits, dll_long_double ld)
|
||||||
|
{
|
||||||
|
double d;
|
||||||
|
memcpy(&d, &ld, sizeof(double));
|
||||||
|
sprintf(buffer, "%.*Lg", digits, d);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* initialization */
|
||||||
|
void scheme_load_long_double_dll()
|
||||||
|
{
|
||||||
|
HANDLE m;
|
||||||
|
m = LoadLibraryW(scheme_get_dll_path(L"longdouble.dll"));
|
||||||
|
|
||||||
|
if (m) long_double_dll_available = 1;
|
||||||
|
|
||||||
|
# define EXTRACT_LDBL(name, fail) \
|
||||||
|
_imp_ ## name = (name ##_t)(m ? GetProcAddress(m, # name) : NULL); \
|
||||||
|
if (!(_imp_ ## name)) _imp_ ## name = (name ##_t)fail;
|
||||||
|
|
||||||
|
EXTRACT_LDBL(long_double_sprint, fail_sprint);
|
||||||
|
EXTRACT_LDBL(long_double_from_string_indirect, fail_from_string_indirect);
|
||||||
|
}
|
||||||
|
|
||||||
|
int long_double_available() {
|
||||||
|
return long_double_dll_available;
|
||||||
|
}
|
||||||
|
|
||||||
|
void long_double_sprint(char* buffer, int digits, long double d) {
|
||||||
|
dll_long_double ld;
|
||||||
|
ld.val = d;
|
||||||
|
_imp_long_double_sprint(buffer, digits, ld);
|
||||||
|
}
|
||||||
|
|
||||||
|
long double long_double_from_string(char* buff, char** p) {
|
||||||
|
dll_long_double ld;
|
||||||
|
_imp_long_double_from_string_indirect(buff, p, &ld);
|
||||||
|
return ld.val;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef MZ_PRECISE_GC
|
||||||
|
END_XFORM_SKIP;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -1,45 +1,41 @@
|
||||||
#ifndef MZ_LONGDOUBLE_H
|
#ifndef MZ_LONGDOUBLE_H
|
||||||
#define MZ_LONGDOUBLE_H
|
#define MZ_LONGDOUBLE_H
|
||||||
|
|
||||||
#if defined(_MSC_VER) || defined(IMPLEMENTING_MSC_LONGDOUBLE)
|
#if defined(_MSC_VER)
|
||||||
/* aligning */
|
# define MZ_LONG_DOUBLE_API_IS_EXTERNAL
|
||||||
# if defined(_X86_64) || defined(_M_X64) || defined(_WIN64)
|
#endif
|
||||||
# define SIZEOF_LONGDOUBLE 16
|
|
||||||
# else
|
|
||||||
# define SIZEOF_LONGDOUBLE 16
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# ifdef BYTES_RESERVED_FOR_LONG_DOUBLE
|
#if defined(__MINGW32__) && defined(MZ_LONG_DOUBLE)
|
||||||
|
# define LONG_DOUBLE_STRING_OP_API_IS_EXTERNAL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MZ_LONG_DOUBLE_API_IS_EXTERNAL) \
|
||||||
|
|| defined(LONG_DOUBLE_STRING_OP_API_IS_EXTERNAL) \
|
||||||
|
|| defined(IMPLEMENTING_MSC_LONGDOUBLE)
|
||||||
|
# define SIZEOF_LONGDOUBLE 16
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef BYTES_RESERVED_FOR_LONG_DOUBLE
|
||||||
/* check "scheme.h" versus "longdouble.h": */
|
/* check "scheme.h" versus "longdouble.h": */
|
||||||
# if BYTES_RESERVED_FOR_LONG_DOUBLE != SIZEOF_LONGDOUBLE
|
# if BYTES_RESERVED_FOR_LONG_DOUBLE != SIZEOF_LONGDOUBLE
|
||||||
!! mismatch in mz_long_double size !!
|
!! mismatch in mz_long_double size !!
|
||||||
# endif
|
|
||||||
# endif
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
# ifdef IMPLEMENTING_MSC_LONGDOUBLE
|
#ifdef IMPLEMENTING_MSC_LONGDOUBLE
|
||||||
typedef union long_double
|
typedef union long_double
|
||||||
{
|
{
|
||||||
char bytes[SIZEOF_LONGDOUBLE];
|
char bytes[SIZEOF_LONGDOUBLE];
|
||||||
long double val;
|
long double val;
|
||||||
} long_double;
|
} long_double;
|
||||||
# else
|
|
||||||
# define long_double mz_long_double
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#else
|
|
||||||
# define long_double mz_long_double
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef IMPLEMENTING_MSC_LONGDOUBLE
|
|
||||||
# define LDBL_DLL_API __declspec(dllexport)
|
# define LDBL_DLL_API __declspec(dllexport)
|
||||||
# define XFORM_NONGCING /* empty */
|
# define XFORM_NONGCING /* empty */
|
||||||
#else
|
#else
|
||||||
|
# define long_double mz_long_double
|
||||||
# define LDBL_DLL_API /* empty */
|
# define LDBL_DLL_API /* empty */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(_MSC_VER) || defined(IMPLEMENTING_MSC_LONGDOUBLE)
|
#if defined(MZ_LONG_DOUBLE_API_IS_EXTERNAL) || defined(IMPLEMENTING_MSC_LONGDOUBLE)
|
||||||
|
|
||||||
#define MZ_LONG_DOUBLE_API_IS_EXTERNAL
|
|
||||||
|
|
||||||
void scheme_load_long_double_dll();
|
void scheme_load_long_double_dll();
|
||||||
|
|
||||||
|
@ -121,6 +117,7 @@ XFORM_NONGCING LDBL_DLL_API long_double long_double_array_ref(void *pointer, int
|
||||||
XFORM_NONGCING LDBL_DLL_API void long_double_array_set(void *pointer, int index, long_double value);
|
XFORM_NONGCING LDBL_DLL_API void long_double_array_set(void *pointer, int index, long_double value);
|
||||||
|
|
||||||
XFORM_NONGCING LDBL_DLL_API long_double long_double_from_string(char* buff, char** p);
|
XFORM_NONGCING LDBL_DLL_API long_double long_double_from_string(char* buff, char** p);
|
||||||
|
XFORM_NONGCING LDBL_DLL_API void long_double_from_string_indirect(char* buff, char** p, long_double *_ld);
|
||||||
|
|
||||||
XFORM_NONGCING void to_double_prec();
|
XFORM_NONGCING void to_double_prec();
|
||||||
XFORM_NONGCING void to_extended_prec();
|
XFORM_NONGCING void to_extended_prec();
|
||||||
|
@ -199,14 +196,23 @@ XFORM_NONGCING int long_double_available();
|
||||||
|
|
||||||
# define long_double_frexp(a, i) frexpl(a, i)
|
# define long_double_frexp(a, i) frexpl(a, i)
|
||||||
|
|
||||||
# define long_double_from_string(x,y) strtold(x, y)
|
# ifdef LONG_DOUBLE_STRING_OP_API_IS_EXTERNAL
|
||||||
|
XFORM_NONGCING LDBL_DLL_API long_double long_double_from_string(char* buff, char** p);
|
||||||
# define long_double_sprint(buffer,digits,d) sprintf(buffer, "%.*Lg", digits, d)
|
XFORM_NONGCING LDBL_DLL_API void long_double_sprint(char* buffer, int digits, long_double d);
|
||||||
|
# else
|
||||||
|
# define long_double_from_string(x,y) strtold(x, y)
|
||||||
|
# define long_double_sprint(buffer,digits,d) sprintf(buffer, "%.*Lg", digits, d)
|
||||||
|
# endif
|
||||||
|
|
||||||
# define long_double_array_ref(pointer,index) ((long_double *)(pointer))[index]
|
# define long_double_array_ref(pointer,index) ((long_double *)(pointer))[index]
|
||||||
# define long_double_array_set(pointer,index,value) ((long_double *)(pointer))[index] = (value)
|
# define long_double_array_set(pointer,index,value) ((long_double *)(pointer))[index] = (value)
|
||||||
|
|
||||||
# define long_double_available() 1
|
# ifdef LONG_DOUBLE_STRING_OP_API_IS_EXTERNAL
|
||||||
|
XFORM_NONGCING void scheme_load_long_double_dll();
|
||||||
|
XFORM_NONGCING int long_double_available();
|
||||||
|
# else
|
||||||
|
# define long_double_available() 1
|
||||||
|
# endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -5457,6 +5457,6 @@ static Scheme_Object *extfl_to_integer (int argc, Scheme_Object *argv[])
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MZ_LONG_DOUBLE_API_IS_EXTERNAL
|
#if defined(MZ_LONG_DOUBLE_API_IS_EXTERNAL) || defined(LONG_DOUBLE_STRING_OP_API_IS_EXTERNAL)
|
||||||
# include "longdouble/longdouble.c"
|
# include "longdouble/longdouble.c"
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue
Block a user