c10 = ( 1.7951958020513104220_10, 2.6457513110645905904_10 )
write(*,*) 'Alive to here'
write(*,*) abs(c10)
write(*,*) 'Survived the ordeal'
end program abstest
C:\gfortran\james\intrinsics\func1>gfortran abs.f90 -oabs
C:\gfortran\james\intrinsics\func1>abs
Alive to here
C:\gfortran\james\intrinsics\func1>
--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end
This one works for me on FreeBSD with versions 4.2.3 and
4.4.0. I suspect your version of mingw or win64 has a broken
printf/scanf in libc with long doubles.
This is not a problem with printf/scanf. The problem is on the function
"abs" on mingw-w64. On mingw32, everything is fine. See the following:
C:\TEMP>type james.f90
program abstest
complex(10) c10
c10 = ( 1.7951958020513104220_10, 2.6457513110645905904_10 )
write(*,*) 'Alive to here'
write(*,*) abs(c10)
write(*,*) 'Survived the ordeal'
end program abstest
C:\TEMP>gfortran -o james.exe james.f90
C:\TEMP>james
Alive to here
3.1973001059804579615
Survived the ordeal
C:\TEMP>
However, on mingw-w64, the program dies when calling the function abs(). If
we modify james' program as:
program abstest
complex(10) c10
complex(10) cc
c10 = ( 1.7951958020513104220_10, 2.6457513110645905904_10 )
write(*,*) 'Alive to here'
cc = abs(c10)
write(*,*) 'Survived the ordeal'
end program abstest
What you can get is nothing but Alive to here. Maybe FX should take a look
at the function "abs"
In the previous post, I declare "cc" as "complex(10) cc". Suppose "cc"
should be declared as "real(10) cc". The program exit when calling the
function "abs" on mingw-w64, which can be seen in the following:
C:\temp\fortran>type james.f90
program abstest
complex(10) c10
real(10) cc
c10 = ( 1.7951958020513104220_10, 2.6457513110645905904_10 )
write(*,*) 'Alive to here'
cc =abs(c10)
write(*,*) 'Survived the ordeal'
end program abstest
C:\temp\fortran>gfortran -o james.exe james.f90
C:\temp\fortran>james
Alive to here
C:\temp\fortran>
(snip)
> However, on mingw-w64, the program dies when calling the function abs(). If
> we modify james' program as:
>
> program abstest
> complex(10) c10
> complex(10) cc
> c10 = ( 1.7951958020513104220_10, 2.6457513110645905904_10 )
> write(*,*) 'Alive to here'
> cc = abs(c10)
> write(*,*) 'Survived the ordeal'
> end program abstest
>
>
> What you can get is nothing but Alive to here. Maybe FX should take a look
> at the function "abs"
mobile:kargl[226] gfc -c j4.f90
mobile:kargl[227] nm j4.o |more
00000000 T MAIN__
U _gfortran_set_std
U _gfortran_st_write
U _gfortran_st_write_done
U _gfortran_transfer_character
U cabsl
So mingw-w64 or win64 don't supply a funtion cabsl() funtion?
Try the following.
#include <stdio.h>
#include <math.h>
#include <complex.h>
int main(void)
{
long complex z;
long double x;
z = 1. + 2 * I;
x = cabsl(z);
printf("cabsl(%Le,%Le) = %Le\n", creall(z), cimagl(z), x);
return 0;
}
mobile:kargl[242] cc -o z a.c -lm
mobile:kargl[243] ./z
cabsl(1.000000e+00,2.000000e+00) = 2.236068e+00
win64 doesn't, but mingw does. The problem has to be there. (If there
simply weren't any cabsl function available, the program wouldn't link.)
> Try the following.
That will indeed help. James, can you also run the following modified
program?
#include <stdio.h>
#include <math.h>
#include <complex.h>
int main(void)
{
long complex z;
long double x;
z = 1. + 2 * I;
x = __builtin_cabsl(z);
printf("cabsl(%Le,%Le) = %Le\n", creall(z), cimagl(z), x);
return 0;
}
--
FX
I think you are right. I run your example on W64. The result is as:
C:\temp\c>type kargl.c
#include <stdio.h>
#include <math.h>
#include <complex.h>
int main(void)
{
long complex z;
long double x;
printf("I am at A.\n");
z = 1. + 2 * I;
printf("I am at B.\n");
x = cabsl(z);
printf("I am at C.\n");
printf("cabsl(%Le,%Le) = %Le\n", creall(z), cimagl(z), x);
return 0;
}
C:\temp\c>gcc -o kargl.exe kargl.c
C:\temp\c>kargl
I am at A.
I am at B.
C:\temp\c>
The result on Win64 is as:
C:\temp\c>type fx.c
#include <stdio.h>
#include <math.h>
#include <complex.h>
int main(void)
{
long complex z;
long double x;
printf("I am at A.\n");
z = 1. + 2 * I;
printf("I am at B.\n");
x = __builtin_cabsl(z);
printf("I am at C.\n");
printf("cabsl(%Le,%Le) = %Le\n", creall(z), cimagl(z), x);
return 0;
}
C:\temp\c>gcc -o fx.exe fx.c
C:\temp\c>fx
What happens if you change the above line to
x = hypotl(creall(z), cimagl(z));
> printf("I am at C.\n");
> printf("cabsl(%Le,%Le) = %Le\n", creall(z), cimagl(z), x);
> return 0;
> }
>> So mingw-w64 or win64 don't supply a funtion cabsl() funtion?
> win64 doesn't, but mingw does. The problem has to be there. (If there
> simply weren't any cabsl function available, the program wouldn't link.)
>> Try the following.
> That will indeed help. James, can you also run the following modified
> program?
C:\gfortran\james\intrinsics\func1>type cabs.c
#include <stdio.h>
#include <math.h>
#include <complex.h>
int main(void)
{
long complex z;
long double x;
z = 1. + 2 * I;
x = __builtin_cabsl(z);
printf("cabsl(%Le,%Le) = %Le\n", creall(z), cimagl(z), x);
return 0;
}
C:\gfortran\james\intrinsics\func1>gcc cabs.c -ocabs
C:\gfortran\james\intrinsics\func1>cabs
C:\gfortran\james\intrinsics\func1>
Another test (but I don't know whether it helps)
C:\gfortran\james\intrinsics\func1>type frexp.c
#include <stdio.h>
#include <math.h>
#include <complex.h>
int main(void)
{
int i;
long double x;
long double y;
x = 1.;
i = 2;
y = __builtin_scalbnl(x, i);
printf("scalbnl(%Le,%d) = %Le\n", x, i, y);
return 0;
}
C:\gfortran\james\intrinsics\func1>gcc frexp.c -ofrexp
C:\gfortran\james\intrinsics\func1>frexp
C:\gfortran\james\intrinsics\func1>
Thank you for your attention to this matter.
I think I found the problem. cabsl put long double in 12-byte space. GCC
team needs to correct it.
By default, 32-bit gcc (or gfortran) allocates 12 bytes for long double (or
real*10). There is no problem for 32-bit Windows. However, 64-bit gcc (or
gfortran), by default, allocates 16 bytes for long double. That is a reason
to crash. I re-run your example with 96 bits, and everything is OK. See the
following:
C:\temp\c>type kargl.c
#include <stdio.h>
#include <math.h>
#include <complex.h>
int main(void)
{
long complex z;
long double x;
printf("I am at A.\n");
z = 1. + 2 * I;
printf("I am at B.\n");
x = cabsl(z);
printf("I am at C.\n");
printf("cabsl(%Le,%Le) = %Le\n", creall(z), cimagl(z), x);
return 0;
}
C:\temp\c>gcc -m128bit-long-double kargl.c -o kargl.exe
C:\temp\c>kargl
I am at A.
I am at B.
C:\temp\c>gcc -m96bit-long-double kargl.c -o kargl.exe
C:\temp\c>kargl
I am at A.
I am at B.
I am at C.
cabsl(1.133078e-317,1.133055e-317) = 1.133047e-317
C:\temp\c>
I not so sure. See below.
> By default, 32-bit gcc (or gfortran) allocates 12 bytes for long double (or
> real*10). There is no problem for 32-bit Windows. However, 64-bit gcc (or
> gfortran), by default, allocates 16 bytes for long double. That is a reason
> to crash. I re-run your example with 96 bits, and everything is OK. See the
> following:
>
> C:\temp\c>type kargl.c
> #include <stdio.h>
> #include <math.h>
> #include <complex.h>
> int main(void)
> {
> long complex z;
> long double x;
> printf("I am at A.\n");
> z = 1. + 2 * I;
> printf("I am at B.\n");
> x = cabsl(z);
> printf("I am at C.\n");
> printf("cabsl(%Le,%Le) = %Le\n", creall(z), cimagl(z), x);
> return 0;
> }
(snip)
> C:\temp\c>kargl
> I am at A.
> I am at B.
> I am at C.
> cabsl(1.133078e-317,1.133055e-317) = 1.133047e-317
The correct output is
cabsl(1.000000e+00,2.000000e+00) = 2.236068e+00
It looks like win64 has messed up 'long complex' support
in it's libraries.
Sorry, i did not check the number. It seems the problem is in the libraries.
>> cabsl(1.133078e-317,1.133055e-317) = 1.133047e-317
> The correct output is
> cabsl(1.000000e+00,2.000000e+00) = 2.236068e+00
Are you sure it's not the C compiler which is messed up here? In my
complex tests, some things went OK:
Test of AIMAG intrinsic
Name = Z, Type = COMPLEX, Kind = 4, Value = ( 1.7951958 ,
6457512 )
Name = RESULT, Type = REAL, Kind = 4, Value = 2.6457512
Test of AIMAG intrinsic
Name = Z, Type = COMPLEX, Kind = 8, Value = ( 1.7951958020513104 ,
2.6457513110645907 )
Name = RESULT, Type = REAL, Kind = 8, Value = 2.6457513110645907
Test of AIMAG intrinsic
Name = Z, Type = COMPLEX, Kind = 10, Value = ( 1.7951958020513104220 ,
2.6457513110645905904 )
Name = RESULT, Type = REAL, Kind = 10, Value = 2.6457513110645905904
Test of CMPLX intrinsic
Name = x, Type = COMPLEX, Kind = 4, Value = ( 1.7951958 ,
6457512 )
Name = RESULT, Type = COMPLEX, Kind = 4, Value = ( 1.7951958 ,
2.6457512 )
Test of CMPLX intrinsic
Name = x, Type = COMPLEX, Kind = 8, Value = ( 1.7951958020513104 ,
2.6457513110645907 )
Name = RESULT, Type = COMPLEX, Kind = 4, Value = ( 1.7951958 ,
2.6457512 )
Test of CMPLX intrinsic
Name = x, Type = COMPLEX, Kind = 10, Value = ( 1.7951958020513104220 ,
2.6457513110645905904 )
Name = RESULT, Type = COMPLEX, Kind = 4, Value = ( 1.7951958 ,
2.6457512 )
Test of CONJG intrinsic
Name = Z, Type = COMPLEX, Kind = 4, Value = ( 1.7951958 ,
6457512 )
Name = RESULT, Type = COMPLEX, Kind = 4, Value = ( 1.7951958
, -2.6457512 )
Test of CONJG intrinsic
Name = Z, Type = COMPLEX, Kind = 8, Value = ( 1.7951958020513104 ,
2.6457513110645907 )
Name = RESULT, Type = COMPLEX, Kind = 8, Value = ( 1.7951958020513104
, -2.6457513110645907 )
Test of CONJG intrinsic
Name = Z, Type = COMPLEX, Kind = 10, Value = ( 1.7951958020513104220 ,
2.6457513110645905904 )
Name = RESULT, Type = COMPLEX, Kind = 10, Value = ( 1.7951958020513104220
, -2.6457513110645905904 )
Test of COS intrinsic
Name = X, Type = COMPLEX, Kind = 4, Value = ( 1.7951958 ,
6457512 )
Name = RESULT, Type = COMPLEX, Kind = 4, Value = ( -1.5760025
, -6.8357444 )
Test of COS intrinsic
Name = X, Type = COMPLEX, Kind = 8, Value = ( 1.7951958020513104 ,
2.6457513110645907 )
Name = RESULT, Type = COMPLEX, Kind = 8, Value = ( -1.5760025269365714
, -6.8357451176440049 )
Test of COS intrinsic
Name = X, Type = COMPLEX, Kind = 10, Value = ( 1.7951958020513104220 ,
2.6457513110645905904 )
Name = RESULT, Type = COMPLEX, Kind = 10, Value = ( -1.5760025269365716216
, -6.8357451176440044969 )
Test of DBLE intrinsic
Name = A, Type = COMPLEX, Kind = 4, Value = ( 1.7951958 ,
6457512 )
Name = RESULT, Type = REAL, Kind = 8, Value = 1.7951958179473877
Test of DBLE intrinsic
Name = A, Type = COMPLEX, Kind = 8, Value = ( 1.7951958020513104 ,
2.6457513110645907 )
Name = RESULT, Type = REAL, Kind = 8, Value = 1.7951958020513104
Test of DBLE intrinsic
Name = A, Type = COMPLEX, Kind = 10, Value = ( 1.7951958020513104220 ,
2.6457513110645905904 )
Name = RESULT, Type = REAL, Kind = 8, Value = 1.7951958020513104
Test of DCMPLX intrinsic
Name = X, Type = COMPLEX, Kind = 4, Value = ( 1.7951958 ,
6457512 )
Name = RESULT, Type = COMPLEX, Kind = 8, Value = ( 1.7951958179473877 ,
2.6457512378692627 )
Test of DCMPLX intrinsic
Name = X, Type = COMPLEX, Kind = 8, Value = ( 1.7951958020513104 ,
2.6457513110645907 )
Name = RESULT, Type = COMPLEX, Kind = 8, Value = ( 1.7951958020513104 ,
2.6457513110645907 )
Test of DCMPLX intrinsic
Name = X, Type = COMPLEX, Kind = 10, Value = ( 1.7951958020513104220 ,
2.6457513110645905904 )
Name = RESULT, Type = COMPLEX, Kind = 8, Value = ( 1.7951958020513104 ,
2.6457513110645907 )
Test of DFLOAT intrinsic
Name = A, Type = COMPLEX, Kind = 4, Value = ( 1.7951958 ,
6457512 )
Name = RESULT, Type = REAL, Kind = 8, Value = 1.7951958179473877
Test of DFLOAT intrinsic
Name = A, Type = COMPLEX, Kind = 8, Value = ( 1.7951958020513104 ,
2.6457513110645907 )
Name = RESULT, Type = REAL, Kind = 8, Value = 1.7951958020513104
Test of DFLOAT intrinsic
Name = A, Type = COMPLEX, Kind = 10, Value = ( 1.7951958020513104220 ,
2.6457513110645905904 )
Name = RESULT, Type = REAL, Kind = 8, Value = 1.7951958020513104
Test of EXP intrinsic
Name = X, Type = COMPLEX, Kind = 4, Value = ( 1.7951958 ,
6457512 )
Name = RESULT, Type = COMPLEX, Kind = 4, Value = ( -5.2955785 ,
2.8644578 )
Test of EXP intrinsic
Name = X, Type = COMPLEX, Kind = 8, Value = ( 1.7951958020513104 ,
2.6457513110645907 )
Name = RESULT, Type = COMPLEX, Kind = 8, Value = ( -5.2955785446929182 ,
2.8644573648303466 )
Test of EXP intrinsic
Name = X, Type = COMPLEX, Kind = 10, Value = ( 1.7951958020513104220 ,
2.6457513110645905904 )
Name = RESULT, Type = COMPLEX, Kind = 10, Value = ( -5.2955785446929180188
, 2.8644573648303478301 )
Test of INT intrinsic
Name = A, Type = COMPLEX, Kind = 4, Value = ( 1.7951958 ,
6457512 )
Name = RESULT, Type = INTEGER, Kind = 4, Value = 1
Test of INT intrinsic
Name = A, Type = COMPLEX, Kind = 8, Value = ( 1.7951958020513104 ,
2.6457513110645907 )
Name = RESULT, Type = INTEGER, Kind = 4, Value = 1
Test of INT intrinsic
Name = A, Type = COMPLEX, Kind = 10, Value = ( 1.7951958020513104220 ,
2.6457513110645905904 )
Name = RESULT, Type = INTEGER, Kind = 4, Value = 1
Test of INT2 intrinsic
Name = A, Type = COMPLEX, Kind = 4, Value = ( 1.7951958 ,
6457512 )
Name = RESULT, Type = INTEGER, Kind = 2, Value = 1
Test of INT2 intrinsic
Name = A, Type = COMPLEX, Kind = 8, Value = ( 1.7951958020513104 ,
2.6457513110645907 )
Name = RESULT, Type = INTEGER, Kind = 2, Value = 1
Test of INT2 intrinsic
Name = A, Type = COMPLEX, Kind = 10, Value = ( 1.7951958020513104220 ,
2.6457513110645905904 )
Name = RESULT, Type = INTEGER, Kind = 2, Value = 1
Test of INT8 intrinsic
Name = A, Type = COMPLEX, Kind = 4, Value = ( 1.7951958 ,
6457512 )
Name = RESULT, Type = INTEGER, Kind = 8, Value = 1
Test of INT8 intrinsic
Name = A, Type = COMPLEX, Kind = 8, Value = ( 1.7951958020513104 ,
2.6457513110645907 )
Name = RESULT, Type = INTEGER, Kind = 8, Value = 1
Test of INT8 intrinsic
Name = A, Type = COMPLEX, Kind = 10, Value = ( 1.7951958020513104220 ,
2.6457513110645905904 )
Name = RESULT, Type = INTEGER, Kind = 8, Value = 1
Test of LOC intrinsic
Name = ARRAY, Type = COMPLEX, Kind = 4, Value = ( 1.7951958 ,
6457512 )
Name = RESULT, Type = INTEGER, Kind = 8, Value = 2293336
Test of LOC intrinsic
Name = ARRAY, Type = COMPLEX, Kind = 8, Value = ( 1.7951958020513104 ,
2.6457513110645907 )
Name = RESULT, Type = INTEGER, Kind = 8, Value = 2293344
Test of LOC intrinsic
Name = ARRAY, Type = COMPLEX, Kind = 10, Value = ( 1.7951958020513104220
, 2.6457513110645905904 )
Name = RESULT, Type = INTEGER, Kind = 8, Value = 2293296
Test of LONG intrinsic
Name = A, Type = COMPLEX, Kind = 4, Value = ( 1.7951958 ,
6457512 )
Name = RESULT, Type = INTEGER, Kind = 4, Value = 1
Test of LONG intrinsic
Name = A, Type = COMPLEX, Kind = 8, Value = ( 1.7951958020513104 ,
2.6457513110645907 )
Name = RESULT, Type = INTEGER, Kind = 4, Value = 1
Test of LONG intrinsic
Name = A, Type = COMPLEX, Kind = 10, Value = ( 1.7951958020513104220 ,
2.6457513110645905904 )
Name = RESULT, Type = INTEGER, Kind = 4, Value = 1
Test of REAL intrinsic
Name = A, Type = COMPLEX, Kind = 4, Value = ( 1.7951958 ,
6457512 )
Name = RESULT, Type = REAL, Kind = 4, Value = 1.7951958
Test of REAL intrinsic
Name = A, Type = COMPLEX, Kind = 8, Value = ( 1.7951958020513104 ,
2.6457513110645907 )
Name = RESULT, Type = REAL, Kind = 8, Value = 1.7951958020513104
Test of REAL intrinsic
Name = A, Type = COMPLEX, Kind = 10, Value = ( 1.7951958020513104220 ,
2.6457513110645905904 )
Name = RESULT, Type = REAL, Kind = 10, Value = 1.7951958020513104220
Test of SIN intrinsic
Name = X, Type = COMPLEX, Kind = 4, Value = ( 1.7951958 ,
6457512 )
Name = RESULT, Type = COMPLEX, Kind = 4, Value = ( 6.9049177
, -1.5602142 )
Test of SIN intrinsic
Name = X, Type = COMPLEX, Kind = 8, Value = ( 1.7951958020513104 ,
2.6457513110645907 )
Name = RESULT, Type = COMPLEX, Kind = 8, Value = ( 6.9049182288673823
, -1.5602142156965715 )
Test of SIN intrinsic
Name = X, Type = COMPLEX, Kind = 10, Value = ( 1.7951958020513104220 ,
2.6457513110645905904 )
Name = RESULT, Type = COMPLEX, Kind = 10, Value = ( 6.9049182288673813406
, -1.5602142156965718157 )
Test of SIZEOF intrinsic
Name = I, Type = COMPLEX, Kind = 4, Value = ( 1.7951958 ,
6457512 )
Name = RESULT, Type = INTEGER, Kind = 8, Value = 8
Test of SIZEOF intrinsic
Name = I, Type = COMPLEX, Kind = 8, Value = ( 1.7951958020513104 ,
2.6457513110645907 )
Name = RESULT, Type = INTEGER, Kind = 8, Value = 16
Test of SIZEOF intrinsic
Name = I, Type = COMPLEX, Kind = 10, Value = ( 1.7951958020513104220 ,
2.6457513110645905904 )
Name = RESULT, Type = INTEGER, Kind = 8, Value = 32
So the C compiler seems to me to be messed up worse than the Fortran
compiler.
For no reason. MS has very poor long double support. What everyone is
talking about here (whether they realize it or not, I don't know) is
about the mingw library.
--
FX
> What happens if you change the above line to
> x = hypotl(creall(z), cimagl(z));
I don't know if it's relevant any more, but my testing has reached
HYPOT, and it fails like ABS, SPACING, and RRSPACING:
C:\gfortran\james\intrinsics\funr2>type hypot.f90
program test_hypot
real(10) x, y, z
x = 1
y = 2
write(*,*) 'To here'
z = hypot(x,y)
write(*,*) 'To the end'
end program test_hypot
C:\gfortran\james\intrinsics\funr2>gfortran hypot.f90 -ohypot
C:\gfortran\james\intrinsics\funr2>hypot
To here
C:\gfortran\james\intrinsics\funr2>