Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Issue with the G format

Phosphoenix
Beginner
356 Views

I'm getting inconsistent outputs with the G format

 

WRITE(*,'(G10.4)') -9.999              Outputs: -9.999

WRITE(*,'(G10.4)') -9.9999            Outputs: **********

WRITE(*,'(G10.4)') -9.9996            Outputs: ********** 

WRITE(*,'(G10.5)') -9.9996            Outputs: ********** 

WRITE(*,'(G10.4)') -9.99999          Outputs: -10.00

WRITE(*,'(G10.4)') -9.99999999999999  Outputs: -10.00

 

It seems to outputs asterisks when it as to round up on the 4th decimal on negative numbers.
Can someone explains why and how I can account for this behavior ?

 

I'm using version 2024.1

0 Kudos
1 Solution
Ron_Green
Moderator
297 Views

as a human, it would seem obvious that the runtime can format -9.999 with 4 fractional digits rather easily.

But the compiler is not looking at the value -9.999.  It has to be general and work in many cases.  Consider:

WRITE(*,'(G10.4)')  X

X can be any value. 

The compiler did warn you:

ifx -O0 gformat.f90 
gformat.f90(4): remark #8291: Recommended relationship between field width 'W' and the number of fractional digits 'D' in this edit descriptor is 'W>=D+7'.
WRITE(*,'(G10.4)') -9.9999
-----------^
gformat.f90(6): remark #8291: Recommended relationship between field width 'W' and the number of fractional digits 'D' in this edit descriptor is 'W>=D+7'.
WRITE(*,'(G10.4)') -9.9996 
-----------^
gformat.f90(8): remark #8291: Recommended relationship between field width 'W' and the number of fractional digits 'D' in this edit descriptor is 'W>=D+7'.
WRITE(*,'(G10.5)') -9.9996

 

It's telling you that GW.D, if you have D=4, then W needs to be 11.  You should have at least W 11 or bigger.  Here's why:

WRITE(*,'(G11.4)') -0.0099999

gives output

-0.1000E-01

it needs room for the "E[+ | -]XY".  that's 4 characters. 

You want 4 fractional digits, plus space for 4 characters for the exponent like E-01 in case it's needed, plus 1 character for a leading sign, plus 1 character for the decimal point itself, and 1 character for the digit to the left of the decimal point.  Total is 11 characters to accommodate any possible value with 4 fractional digits.
Sure, looking at it you say we don't need the E[+ | -]XY but the runtime isn't going to waste time figuring out all possible inputs.  If your format isn't wide enough for the D you specified it'll give you stars. 

View solution in original post

0 Kudos
2 Replies
Ron_Green
Moderator
298 Views

as a human, it would seem obvious that the runtime can format -9.999 with 4 fractional digits rather easily.

But the compiler is not looking at the value -9.999.  It has to be general and work in many cases.  Consider:

WRITE(*,'(G10.4)')  X

X can be any value. 

The compiler did warn you:

ifx -O0 gformat.f90 
gformat.f90(4): remark #8291: Recommended relationship between field width 'W' and the number of fractional digits 'D' in this edit descriptor is 'W>=D+7'.
WRITE(*,'(G10.4)') -9.9999
-----------^
gformat.f90(6): remark #8291: Recommended relationship between field width 'W' and the number of fractional digits 'D' in this edit descriptor is 'W>=D+7'.
WRITE(*,'(G10.4)') -9.9996 
-----------^
gformat.f90(8): remark #8291: Recommended relationship between field width 'W' and the number of fractional digits 'D' in this edit descriptor is 'W>=D+7'.
WRITE(*,'(G10.5)') -9.9996

 

It's telling you that GW.D, if you have D=4, then W needs to be 11.  You should have at least W 11 or bigger.  Here's why:

WRITE(*,'(G11.4)') -0.0099999

gives output

-0.1000E-01

it needs room for the "E[+ | -]XY".  that's 4 characters. 

You want 4 fractional digits, plus space for 4 characters for the exponent like E-01 in case it's needed, plus 1 character for a leading sign, plus 1 character for the decimal point itself, and 1 character for the digit to the left of the decimal point.  Total is 11 characters to accommodate any possible value with 4 fractional digits.
Sure, looking at it you say we don't need the E[+ | -]XY but the runtime isn't going to waste time figuring out all possible inputs.  If your format isn't wide enough for the D you specified it'll give you stars. 

0 Kudos
Phosphoenix
Beginner
254 Views

Thanks, this explains the behavior and I did overlook the warnings.
I was surprised cause the project I'm working on was migrated from an older Fortran compiler that did not behave this way and now using IFX I've been getting random asterisks outputs.

0 Kudos
Reply