Skip to content

Commit a1e853b

Browse files
committed
Fix #147: xlapy2 not propagating nans
xLAPY2 now returns a NaN whenever input variables X or Y are NaNs. The previous xLAPY2 was relying on FORTRAN INTRINSIC MAX and MIN to behave in a certain way with NaNs (i.e. return a NaN whenever X or Y are NaN) and this behavior is not observed on some (most?) compilers. We handle the NaN behavior of xLAPY2 by checking for NaNs at the start of the function. Thanks to Andreas Noack for providing report and sample code to demonstrate the problem.
1 parent 2f60afb commit a1e853b

2 files changed

Lines changed: 43 additions & 16 deletions

File tree

SRC/dlapy2.f

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -82,20 +82,32 @@ DOUBLE PRECISION FUNCTION DLAPY2( X, Y )
8282
* ..
8383
* .. Local Scalars ..
8484
DOUBLE PRECISION W, XABS, YABS, Z
85+
LOGICAL X_IS_NAN, Y_IS_NAN
86+
* ..
87+
* .. External Functions ..
88+
LOGICAL DISNAN
89+
EXTERNAL DISNAN
8590
* ..
8691
* .. Intrinsic Functions ..
8792
INTRINSIC ABS, MAX, MIN, SQRT
8893
* ..
8994
* .. Executable Statements ..
9095
*
91-
XABS = ABS( X )
92-
YABS = ABS( Y )
93-
W = MAX( XABS, YABS )
94-
Z = MIN( XABS, YABS )
95-
IF( Z.EQ.ZERO ) THEN
96-
DLAPY2 = W
97-
ELSE
98-
DLAPY2 = W*SQRT( ONE+( Z / W )**2 )
96+
X_IS_NAN = DISNAN( X )
97+
Y_IS_NAN = DISNAN( Y )
98+
IF ( X_IS_NAN ) DLAPY2 = X
99+
IF ( Y_IS_NAN ) DLAPY2 = Y
100+
*
101+
IF ( .NOT.( X_IS_NAN.OR.Y_IS_NAN ) ) THEN
102+
XABS = ABS( X )
103+
YABS = ABS( Y )
104+
W = MAX( XABS, YABS )
105+
Z = MIN( XABS, YABS )
106+
IF( Z.EQ.ZERO ) THEN
107+
DLAPY2 = W
108+
ELSE
109+
DLAPY2 = W*SQRT( ONE+( Z / W )**2 )
110+
END IF
99111
END IF
100112
RETURN
101113
*

SRC/slapy2.f

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -82,20 +82,35 @@ REAL FUNCTION SLAPY2( X, Y )
8282
* ..
8383
* .. Local Scalars ..
8484
REAL W, XABS, YABS, Z
85+
LOGICAL X_IS_NAN, Y_IS_NAN
86+
* ..
87+
* .. External Functions ..
88+
LOGICAL SISNAN
89+
EXTERNAL SISNAN
8590
* ..
8691
* .. Intrinsic Functions ..
8792
INTRINSIC ABS, MAX, MIN, SQRT
8893
* ..
8994
* .. Executable Statements ..
9095
*
91-
XABS = ABS( X )
92-
YABS = ABS( Y )
93-
W = MAX( XABS, YABS )
94-
Z = MIN( XABS, YABS )
95-
IF( Z.EQ.ZERO ) THEN
96-
SLAPY2 = W
97-
ELSE
98-
SLAPY2 = W*SQRT( ONE+( Z / W )**2 )
96+
* ..
97+
* .. Executable Statements ..
98+
*
99+
X_IS_NAN = SISNAN( X )
100+
Y_IS_NAN = SISNAN( Y )
101+
IF ( X_IS_NAN ) SLAPY2 = X
102+
IF ( Y_IS_NAN ) SLAPY2 = Y
103+
*
104+
IF ( .NOT.( X_IS_NAN.OR.Y_IS_NAN ) ) THEN
105+
XABS = ABS( X )
106+
YABS = ABS( Y )
107+
W = MAX( XABS, YABS )
108+
Z = MIN( XABS, YABS )
109+
IF( Z.EQ.ZERO ) THEN
110+
SLAPY2 = W
111+
ELSE
112+
SLAPY2 = W*SQRT( ONE+( Z / W )**2 )
113+
END IF
99114
END IF
100115
RETURN
101116
*

0 commit comments

Comments
 (0)