Community
cancel
Showing results for
Did you mean:
Highlighted
New Contributor II
7 Views

## Signed zero issue

Is the following a bug?  Compiled with Fortran 2019u4 x64 under Windows 10 with /O:d.  I have read the Floating-point Optimizations section of the manual, but didn't find any mention of the treatment of minus zero.

With s=-1; y=s*0.0_8 we have IEEE_CLASS(y)==IEEE_POSITIVE_ZERO

```program signed_zero_03
use, intrinsic :: ieee_arithmetic
implicit none
integer s
real(8) x,y
s=-1
x=0.0_8
y = s * x
write(*,*) (IEEE_CLASS(y)==IEEE_POSITIVE_ZERO)
y = -1 * 0.0_8
write(*,*) (IEEE_CLASS(y)==IEEE_POSITIVE_ZERO)
y = s * 0.0_8
write(*,*) (IEEE_CLASS(y)==IEEE_POSITIVE_ZERO)
end```

with output

``` F
F
T```

Tags (1)

Accepted Solutions
Highlighted
Retired Employee
7 Views

## Not a bug. If you want to

Not a bug. If you want to rely on the stranger parts of IEEE arithmetic, you have to compile with /fp:strict.

I modified the program as follows:

```program signed_zero_03
use, intrinsic :: ieee_arithmetic
implicit none
integer s
real(8) x,y
s=-1
x=0.0_8
y = s * x
write(*,101) (IEEE_CLASS(y)==IEEE_POSITIVE_ZERO), y
101 format (L1, 1X, Z16.16)
y = -1 * 0.0_8
write(*,101) (IEEE_CLASS(y)==IEEE_POSITIVE_ZERO), y
y = s * 0.0_8
write(*,101) (IEEE_CLASS(y)==IEEE_POSITIVE_ZERO) , y
end```

Compiling normally, I get:

```F 8000000000000000
F 8000000000000000
T 0000000000000000```

so you can see that the first two are negative zero, but the third is "positive zero".

But with /fp:strict:

```F 8000000000000000
F 8000000000000000
F 8000000000000000```

Now all three are negative zero. Without /fp:strict, the compiler is looser about such things and can give you arithmetically correct results that aren't what you get by strictly adhering to IEEE 754. Performance will be degraded in this mode.

--
Steve (aka "Doctor Fortran") - https://stevelionel.com/drfortran
4 Replies
Highlighted
Retired Employee
8 Views

## Not a bug. If you want to

Not a bug. If you want to rely on the stranger parts of IEEE arithmetic, you have to compile with /fp:strict.

I modified the program as follows:

```program signed_zero_03
use, intrinsic :: ieee_arithmetic
implicit none
integer s
real(8) x,y
s=-1
x=0.0_8
y = s * x
write(*,101) (IEEE_CLASS(y)==IEEE_POSITIVE_ZERO), y
101 format (L1, 1X, Z16.16)
y = -1 * 0.0_8
write(*,101) (IEEE_CLASS(y)==IEEE_POSITIVE_ZERO), y
y = s * 0.0_8
write(*,101) (IEEE_CLASS(y)==IEEE_POSITIVE_ZERO) , y
end```

Compiling normally, I get:

```F 8000000000000000
F 8000000000000000
T 0000000000000000```

so you can see that the first two are negative zero, but the third is "positive zero".

But with /fp:strict:

```F 8000000000000000
F 8000000000000000
F 8000000000000000```

Now all three are negative zero. Without /fp:strict, the compiler is looser about such things and can give you arithmetically correct results that aren't what you get by strictly adhering to IEEE 754. Performance will be degraded in this mode.

--
Steve (aka "Doctor Fortran") - https://stevelionel.com/drfortran
New Contributor II
7 Views

Thanks.  I hadn't cared about signed zeroes for a while and had forgotten which flags did what.

Highlighted
Retired Employee
7 Views

## FWIW, I once tried arguing

FWIW, I once tried arguing with the developers that a USE of the IEEE modules ought to imply /fp:strict. I was unpersuasive at this.Chapter 17.1 (Exceptions and IEEE Arithmetic) spends a lot of text saying that if certain items from the modules are "accessible" then certain behaviors are in effect. For example:

The processor’s fullest support is provided when all of IEEE_FEATURES is accessed as in
USE, INTRINSIC :: IEEE_ARITHMETIC; USE, INTRINSIC :: IEEE_FEATURES
but execution might then be slowed by the presence of a feature that is not needed.

Given the number of questions similar to yours that I received over the years, I thought such an implementation was appropriate and in the spirit if not the letter of the standard.

--
Steve (aka "Doctor Fortran") - https://stevelionel.com/drfortran
Highlighted
New Contributor I
7 Views