mirror of
https://github.com/HDFGroup/hdf5.git
synced 2025-03-31 17:10:47 +08:00
[svn-r10797] Purpose: A feature
Description: Cygwin compiler doesn't do rounding correctly when converting "unsigned long long" to "long double". Solution: Added test case to variable detection of "hdf5_cv_ullong_to_ldouble_precision_works". Platforms tested: sleipnir, fuss, and shanti - mainly to test configuration, don't need to run h5committest.
This commit is contained in:
parent
8ed5f23492
commit
db223e85b2
46
configure
vendored
46
configure
vendored
@ -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);
|
||||
}
|
||||
|
||||
|
54
configure.in
54
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)
|
||||
{
|
||||
unsigned long long l = 0xa601e80bda85fcefULL;
|
||||
long double ld;
|
||||
unsigned char *c1, *c2;
|
||||
size_t size;
|
||||
/* 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;
|
||||
|
||||
/* 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],)])
|
||||
|
Loading…
x
Reference in New Issue
Block a user