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

Real variables: precision and representation

lucaslehmer
Beginner
681 Views
Hello everybody,

When trying out some elementary things with real variables in Fortran-95, I defined 3 real variables x, y and z, of REAL KIND=1, 2 and 3, respectively.
REAL (KIND=1) :: x
REAL (KIND=2) :: y
REAL (KIND=3) :: z

However I got 3 compiler warnings saying:

Specifying the kind of the type REAL with the constant '1' is non-portable - 'SELECTED_REAL_KIND(6,37)' would be better
Specifying the kind of the type REAL with the constant '2' is non-portable - 'SELECTED_REAL_KIND(15,307)' would be better
Specifying the kind of the type REAL with the constant '3' is non-portable - 'SELECTED_REAL_KIND(18,4931)' would be better

A little surprised by these "strange" numbers, I started to play around a bit with log10's and log2's to find out about the internal representation of real variables in FTN95.

KIND=1
---------
To cover a RANGE from -10^37 to 10^37 we need exactly 8 bits for the exponent (7 databits + 1 signbit).
To get a PRECISION of 6 decimal digits we need at least 21 bits (20+1) and maximally 24 bits (23+1) for the mantissa.
So, I guess that a REAL (KIND=1) is represented in 4 bytes with a (24,8)-division between mantisse and exponent.
In other words: the classical REAL*4.
So far, so good.

KIND=2
---------
To cover a RANGE from -10^307 to 10^307 we need exactly 11 bits for the exponent (10 databits + 1 signbit).
To get a PRECISION of 15 decimal digits we need at least 51 bits (50+1) and maximally 54 bits (53+1) for the mantissa.
So, I guess that a REAL (KIND=2) is represented in 8 bytes with a (53,11)-division between mantissa and exponent.
A rather unexpected division (53,11), but at least we still have the 8-byte representation.
Or is it rather a (52,12)-division?
However, with 12 bits for the exponent we could cover the range -10^616 to 10^616.


But now!

KIND=3
---------
To cover a RANGE from -10^4931 to 10^4931 we need exactly 15 bits for the exponent (14 databits + 1 signbit).
To get a PRECISION of 18 decimal digits we need at least 61 bits (60+1) and maximally 64 bits (63+1) for the mantisse.
If we assume that the PRECISION and RANGE values as supplied by the compiler are correct, that would imply that a REAL (KIND=3) variabale is represented internally by 76 to 79 bits.
Since this interval doesn't contain a multiple of 8 I suppose that a REAL (KIND=3) is represented in 10 bytes (REAL*10) with a (64,16)-division between mantissa and exponent.
However, with 16 bits for the exponent we could cover the range -10^9864 to 10^9864.

I know this is a rather long post, but could anyone confirm the numbers above and the reasoning I have applied?
Maybe I'm a bit old-fashioned, but I like to know how numbers (and objects in general) are represented internally.
I guess this is still a result of my assembler adventures in a previous life...

Many thanks for the feedback and the trouble of checking all this!
Kind regards,
Lucas.
0 Kudos
2 Replies
Jugoslav_Dujic
Valued Contributor II
681 Views
0 Kudos
lucaslehmer
Beginner
681 Views
Many thanks, Jugoslav!

Especially the first link you provided is most clarifying!
Kind regards,
Lucas.
0 Kudos
Reply