<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
 
 <title>Homepage of Michael Goerz - Fortran</title>
 <link href="http://users.physik.fu-berlin.de/~mgoerz/feeds/categories/Fortran" rel="self"/>
 <link href="http://users.physik.fu-berlin.de/~mgoerz/"/>
 <updated>2013-03-14T16:35:44+01:00</updated>
 <author>
   <name>Michael Goerz</name>
   <email>goerz@physik.fu-berlin.de</email>
 </author>

 
 <entry>
   <title>Floating Points Numbers, Down to the Bit</title>
   <link href="blog/2011/05/floating-point-numbers-down-to-the-bit/"/>
   <updated>2011-05-28T00:00:00+02:00</updated>
   <id>blog/2011/05/floating-point-numbers-down-to-the-bit</id>
   <content type="html">&lt;h3 id=&#39;floating_point_memory_format&#39;&gt;Floating Point Memory Format&lt;/h3&gt;

&lt;p&gt;The general idea behind floating point numbers is the same as behind scientific notation: write a mantissa, combined with an exponent to move the decimal point. E.g. $1.093 \times 10^5 = 10^5 \sum_{k=0}^3 a_k 10^{-k}$ with $a_k = 1,0,9,3$. The exact same thing can be done in binary:&lt;/p&gt;

&lt;p&gt;$$ v = 2^e \sum_{k=0}^{n-1} a_k 2^{-k} $$&lt;/p&gt;

&lt;p&gt;In memory, floats can be stored by reserving a section of the total available bits to store the exponent, while the mantissa is stored in the remaining bits. For a double precision float, the total size is 64 bit. One bit is used to encode the sign of the number, 11 bits for the exponent, and the remaining 52 bits for the mantissa. In order to only have to store positive integers as exponents, as fixed bias exponent of 1023 is subtracted from the stored exponent. Also, the digit $a_0$ is assumed to be 1, and is not stored explicitly in the mantissa; the effective number of mantissa digits is therefore 53. For details, see the Wikipedia article for the &lt;a href=&#39;http://en.wikipedia.org/wiki/Double_precision_floating-point_format&#39;&gt;Double precision floating-point format&lt;/a&gt;. The &lt;a href=&#39;http://en.wikipedia.org/wiki/Single_precision_floating-point_format&#39;&gt;Single precision floating-point format&lt;/a&gt; is very similar, but only uses 32 total bits.&lt;/p&gt;

&lt;h3 id=&#39;parsing_double_precision_floats_in_python&#39;&gt;Parsing Double Precision Floats in Python&lt;/h3&gt;

&lt;p&gt;It is relatively easy to parse a binary representation of a double precision float. I&amp;#8217;ve written a python script to do so (both for double and single precision), available on &lt;a href=&#39;https://github.com/goerz/float_parsers&#39;&gt;Github&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Given a representation (as a hex string) or a float value (as a string like &amp;#8220;1.2&amp;#8221; or &amp;#8220;-2.3456e-192&amp;#8221;) the scripts decompose the binary representation into sign, exponent, and mantissa, and print out this information along with the exact decimal the binary representation corresponds to according to the floating point model.&lt;/p&gt;

&lt;p&gt;A similar online tool for double precision floats is available at &lt;a href=&#39;http://www.binaryconvert.com/convert_double.html&#39;&gt;binaryconvert.com&lt;/a&gt; (also &lt;a href=&#39;http://www.binaryconvert.com/convert_float.html&#39;&gt;single precision&lt;/a&gt; and &lt;a href=&#39;http://www.binaryconvert.com/index.html&#39;&gt;others&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;The key routine:&lt;/p&gt;
&lt;div class=&#39;highlight&#39;&gt;&lt;pre&gt;&lt;code class=&#39;python&#39;&gt;    &lt;span class=&#39;n&#39;&gt;BIAS&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;mi&#39;&gt;1023&lt;/span&gt;                &lt;span class=&#39;c&#39;&gt;# constant to be subtracted from the stored exponent&lt;/span&gt;
    &lt;span class=&#39;n&#39;&gt;SIGN_BIT&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;mi&#39;&gt;63&lt;/span&gt;              &lt;span class=&#39;c&#39;&gt;# bit index at which the sign is stored&lt;/span&gt;
    &lt;span class=&#39;n&#39;&gt;EXP_BIT&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;mi&#39;&gt;52&lt;/span&gt;               &lt;span class=&#39;c&#39;&gt;# bit index at which the exponent starts&lt;/span&gt;
    &lt;span class=&#39;n&#39;&gt;EXP_MASK&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;mh&#39;&gt;0x000fffffffffffff&lt;/span&gt;  &lt;span class=&#39;c&#39;&gt;# bit-mask to remove exponent, leaving mantissa&lt;/span&gt;
    &lt;span class=&#39;n&#39;&gt;NAN_EXP&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;mh&#39;&gt;0x7ff&lt;/span&gt;            &lt;span class=&#39;c&#39;&gt;# special exponent which encodes NaN/Infinity&lt;/span&gt;
    
    &lt;span class=&#39;k&#39;&gt;def&lt;/span&gt; &lt;span class=&#39;nf&#39;&gt;parse_hex&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;hexstring&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;n&#39;&gt;float_format&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;=&lt;/span&gt;&lt;span class=&#39;s&#39;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&#39;si&#39;&gt;%.15e&lt;/span&gt;&lt;span class=&#39;s&#39;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;n&#39;&gt;no_decimal&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;=&lt;/span&gt;&lt;span class=&#39;bp&#39;&gt;False&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;):&lt;/span&gt;
        &lt;span class=&#39;sd&#39;&gt;&amp;quot;&amp;quot;&amp;quot; Take a 8-byte hex string (16 digits) representing a double precision,&lt;/span&gt;
&lt;span class=&#39;sd&#39;&gt;            parse it, and print detailed information about the represented float&lt;/span&gt;
&lt;span class=&#39;sd&#39;&gt;            value.&lt;/span&gt;
&lt;span class=&#39;sd&#39;&gt;        &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
        &lt;span class=&#39;n&#39;&gt;bits&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;nb&#39;&gt;int&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;s&#39;&gt;&amp;#39;0x&lt;/span&gt;&lt;span class=&#39;si&#39;&gt;%s&lt;/span&gt;&lt;span class=&#39;s&#39;&gt;&amp;#39;&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;%&lt;/span&gt; &lt;span class=&#39;n&#39;&gt;hexstring&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;mi&#39;&gt;16&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt;
        &lt;span class=&#39;n&#39;&gt;sign&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;s&#39;&gt;&amp;#39;+1&amp;#39;&lt;/span&gt;
        &lt;span class=&#39;k&#39;&gt;if&lt;/span&gt; &lt;span class=&#39;n&#39;&gt;test_bit&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;bits&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;n&#39;&gt;SIGN_BIT&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#39;mi&#39;&gt;0&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;:&lt;/span&gt;
            &lt;span class=&#39;n&#39;&gt;sign&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;s&#39;&gt;&amp;#39;-1&amp;#39;&lt;/span&gt;
        &lt;span class=&#39;n&#39;&gt;bits&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;n&#39;&gt;clear_bit&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;bits&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;n&#39;&gt;SIGN_BIT&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt;
        &lt;span class=&#39;n&#39;&gt;stored_exp&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;n&#39;&gt;bits&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#39;n&#39;&gt;EXP_BIT&lt;/span&gt;
        &lt;span class=&#39;n&#39;&gt;mantissa&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;n&#39;&gt;bits&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&#39;n&#39;&gt;EXP_MASK&lt;/span&gt; &lt;span class=&#39;c&#39;&gt;# mask the exponent bits&lt;/span&gt;
    
        &lt;span class=&#39;k&#39;&gt;print&lt;/span&gt; &lt;span class=&#39;s&#39;&gt;&amp;quot;&amp;quot;&lt;/span&gt;
        &lt;span class=&#39;k&#39;&gt;print&lt;/span&gt; &lt;span class=&#39;s&#39;&gt;&amp;quot;Bytes         = 0x&lt;/span&gt;&lt;span class=&#39;si&#39;&gt;%s&lt;/span&gt;&lt;span class=&#39;s&#39;&gt;&amp;quot;&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;%&lt;/span&gt; &lt;span class=&#39;n&#39;&gt;hexstring&lt;/span&gt;
        &lt;span class=&#39;k&#39;&gt;print&lt;/span&gt; &lt;span class=&#39;s&#39;&gt;&amp;quot;Float         = &amp;quot;&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;+&lt;/span&gt; &lt;span class=&#39;n&#39;&gt;float_format&lt;/span&gt; \
                               &lt;span class=&#39;o&#39;&gt;%&lt;/span&gt; &lt;span class=&#39;n&#39;&gt;struct&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;unpack&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;s&#39;&gt;&amp;#39;!d&amp;#39;&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;n&#39;&gt;hexstring&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;.&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;decode&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;s&#39;&gt;&amp;#39;hex&amp;#39;&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;))[&lt;/span&gt;&lt;span class=&#39;mi&#39;&gt;0&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;]&lt;/span&gt;
        &lt;span class=&#39;k&#39;&gt;print&lt;/span&gt; &lt;span class=&#39;s&#39;&gt;&amp;quot;Sign          = &lt;/span&gt;&lt;span class=&#39;si&#39;&gt;%s&lt;/span&gt;&lt;span class=&#39;s&#39;&gt;&amp;quot;&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;%&lt;/span&gt; &lt;span class=&#39;n&#39;&gt;sign&lt;/span&gt;
        &lt;span class=&#39;k&#39;&gt;if&lt;/span&gt; &lt;span class=&#39;n&#39;&gt;stored_exp&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;==&lt;/span&gt; &lt;span class=&#39;mi&#39;&gt;0&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;:&lt;/span&gt;
            &lt;span class=&#39;k&#39;&gt;print&lt;/span&gt; &lt;span class=&#39;s&#39;&gt;&amp;quot;Exponent      = 0x&lt;/span&gt;&lt;span class=&#39;si&#39;&gt;%x&lt;/span&gt;&lt;span class=&#39;s&#39;&gt; (Special: Zero/Subnormal)&amp;quot;&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;%&lt;/span&gt; &lt;span class=&#39;n&#39;&gt;stored_exp&lt;/span&gt;
            &lt;span class=&#39;k&#39;&gt;print&lt;/span&gt; &lt;span class=&#39;s&#39;&gt;&amp;quot;Mantissa      = 0x&lt;/span&gt;&lt;span class=&#39;si&#39;&gt;%x&lt;/span&gt;&lt;span class=&#39;s&#39;&gt;&amp;quot;&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;%&lt;/span&gt; &lt;span class=&#39;n&#39;&gt;mantissa&lt;/span&gt;
            &lt;span class=&#39;k&#39;&gt;if&lt;/span&gt; &lt;span class=&#39;ow&#39;&gt;not&lt;/span&gt; &lt;span class=&#39;n&#39;&gt;no_decimal&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;:&lt;/span&gt;
                &lt;span class=&#39;k&#39;&gt;if&lt;/span&gt; &lt;span class=&#39;n&#39;&gt;mantissa&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;==&lt;/span&gt; &lt;span class=&#39;mi&#39;&gt;0&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;:&lt;/span&gt;
                    &lt;span class=&#39;k&#39;&gt;print&lt;/span&gt; &lt;span class=&#39;s&#39;&gt;&amp;quot;Exact Decimal = &lt;/span&gt;&lt;span class=&#39;si&#39;&gt;%s&lt;/span&gt;&lt;span class=&#39;s&#39;&gt;0&amp;quot;&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;%&lt;/span&gt; &lt;span class=&#39;n&#39;&gt;sign&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;[&lt;/span&gt;&lt;span class=&#39;mi&#39;&gt;0&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;]&lt;/span&gt;
                &lt;span class=&#39;k&#39;&gt;else&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;:&lt;/span&gt;
                    &lt;span class=&#39;k&#39;&gt;print&lt;/span&gt; &lt;span class=&#39;s&#39;&gt;&amp;quot;Exact Decimal = &lt;/span&gt;&lt;span class=&#39;si&#39;&gt;%s&lt;/span&gt;&lt;span class=&#39;s&#39;&gt; (subnormal)&amp;quot;&lt;/span&gt; \
                        &lt;span class=&#39;o&#39;&gt;%&lt;/span&gt; &lt;span class=&#39;n&#39;&gt;float2decimal&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;hex2float&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;hexstring&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;))&lt;/span&gt;
        &lt;span class=&#39;k&#39;&gt;elif&lt;/span&gt; &lt;span class=&#39;n&#39;&gt;stored_exp&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;==&lt;/span&gt; &lt;span class=&#39;n&#39;&gt;NAN_EXP&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;:&lt;/span&gt;
            &lt;span class=&#39;k&#39;&gt;print&lt;/span&gt; &lt;span class=&#39;s&#39;&gt;&amp;quot;Exponent      = 0x&lt;/span&gt;&lt;span class=&#39;si&#39;&gt;%x&lt;/span&gt;&lt;span class=&#39;s&#39;&gt; (Special: NaN/Infinity)&amp;quot;&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;%&lt;/span&gt; &lt;span class=&#39;n&#39;&gt;stored_exp&lt;/span&gt;
            &lt;span class=&#39;k&#39;&gt;print&lt;/span&gt; &lt;span class=&#39;s&#39;&gt;&amp;quot;Mantissa      = 0x&lt;/span&gt;&lt;span class=&#39;si&#39;&gt;%x&lt;/span&gt;&lt;span class=&#39;s&#39;&gt;&amp;quot;&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;%&lt;/span&gt; &lt;span class=&#39;n&#39;&gt;mantissa&lt;/span&gt;
            &lt;span class=&#39;k&#39;&gt;if&lt;/span&gt; &lt;span class=&#39;ow&#39;&gt;not&lt;/span&gt; &lt;span class=&#39;n&#39;&gt;no_decimal&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;:&lt;/span&gt;
                &lt;span class=&#39;k&#39;&gt;if&lt;/span&gt; &lt;span class=&#39;n&#39;&gt;mantissa&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;==&lt;/span&gt; &lt;span class=&#39;mi&#39;&gt;0&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;:&lt;/span&gt;
                    &lt;span class=&#39;k&#39;&gt;print&lt;/span&gt; &lt;span class=&#39;s&#39;&gt;&amp;quot;Exact Decimal = &lt;/span&gt;&lt;span class=&#39;si&#39;&gt;%s&lt;/span&gt;&lt;span class=&#39;s&#39;&gt;Infinity&amp;quot;&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;%&lt;/span&gt; &lt;span class=&#39;n&#39;&gt;sign&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;[&lt;/span&gt;&lt;span class=&#39;mi&#39;&gt;0&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;]&lt;/span&gt;
                &lt;span class=&#39;k&#39;&gt;else&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;:&lt;/span&gt;
                    &lt;span class=&#39;k&#39;&gt;print&lt;/span&gt; &lt;span class=&#39;s&#39;&gt;&amp;quot;Exact Decimal = NaN&amp;quot;&lt;/span&gt;
        &lt;span class=&#39;k&#39;&gt;else&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;:&lt;/span&gt;
            &lt;span class=&#39;k&#39;&gt;print&lt;/span&gt; &lt;span class=&#39;s&#39;&gt;&amp;quot;Exponent      = 0x&lt;/span&gt;&lt;span class=&#39;si&#39;&gt;%x&lt;/span&gt;&lt;span class=&#39;s&#39;&gt; = &lt;/span&gt;&lt;span class=&#39;si&#39;&gt;%i&lt;/span&gt;&lt;span class=&#39;s&#39;&gt; (bias &lt;/span&gt;&lt;span class=&#39;si&#39;&gt;%i&lt;/span&gt;&lt;span class=&#39;s&#39;&gt;)&amp;quot;&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;%&lt;/span&gt; &lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;stored_exp&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt;
                                                           &lt;span class=&#39;n&#39;&gt;stored_exp&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;n&#39;&gt;BIAS&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt;
            &lt;span class=&#39;k&#39;&gt;print&lt;/span&gt; &lt;span class=&#39;s&#39;&gt;&amp;quot;Mantissa      = 0x&lt;/span&gt;&lt;span class=&#39;si&#39;&gt;%x&lt;/span&gt;&lt;span class=&#39;s&#39;&gt;&amp;quot;&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;%&lt;/span&gt; &lt;span class=&#39;n&#39;&gt;mantissa&lt;/span&gt;
            &lt;span class=&#39;k&#39;&gt;if&lt;/span&gt; &lt;span class=&#39;ow&#39;&gt;not&lt;/span&gt; &lt;span class=&#39;n&#39;&gt;no_decimal&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;:&lt;/span&gt;
                &lt;span class=&#39;n&#39;&gt;mantissa&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;n&#39;&gt;set_bit&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;mantissa&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;n&#39;&gt;EXP_BIT&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;c&#39;&gt;# set the implicit bit&lt;/span&gt;
                &lt;span class=&#39;k&#39;&gt;print&lt;/span&gt; &lt;span class=&#39;s&#39;&gt;&amp;quot;Exact Decimal = &lt;/span&gt;&lt;span class=&#39;si&#39;&gt;%s&lt;/span&gt;&lt;span class=&#39;s&#39;&gt; 2^(&lt;/span&gt;&lt;span class=&#39;si&#39;&gt;%i&lt;/span&gt;&lt;span class=&#39;s&#39;&gt;) * [0x&lt;/span&gt;&lt;span class=&#39;si&#39;&gt;%x&lt;/span&gt;&lt;span class=&#39;s&#39;&gt; * 2^(-52)]&amp;quot;&lt;/span&gt; \
                                    &lt;span class=&#39;o&#39;&gt;%&lt;/span&gt; &lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;sign&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;[&lt;/span&gt;&lt;span class=&#39;mi&#39;&gt;0&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;],&lt;/span&gt; &lt;span class=&#39;n&#39;&gt;stored_exp&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;-&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;BIAS&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;n&#39;&gt;mantissa&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt;
                &lt;span class=&#39;k&#39;&gt;print&lt;/span&gt; &lt;span class=&#39;s&#39;&gt;&amp;quot;              = &lt;/span&gt;&lt;span class=&#39;si&#39;&gt;%s&lt;/span&gt;&lt;span class=&#39;s&#39;&gt;&amp;quot;&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;%&lt;/span&gt; &lt;span class=&#39;n&#39;&gt;float2decimal&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;hex2float&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;n&#39;&gt;hexstring&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;))&lt;/span&gt;
    
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The procedure is quite straightforward:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Extract the sign from the left-most bit, and set it to 0&lt;/li&gt;

&lt;li&gt;Extract the stored exponent by shifting out the mantissa; to get the actual exponent the bias exponent (1023) has to be subtracted&lt;/li&gt;

&lt;li&gt;Extract the mantissa by setting all bits of the exponential to 0 with a suitable bitmask&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Any float can be represented as an exact decimal, without loss of information. The calculating of the exact decimal is not completely trivial to implement. The basic idea is to double the mantissa until it is a (possibly very large) integer. A routine &lt;code&gt;float2decimal&lt;/code&gt; that does this is available in the &lt;a href=&#39;http://docs.python.org/release/2.5.2/lib/decimal-faq.html&#39;&gt;FAQ for the Decimal module&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&#39;connection_to_the_fortran_numerical_model&#39;&gt;Connection to the Fortran Numerical Model&lt;/h3&gt;

&lt;p&gt;In Fortran, the numerical model is described as follows (see the &lt;a href=&#39;http://portal.acm.org/citation.cfm?id=151166&#39;&gt;Fortran Handbook&lt;/a&gt; section 13.2.3):&lt;/p&gt;

&lt;p&gt;$$ x = s b^e \sum_{k=1}^p f_k b^{-k} $$&lt;/p&gt;

&lt;p&gt;Note that in good Fortran fashion, the index $k$ counts from 1 as opposed to 0. This means that the exponential $e$ is shifted by one compared to the more traditional formula used in the &amp;#8220;Floating Point Memory Format&amp;#8221; section above.&lt;/p&gt;

&lt;p&gt;The specific parameters for single and double precision for a given compiler/system can be found using the very useful &lt;a href=&#39;http://portal.acm.org/citation.cfm?id=151166&#39;&gt;kindfinder utility&lt;/a&gt;. On my system, I get the following:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt; FLOATINGPOINT MODEL (Real/Complex):
  Name:                     Single              Double              Extnd1
  KIND:                          4                   8                  16
  DIGITS:                       24                  53                 113
  RADIX:                         2                   2                   2
  MINEXPONENT:                -125               -1021              -16381
  MAXEXPONENT:                 128                1024               16384
  PRECISION:                     6                  15                  33
  RANGE:                        37                 307                4931
  EPSILON:               1.192E-07           2.220E-16           1.926E-34
  HUGE:                  3.403E+38           1.798+308          1.190+4932
  TINY:                  1.175E-38           2.225-308          3.362-4932&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Looking at double precision floats, the &lt;code&gt;DIGITS&lt;/code&gt; corresponds to the total number of mantissa digits, $p$ in the model. Note that &lt;code&gt;DIGITS&lt;/code&gt; is 53, whereas only 52 bits are used to store the mantissa in memory format: the 53rd bit for $2^0$ is implicit, as discussed earlier.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;TINY&lt;/code&gt; and &lt;code&gt;HUGE&lt;/code&gt; are the smallest and largest representable numbers, respectively. The &lt;code&gt;parse_dp_float.py&lt;/code&gt; script gives the following information:&lt;/p&gt;

&lt;p&gt;For &lt;code&gt;TINY&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Bytes         = 0x0010000000000000
Float         = 2.225073858507201e-308
Sign          = +1
Exponent      = 0x1 = 1 (bias 1023)
Mantissa      = 0x0
Exact Decimal = + 2^(-1022) * [0x10000000000000 * 2^(-52)]
              = 2.225073858507201383090232717332404064219215980462331830553327
416887204434813918195854283159012511020564067339731035811005152434161553460108
856012385377718821130777993532002330479610147442583636071921565046942503734208
375250806650616658158948720491179968591639648500635908770118304874799780887753
749949451580451605050915399856582470818645113537935804992115981085766051992433
352114352390148795699609591288891602992641511063466313393663477586513029371762
047325631781485664350872122828637642044846811407613911477062801689853244110024
161447421618567166150540154285084716752901903161322778896729707373123334086988
983175067838846926092773977972858659654941091369095406136467568702398678315290
680984617210924625396728515625E-308&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;For &lt;code&gt;HUGE&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Bytes         = 0x7fefffffffffffff
Float         = 1.797693134862316e+308
Sign          = +1
Exponent      = 0x7fe = 2046 (bias 1023)
Mantissa      = 0xfffffffffffff
Exact Decimal = + 2^(1023) * [0x1fffffffffffff * 2^(-52)]
              = 17976931348623157081452742373170435679807056752584499659891747
680315726078002853876058955863276687817154045895351438246423432132688946418276
846754670353751698604991057655128207624549009038932894407586850845513394230458
323690322294816580855933212334827479782620414472316873817718091929988125040402
6184124858368&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note the &lt;code&gt;MINEXPONENT = EXPONENT(TINY)&lt;/code&gt; and &lt;code&gt;MAXEXPONENT = EXPONENT(HUGE)&lt;/code&gt;, where &lt;code&gt;EXPONENT&lt;/code&gt; is the Fortran function that returns the exponent in the Fortran numerical model. These values are shifted by one compared to the stored exponent in the binary representation, due to the sum in the numerical model starting at one, as discussed above.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;PRECISION&lt;/code&gt; is the number of significant digits (the digits after the decimal point) that are guaranteed to be represented accurately; That is, when you assign a number to a double precision float, the number actually stored will always match the assigned number within at least 15 significant digits.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;RANGE&lt;/code&gt; is defined as &lt;code&gt;INT(MIN( LOG10(HUGE), -LOG10(TINY) ))&lt;/code&gt;, in this case &lt;code&gt;RANGE = INT(-LOG10(2.225e-308)) = INT(- (308 + 0.347)) = INT(307.653) = 307&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Finally, &lt;code&gt;EPSILON&lt;/code&gt; is the difference between one and the next closest representable number, given as $2^{-52}$. This is the smallest difference for any two neighboring numbers greater than one. &lt;code&gt;0.5*EPSILON&lt;/code&gt; provides an upper bound for the relative error due to rounding.&lt;/p&gt;

&lt;p&gt;Some final observations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Two distinct double precision numbers can look the same when printed to 15 significant digits. The best example for this is &lt;code&gt;one + EPSILON(one)&lt;/code&gt;. However, they will always differ in the 16th significant digit in that case.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;When printing a float to an arbitrary precision (greater the machine precision), there are never any random digits printed. The exact decimal encoded by the float determines the result. However, the digits beyond the machine precision resulting from a &lt;em&gt;computation&lt;/em&gt; involving two floats may depend and the compiler and the environment so that in general, results obtained on different systems cannot be expected to match beyond the machine precision.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;To test whether two floats &lt;code&gt;r1&lt;/code&gt; and &lt;code&gt;r2&lt;/code&gt; are the same within some relative error &lt;code&gt;delta_r&lt;/code&gt;, the following expression can be used:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt; approx_eq = (ABS(r1 - r2) &amp;lt;= 0.5d0*ABS(r1+r2) * delta_r)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It makes no sense to use a &lt;code&gt;delta_r &amp;lt; 1.0d-16&lt;/code&gt;; the test would be equivalent to a direct comparison on the bit-level.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;To write out the hex representation of a double precision float &lt;code&gt;r&lt;/code&gt; in Fortran, use &lt;code&gt;write(*,&amp;#39;(Z16)&amp;#39;) transfer(r, 1_8)&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Read &lt;a href=&#39;http://download.oracle.com/docs/cd/E19957-01/806-3568/ncg_goldberg.html&#39;&gt;What Every Computer Scientist Should Know about Floating Numbers&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;</content>
 </entry>
 
 <entry>
   <title>Advanced Array-Passing in Fortran</title>
   <link href="blog/2011/05/advanced-array-passing-in-fortran/"/>
   <updated>2011-05-19T00:00:00+02:00</updated>
   <id>blog/2011/05/advanced-array-passing-in-fortran</id>
   <content type="html">&lt;p&gt;There are instances where one wishes to change the rank (the number of dimensions) of an array as it is passed to a subroutine. Maybe you want to call a library routine that expects to get a vector, but you have the data to be passed stored in a matrix. There should be no problem in principle, as the data for an array &amp;#8211; no matter its rank &amp;#8211; is stored sequentially in memory (array element order of subscripts along the first dimension varying more quickly). Thus, it should be possible to simply re-interpret the data to a different shape. In practice, one can change the rank of the array by declaring the dummy array with an explicit shape specification. As soon as the dummy array has an explicit shape, one can pass anything that contains enough elements to fill the dummy array, no matter what the rank or shape. The feature is known as array element sequence association and is illustrated in the following example:&lt;/p&gt;
&lt;div class=&#39;highlight&#39;&gt;&lt;pre&gt;&lt;code class=&#39;fortran&#39;&gt;    &lt;span class=&#39;k&#39;&gt;program &lt;/span&gt;&lt;span class=&#39;nv&#39;&gt;test&lt;/span&gt;
      &lt;span class=&#39;k&#39;&gt;implicit none&lt;/span&gt;
&lt;span class=&#39;k&#39;&gt;      &lt;/span&gt;&lt;span class=&#39;kt&#39;&gt;integer&lt;/span&gt; &lt;span class=&#39;kd&#39;&gt;::&lt;/span&gt; &lt;span class=&#39;nv&#39;&gt;test_array1&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;mi&#39;&gt;10&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt;
      &lt;span class=&#39;kt&#39;&gt;integer&lt;/span&gt; &lt;span class=&#39;kd&#39;&gt;::&lt;/span&gt; &lt;span class=&#39;nv&#39;&gt;test_array2&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;mi&#39;&gt;10&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt;&lt;span class=&#39;mi&#39;&gt;2&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt;
      &lt;span class=&#39;nv&#39;&gt;test_array1&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;/&lt;/span&gt;&lt;span class=&#39;mi&#39;&gt;1&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;mi&#39;&gt;2&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;mi&#39;&gt;3&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;mi&#39;&gt;4&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;mi&#39;&gt;5&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;mi&#39;&gt;6&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;mi&#39;&gt;7&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;mi&#39;&gt;8&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;mi&#39;&gt;9&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;mi&#39;&gt;10&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;/&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt;
      &lt;span class=&#39;nv&#39;&gt;test_array2&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(:,&lt;/span&gt;&lt;span class=&#39;mi&#39;&gt;1&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;/&lt;/span&gt;&lt;span class=&#39;mi&#39;&gt;1&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt;   &lt;span class=&#39;mi&#39;&gt;2&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt;  &lt;span class=&#39;mi&#39;&gt;3&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt;  &lt;span class=&#39;mi&#39;&gt;4&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt;  &lt;span class=&#39;mi&#39;&gt;5&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt;  &lt;span class=&#39;mi&#39;&gt;6&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt;  &lt;span class=&#39;mi&#39;&gt;7&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt;  &lt;span class=&#39;mi&#39;&gt;8&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt;  &lt;span class=&#39;mi&#39;&gt;9&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;mi&#39;&gt;10&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;/&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt;
      &lt;span class=&#39;nv&#39;&gt;test_array2&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(:,&lt;/span&gt;&lt;span class=&#39;mi&#39;&gt;2&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;/&lt;/span&gt;&lt;span class=&#39;mi&#39;&gt;11&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;mi&#39;&gt;12&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;mi&#39;&gt;13&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;mi&#39;&gt;14&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;mi&#39;&gt;15&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;mi&#39;&gt;16&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;mi&#39;&gt;17&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;mi&#39;&gt;18&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;mi&#39;&gt;19&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;mi&#39;&gt;20&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;/&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt;
      &lt;span class=&#39;k&#39;&gt;write&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;*&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;*&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;s2&#39;&gt;&amp;quot;print_a(test_array1, 10)&amp;quot;&lt;/span&gt;
      &lt;span class=&#39;k&#39;&gt;call &lt;/span&gt;&lt;span class=&#39;nv&#39;&gt;print_a&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;nv&#39;&gt;test_array1&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;mi&#39;&gt;10&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt;
      &lt;span class=&#39;k&#39;&gt;write&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;*&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;*&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;s2&#39;&gt;&amp;quot;print_a(test_array2, 10)&amp;quot;&lt;/span&gt;
      &lt;span class=&#39;k&#39;&gt;call &lt;/span&gt;&lt;span class=&#39;nv&#39;&gt;print_a&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;nv&#39;&gt;test_array2&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;mi&#39;&gt;10&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt;
      &lt;span class=&#39;k&#39;&gt;write&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;*&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;*&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;s2&#39;&gt;&amp;quot;print_a(test_array2, 20)&amp;quot;&lt;/span&gt;
      &lt;span class=&#39;k&#39;&gt;call &lt;/span&gt;&lt;span class=&#39;nv&#39;&gt;print_a&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;nv&#39;&gt;test_array2&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;mi&#39;&gt;20&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt;
      &lt;span class=&#39;k&#39;&gt;write&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;*&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;*&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;s2&#39;&gt;&amp;quot;print_a(test_array2(:,2), 10)&amp;quot;&lt;/span&gt;
      &lt;span class=&#39;k&#39;&gt;call &lt;/span&gt;&lt;span class=&#39;nv&#39;&gt;print_a&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;nv&#39;&gt;test_array2&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(:,&lt;/span&gt;&lt;span class=&#39;mi&#39;&gt;2&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;),&lt;/span&gt; &lt;span class=&#39;mi&#39;&gt;10&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt;
      &lt;span class=&#39;k&#39;&gt;write&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;*&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;*&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;s2&#39;&gt;&amp;quot;print_m(test_array1, 2,5)&amp;quot;&lt;/span&gt;
      &lt;span class=&#39;k&#39;&gt;call &lt;/span&gt;&lt;span class=&#39;nv&#39;&gt;print_m&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;nv&#39;&gt;test_array1&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;mi&#39;&gt;2&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;mi&#39;&gt;5&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt;
    
    &lt;span class=&#39;k&#39;&gt;contains&lt;/span&gt;
&lt;span class=&#39;k&#39;&gt;    &lt;/span&gt;
&lt;span class=&#39;k&#39;&gt;      subroutine &lt;/span&gt;&lt;span class=&#39;nv&#39;&gt;print_a&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;nv&#39;&gt;a&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;nv&#39;&gt;n&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt;
        &lt;span class=&#39;kt&#39;&gt;integer&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;k&#39;&gt;intent&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;nv&#39;&gt;in&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;kd&#39;&gt;::&lt;/span&gt; &lt;span class=&#39;nv&#39;&gt;n&lt;/span&gt;
        &lt;span class=&#39;kt&#39;&gt;integer&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;k&#39;&gt;intent&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;nv&#39;&gt;in&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;kd&#39;&gt;::&lt;/span&gt; &lt;span class=&#39;nv&#39;&gt;a&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;nv&#39;&gt;n&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt;
        &lt;span class=&#39;kt&#39;&gt;integer&lt;/span&gt; &lt;span class=&#39;kd&#39;&gt;::&lt;/span&gt; &lt;span class=&#39;nv&#39;&gt;i&lt;/span&gt;
        &lt;span class=&#39;k&#39;&gt;do &lt;/span&gt;&lt;span class=&#39;nv&#39;&gt;i&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;mi&#39;&gt;1&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;nv&#39;&gt;n&lt;/span&gt;
          &lt;span class=&#39;k&#39;&gt;write&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;*&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;*&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;nv&#39;&gt;a&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;nv&#39;&gt;i&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt;
        &lt;span class=&#39;k&#39;&gt;end do&lt;/span&gt;
&lt;span class=&#39;k&#39;&gt;      end subroutine&lt;/span&gt;
&lt;span class=&#39;k&#39;&gt;    &lt;/span&gt;
&lt;span class=&#39;k&#39;&gt;      subroutine &lt;/span&gt;&lt;span class=&#39;nv&#39;&gt;print_m&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;nv&#39;&gt;a&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;nv&#39;&gt;n&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;nv&#39;&gt;m&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt;
        &lt;span class=&#39;kt&#39;&gt;integer&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;k&#39;&gt;intent&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;nv&#39;&gt;in&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;kd&#39;&gt;::&lt;/span&gt; &lt;span class=&#39;nv&#39;&gt;n&lt;/span&gt;
        &lt;span class=&#39;kt&#39;&gt;integer&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;k&#39;&gt;intent&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;nv&#39;&gt;in&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;kd&#39;&gt;::&lt;/span&gt; &lt;span class=&#39;nv&#39;&gt;m&lt;/span&gt;
        &lt;span class=&#39;kt&#39;&gt;integer&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;k&#39;&gt;intent&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;nv&#39;&gt;in&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;kd&#39;&gt;::&lt;/span&gt; &lt;span class=&#39;nv&#39;&gt;a&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;nv&#39;&gt;n&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt;&lt;span class=&#39;nv&#39;&gt;m&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt;
        &lt;span class=&#39;kt&#39;&gt;integer&lt;/span&gt; &lt;span class=&#39;kd&#39;&gt;::&lt;/span&gt; &lt;span class=&#39;nv&#39;&gt;i&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;nv&#39;&gt;j&lt;/span&gt;
        &lt;span class=&#39;k&#39;&gt;do &lt;/span&gt;&lt;span class=&#39;nv&#39;&gt;i&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;mi&#39;&gt;1&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;nv&#39;&gt;n&lt;/span&gt;
          &lt;span class=&#39;k&#39;&gt;do &lt;/span&gt;&lt;span class=&#39;nv&#39;&gt;j&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;mi&#39;&gt;1&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;nv&#39;&gt;m&lt;/span&gt;
            &lt;span class=&#39;k&#39;&gt;write&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;*&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;*&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;nv&#39;&gt;a&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;nv&#39;&gt;i&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt;&lt;span class=&#39;nv&#39;&gt;j&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt;
          &lt;span class=&#39;k&#39;&gt;end do&lt;/span&gt;
&lt;span class=&#39;k&#39;&gt;        end do&lt;/span&gt;
&lt;span class=&#39;k&#39;&gt;      end subroutine&lt;/span&gt;
&lt;span class=&#39;k&#39;&gt;    &lt;/span&gt;
&lt;span class=&#39;k&#39;&gt;    end program &lt;/span&gt;&lt;span class=&#39;nv&#39;&gt;test&lt;/span&gt;
    
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;There are two alternatives to do basically the same thing, one standard, one not. The first one is known as assumed-size, and looks like this:&lt;/p&gt;
&lt;div class=&#39;highlight&#39;&gt;&lt;pre&gt;&lt;code class=&#39;fortran&#39;&gt;      &lt;span class=&#39;k&#39;&gt;subroutine &lt;/span&gt;&lt;span class=&#39;nv&#39;&gt;print_a&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;nv&#39;&gt;a&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;nv&#39;&gt;n&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt;
        &lt;span class=&#39;kt&#39;&gt;integer&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;k&#39;&gt;intent&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;nv&#39;&gt;in&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;kd&#39;&gt;::&lt;/span&gt; &lt;span class=&#39;nv&#39;&gt;a&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;*&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt;
        &lt;span class=&#39;kt&#39;&gt;integer&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;k&#39;&gt;intent&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;nv&#39;&gt;in&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;kd&#39;&gt;::&lt;/span&gt; &lt;span class=&#39;nv&#39;&gt;n&lt;/span&gt;
        &lt;span class=&#39;kt&#39;&gt;integer&lt;/span&gt; &lt;span class=&#39;kd&#39;&gt;::&lt;/span&gt; &lt;span class=&#39;nv&#39;&gt;i&lt;/span&gt;
        &lt;span class=&#39;k&#39;&gt;do &lt;/span&gt;&lt;span class=&#39;nv&#39;&gt;i&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;mi&#39;&gt;1&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;nv&#39;&gt;n&lt;/span&gt;
          &lt;span class=&#39;k&#39;&gt;write&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;*&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;*&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;nv&#39;&gt;a&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;nv&#39;&gt;i&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt;
        &lt;span class=&#39;k&#39;&gt;end do&lt;/span&gt;
&lt;span class=&#39;k&#39;&gt;      end subroutine&lt;/span&gt;
    
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here, &lt;code&gt;a&lt;/code&gt; has rank one, and a size large enough to fit whatever is passed to the routine. However, the routine does not actually know the size of &lt;code&gt;a&lt;/code&gt; (&lt;code&gt;size(a)&lt;/code&gt; is illegal in this context). There certainly is nothing that ensures that the size of &lt;code&gt;a&lt;/code&gt; is n, and the compiler has no way of perfoming any checks on the use of &lt;code&gt;a&lt;/code&gt;. In that sense, assumed-size is not very useful compared to explicit-shape, except maybe in some rare instances where the array size can somehow be deduced from the data stored in the array, so that the array size &lt;code&gt;n&lt;/code&gt; does not have to be passed along.&lt;/p&gt;

&lt;p&gt;The second alternative is a non-standard trick that behaves identically to assumed-size, but was used before the assumed-size feature was introduced to Fortran. It looks like this:&lt;/p&gt;
&lt;div class=&#39;highlight&#39;&gt;&lt;pre&gt;&lt;code class=&#39;fortran&#39;&gt;      &lt;span class=&#39;k&#39;&gt;subroutine &lt;/span&gt;&lt;span class=&#39;nv&#39;&gt;print_a&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;nv&#39;&gt;a&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;nv&#39;&gt;n&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt;
        &lt;span class=&#39;kt&#39;&gt;integer&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;k&#39;&gt;intent&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;nv&#39;&gt;in&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;kd&#39;&gt;::&lt;/span&gt; &lt;span class=&#39;nv&#39;&gt;a&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;mi&#39;&gt;1&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt;
        &lt;span class=&#39;kt&#39;&gt;integer&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;k&#39;&gt;intent&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;nv&#39;&gt;in&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;kd&#39;&gt;::&lt;/span&gt; &lt;span class=&#39;nv&#39;&gt;n&lt;/span&gt;
        &lt;span class=&#39;kt&#39;&gt;integer&lt;/span&gt; &lt;span class=&#39;kd&#39;&gt;::&lt;/span&gt; &lt;span class=&#39;nv&#39;&gt;i&lt;/span&gt;
        &lt;span class=&#39;k&#39;&gt;do &lt;/span&gt;&lt;span class=&#39;nv&#39;&gt;i&lt;/span&gt; &lt;span class=&#39;o&#39;&gt;=&lt;/span&gt; &lt;span class=&#39;mi&#39;&gt;1&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt; &lt;span class=&#39;nv&#39;&gt;n&lt;/span&gt;
          &lt;span class=&#39;k&#39;&gt;write&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;*&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;,&lt;/span&gt;&lt;span class=&#39;o&#39;&gt;*&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt; &lt;span class=&#39;nv&#39;&gt;a&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;(&lt;/span&gt;&lt;span class=&#39;nv&#39;&gt;i&lt;/span&gt;&lt;span class=&#39;p&#39;&gt;)&lt;/span&gt;
        &lt;span class=&#39;k&#39;&gt;end do&lt;/span&gt;
&lt;span class=&#39;k&#39;&gt;      end subroutine&lt;/span&gt;
    
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In principle, this is also an example of array element sequence association. In the subroutine, &lt;code&gt;a&lt;/code&gt; is called with subscripts outside of the bounds of its declared size 1, which is more or less guaranteed to work since the array is passed by reference. Again, the compiler has not idea about the actual size of &lt;code&gt;a&lt;/code&gt;. Most compilers will recognize this trick and not complain about going out of bounds, even with bound-checking enabled, understanding &lt;code&gt;a(1)&lt;/code&gt; to be identical to &lt;code&gt;a(*)&lt;/code&gt;, with the only difference being that &lt;code&gt;size(a)&lt;/code&gt; is legal, but of course returns 1, i.e. not the size of the actual passed array. Declaring &lt;code&gt;a&lt;/code&gt; as &lt;code&gt;a(2)&lt;/code&gt; will not work, however.&lt;/p&gt;

&lt;p&gt;Any of these definitions should only be used if the rank of the array needs to be changed. For just passing arrays of identical rank, but unknown shape, one should always use the assumed-shape syntax (e.g. &lt;code&gt;a(:,:)&lt;/code&gt;)&lt;/p&gt;

&lt;p&gt;A few pointers about where to find the discussed concepts in the Fortran 90 Handbook: array element order is discussed in section 6.4.7, the definition of array element sequence association appears in section 12.5.2.1, and explicit-shape, assumed-shape, deferred-shape, and assumed-size specification are explained in section 5.3.1.&lt;/p&gt;

&lt;p&gt;Thanks to the people on &lt;code&gt;comp.lang.fortran&lt;/code&gt; for illuminating some of these concepts to me.&lt;/p&gt;</content>
 </entry>
 
 
</feed>