HUGE(3) - [MODEL:NUMERIC] Largest number of a type and kind
result = huge(x)
TYPE(kind=KIND) function huge(x)TYPE(kind=KIND),intent(in) :: x(..)
o X may be any real or integer scalar or array and any kind. o The result will be a scalar of the same type and kind as the input X
HUGE(3) returns the largest number that is not an overflow for the kind and type of X.
o X : X is an arbitrary value which is used merely to determine what kind and type of scalar is being queried. It need not be defined, as only its characteristics are used.
The result is the largest value supported by the specified type and kind.
Note the result is as the same kind as the input to ensure the returned value does not overflow. Any assignment of the result to a variable requires the variable must be able to hold the value as well. For example:
real :: r r=huge(0.0d0)where R is single-precision would almost certainly result in overflow.
Sample program:
program demo_huge use,intrinsic :: iso_fortran_env, only : int8, int16, int32, int64 use,intrinsic :: iso_fortran_env, only : real32,real64,real128 implicit none character(len=*),parameter :: f=(i2,1x,2(i11,1x),f14.0:,1x,l1,1x,a) integer :: i, j, k, biggest real :: v, w integer,allocatable :: undef(:,:,:)################################# ################################# Results:print *,basics:
print *, huge(0), huge(0.0), huge(0.0d0) print *, tiny(0.0), tiny(0.0d0) print *, an array argument returns a scalar print *, huge([10_int8,20_int8,30_int8]) print *, the value of the argument does not matter, it does not print *, even need to be allocated, just the type and kind are print *, used,huge(1000),huge(-654321),huge(undef)
print *, dusty corners:
print *, Perhaps instead of an "infinite" loop you want to make print *, a very large one so you have a counter handy. do i=1,huge(0)-1 call random_number(w) if(w > 0.9999999)exit enddo write(*,*)exited with counter=,i ! use huge(0)-1 not huge(0) because when a loop terminates normally ! the counter is set to the last value + 1. If the loop reached ! i=huge(0) adding 1 would cause an overflow!
! Can HUGE(1.d0) be accurately formatted? print (E330.320), huge(1.d0) print *, huge(1.d0) print (g0), huge(1.d0)
print *,ranges for signed numbers are symmetrical so if HUGE(0.0) print *,is a valid number so is -HUGE(0.0). print *, huge(0.0),-huge(0.0), huge(0.0)-huge(0.0) print *,but for 2s-complement whole numbers -1-huge(0)= print *, -1-huge(0) print *,is a valid number too, but huge(0)+1 will cause an overflow! print *,Almost all computers use 2s-complement integers now-adays. print *,so -huge(0)-1 is often used as a "magic number" to designate print *,invalid whole numbers, as INTEGER types do not have a Nan print *,or Infinite value like floats do if it is not a "possible" print *,value for a computation. print * print *,for a single byte a value can be from -128 to 127 so maybe print *,-128 is not unlikely to be used though, for example: print *,range of a 2scomplement one-byte kind is,-huge(0_int8)-1,& & to,huge(0_int8) print *,so there is no "perfect" integer value to represent an print *,invalid number except on a case-by-case basis.
print *,advanced:
print *,be careful of overflow; Fortran is not required to report it print *,See OUT_OF_RANGE(3) for information on detecting overflows.
biggest=huge(0) ! be careful of overflow when using integers in computation do i=1,14 j=6**i ! Danger, Danger w=6**i ! Danger, Danger v=6.0**i k=v ! Danger, Danger
if(v.gt.biggest)then write(*,f) i, j, k, v, v.eq.w, wrong j and k and w else write(*,f) i, j, k, v, v.eq.w endif enddo
! a simple check of the product of two 32-bit integers print *,checkprod([2,4,5,8],[10000,20000,3000000,400000000])
contains impure elemental function checkprod(i,j) result(ij32) ! checkprod(3f) - check for overflow when multiplying 32-bit integers use,intrinsic :: iso_fortran_env, only : int8, int16, int32, int64 integer(kind=int32),intent(in) :: i, j integer(kind=int64) :: ij64 integer(kind=int32) :: ij32 integer,parameter :: toobig=huge(0_int32) character(len=80) :: message ij64=int(i,kind=int64)*int(j,kind=int64) if(ij64.gt.toobig)then write(message,(*(g0)))& & <ERROR>checkprod(3f):,i,*,j,=,ij64,>,toobig stop message else ij32=ij64 endif end function checkprod end program demo_huge
> basics: > 2147483647 3.40282347E+38 1.7976931348623157E+308 > 1.17549435E-38 2.2250738585072014E-308 > an array argument returns a scalar > 127 > the value of the argument does not matter, it does not > even need to be allocated, just the type and kind are > used 2147483647 2147483647 2147483647 > dusty corners: > Perhaps instead of an "infinite" loop you want to make > a very large one so you have a counter handy. > exited with counter= 851169 > 0.17976931348623157081452742373170435679807056752584499 > 6598917476803157260780028538760589558632766878171540458 > 9535143824642343213268894641827684675467035375169860499 > 1057655128207624549009038932894407586850845513394230458 > 3236903222948165808559332123348274797826204144723168738 > 17718091929988125040402618412485836800000000000+309 > 1.7976931348623157E+308 > 0.17976931348623157E+309 > ranges for signed numbers are symmetrical so if HUGE(0.0) > is a valid number so is -HUGE(0.0). > 3.40282347E+38 -3.40282347E+38 0.00000000 > but for 2s-complement whole numbers -1-huge(0)= > -2147483648 > is a valid number too, but huge(0)+1 will cause an overflow! > Almost all computers use 2s-complement integers now-adays. > so -huge(0)-1 is often used as a "magic number" to designate > invalid whole numbers, as INTEGER types do not have a Nan > or Infinite value like floats do if it is not a "possible" > value for a computation. > > for a single byte a value can be from -128 to 127 so maybe > -128 is not unlikely to be used though, for example: > range of a 2scomplement one-byte kind is -128 to 127 > so there is no "perfect" integer value to represent an > invalid number except on a case-by-case basis. > advanced: > be careful of overflow; Fortran is not required to report it > See OUT_OF_RANGE(3) for information on detecting overflows. > 1 6 6 6. T > 2 36 36 36. T > 3 216 216 216. T > 4 1296 1296 1296. T > 5 7776 7776 7776. T > 6 46656 46656 46656. T > 7 279936 279936 279936. T > 8 1679616 1679616 1679616. T > 9 10077696 10077696 10077696. T > 10 60466176 60466176 60466176. T > 11 362797056 362797056 362797056. T > 12 -2118184960 -2147483648 2176782336. F wrong j and k and w > 13 175792128 -2147483648 13060694016. F wrong j and k and w > 14 1054752768 -2147483648 78364164096. F wrong j and k and w > STOP <ERROR>checkprod(3f):8*400000000=3200000000>2147483647# TRIVIA
The Fortran standard does not specify what the largest value can be in a "Ew.d" edit descriptor, so "E330.320" will likely generate a value that fills all the positions without an error, or maybe cap it at some number of digits even though the vast majority will not be significant.
But perhaps the bigger surprise is the same insignificant digits will likely be generated across platforms.
Unless the platform chooses to pad with zeros it is likely a platform generates the number shown above, not random digits once it gets past the few significant digits.
Most compilers print identical digits because IEEE 754 double precision defines an exact binary bit pattern for "HUGE(0.D0)", and runtime libraries use standard, deterministic conversion algorithms to translate those exact bits into decimal text. Trailing digits beyond the 17th significant figure are purely algorithmic padding or repeating representations.
#### IEEE 754 Binary Representation
+ The value "HUGE(0.D0)" in Fortran represents the maximum positive finite double-precision number (1.7976931348623157 × 10\*\*308). + Internally, this is stored as a fixed 64-bit binary floating-point number with a 53-bit significand (mantissa) and an 11-bit exponent. + Because the underlying binary value is identical across all conforming hardware and compilers, the exact mathematical value being converted is always the same.#### Decimal Conversion and Padding
+ A standard double-precision number only contains about 15 to 17 significant decimal digits of true numerical precision. + When you request 320 digits of precision using "E330.320", the runtime formatting library runs out of real bits from the binary number very quickly. + To fulfill the large requested width, the compilers runtime library either pads the remaining lower-order digits with deterministic zeros, or it mathematically exposes the repeating/terminating behavior of the binary-to-decimal floating-point conversion routine (such as Grisu or Ryu algorithms). Because different modern compilers often link against similar standard math/io library implementations or follow the exact same IEEE decimal formatting specifications, the extended trailing digits match precisely.
Fortran 95
DIGITS(3), EPSILON(3), EXPONENT(3), FRACTION(3), MAXEXPONENT(3), MINEXPONENT(3), NEAREST(3), PRECISION(3), RADIX(3), RANGE(3), RRSPACING(3), SCALE(3), SET_EXPONENT(3), SPACING(3), TINY(3)
Fortran intrinsic descriptions (license: MIT) @urbanjost
