summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xconfigure46
-rw-r--r--configure.in52
2 files changed, 83 insertions, 15 deletions
diff --git a/configure b/configure
index 33684ce..4bd8fec 100755
--- a/configure
+++ b/configure
@@ -50273,13 +50273,23 @@ cat >>conftest.$ac_ext <<_ACEOF
int main(void)
{
+ /* General variables */
+ int endian;
+ int tst_value = 1;
+ int ret = 0;
+
+ /* For FreeBSD */
unsigned long long l = 0xa601e80bda85fcefULL;
long double ld;
unsigned char *c1, *c2;
size_t size;
- int endian;
- int tst_value = 1;
- int ret = 0;
+
+ /* For Cygwin */
+ unsigned long long l_cyg = 0xfffffffffffffff0ULL;
+ long double ld_cyg;
+ unsigned char *c2_cyg;
+ size_t size_cyg;
+
/* Determine this system's endianess */
c1 = (unsigned char*)calloc(1, sizeof(int));
@@ -50289,6 +50299,7 @@ cat >>conftest.$ac_ext <<_ACEOF
else
endian = 1; /* big endian */
+ /* For FreeBSD */
size = sizeof(long double);
memset(&ld, 0, size);
ld = (long double)l;
@@ -50299,12 +50310,35 @@ cat >>conftest.$ac_ext <<_ACEOF
/* Test if the last 2 bytes of mantissa are lost. Mainly for FreeBSD on Intel
* architecture(sleipnir) where it happens. */
/*if(endian==0 && c2[0]==0 && c2[1]==0)*/ /*little endian*/
- if(endian==0 && c2[0]==0) /*little endian*/
+ if(endian==0 && c2[0]==0) { /*little endian*/
+ ret = 1;
+ goto done;
+ }
+
+ /* For Cygwin */
+ size_cyg = sizeof(long double);
+ memset(&ld_cyg, 0, size);
+ ld_cyg = (long double)l_cyg;
+
+ c2_cyg = (unsigned char*)calloc(1, size_cyg);
+ memcpy((void*)c2_cyg, &ld_cyg, size_cyg);
+
+ /* Test if the last 4 bytes(roughly) of mantissa are rounded up. Mainly for Cygwin
+ * where the values like 0xffffffffffffffff, 0xfffffffffffffffe, ...,
+ * 0xfffffffffffff000 ... are rounded up as 0x0000403f8000000000000000
+ * instead of 0x0000403effffffffffffffff, 0x0000403efffffffffffffffe, ...,
+ * 0x0000403efffffffffffff000 ...
+ */
+ if(endian==0 && c2_cyg[0]==0 && c2_cyg[1]==0 && c2_cyg[2]==0 && c2_cyg[3]==0)
ret = 1;
- free(c1);
- free(c2);
done:
+ if(c1)
+ free(c1);
+ if(c2)
+ free(c2);
+ if(c2_cyg)
+ free(c2_cyg);
exit(ret);
}
diff --git a/configure.in b/configure.in
index 292e484..6bc90e9 100644
--- a/configure.in
+++ b/configure.in
@@ -2646,21 +2646,31 @@ dnl Set the flag to indicate that the machine can convert from
dnl 'unsigned long long' to 'long double' without precision loss.
dnl (This flag should be set for all machines, except for FreeBSD(sleipnir)
dnl where the last 2 bytes of mantissa are lost when compiler tries to do
-dnl the conversion.)
+dnl the conversion, and Cygwin where compiler doesn't do rounding correctly.)
dnl
AC_MSG_CHECKING([if converting unsigned long long to long double with precision work])
AC_CACHE_VAL([hdf5_cv_ullong_to_ldouble_precision_works],
[AC_TRY_RUN([
int main(void)
{
+ /* General variables */
+ int endian;
+ int tst_value = 1;
+ int ret = 0;
+
+ /* For FreeBSD */
unsigned long long l = 0xa601e80bda85fcefULL;
long double ld;
unsigned char *c1, *c2;
size_t size;
- int endian;
- int tst_value = 1;
- int ret = 0;
+ /* For Cygwin */
+ unsigned long long l_cyg = 0xfffffffffffffff0ULL;
+ long double ld_cyg;
+ unsigned char *c2_cyg;
+ size_t size_cyg;
+
+
/* Determine this system's endianess */
c1 = (unsigned char*)calloc(1, sizeof(int));
memcpy((void*)c1, &tst_value, sizeof(int));
@@ -2668,7 +2678,8 @@ AC_CACHE_VAL([hdf5_cv_ullong_to_ldouble_precision_works],
endian = 0; /* little endian */
else
endian = 1; /* big endian */
-
+
+ /* For FreeBSD */
size = sizeof(long double);
memset(&ld, 0, size);
ld = (long double)l;
@@ -2679,12 +2690,35 @@ AC_CACHE_VAL([hdf5_cv_ullong_to_ldouble_precision_works],
/* Test if the last 2 bytes of mantissa are lost. Mainly for FreeBSD on Intel
* architecture(sleipnir) where it happens. */
/*if(endian==0 && c2[0]==0 && c2[1]==0)*/ /*little endian*/
- if(endian==0 && c2[0]==0) /*little endian*/
+ if(endian==0 && c2[0]==0) { /*little endian*/
ret = 1;
-
- free(c1);
- free(c2);
+ goto done;
+ }
+
+ /* For Cygwin */
+ size_cyg = sizeof(long double);
+ memset(&ld_cyg, 0, size);
+ ld_cyg = (long double)l_cyg;
+
+ c2_cyg = (unsigned char*)calloc(1, size_cyg);
+ memcpy((void*)c2_cyg, &ld_cyg, size_cyg);
+
+ /* Test if the last 4 bytes(roughly) of mantissa are rounded up. Mainly for Cygwin
+ * where the values like 0xffffffffffffffff, 0xfffffffffffffffe, ...,
+ * 0xfffffffffffff000 ... are rounded up as 0x0000403f8000000000000000
+ * instead of 0x0000403effffffffffffffff, 0x0000403efffffffffffffffe, ...,
+ * 0x0000403efffffffffffff000 ...
+ */
+ if(endian==0 && c2_cyg[0]==0 && c2_cyg[1]==0 && c2_cyg[2]==0 && c2_cyg[3]==0)
+ ret = 1;
+
done:
+ if(c1)
+ free(c1);
+ if(c2)
+ free(c2);
+ if(c2_cyg)
+ free(c2_cyg);
exit(ret);
}
], [hdf5_cv_ullong_to_ldouble_precision_works=yes], [hdf5_cv_ullong_to_ldouble_precision_works=no],)])