| <html> |
| |
| <head> |
| <meta http-equiv="Content-Language" content="en-us"> |
| <meta name="GENERATOR" content="Microsoft FrontPage 5.0"> |
| <meta name="ProgId" content="FrontPage.Editor.Document"> |
| <meta http-equiv="Content-Type" content="text/html; charset=windows-1252"> |
| <title>Floating Point Concerns</title> |
| <link href="styles.css" rel="stylesheet"> |
| </head> |
| |
| <body> |
| |
| <h1>Floating Point Concerns</h1> |
| |
| <p>Consider this simple implementation of <code>endian_reverse</code>:</p> |
| |
| <blockquote> |
| <pre>template <class T> |
| inline T endian_reverse(T x) BOOST_NOEXCEPT |
| { |
| std::reverse(reinterpret_cast<unsigned char*>(&x), |
| reinterpret_cast<unsigned char*>(&x) + sizeof(T)); |
| return x; |
| }</pre> |
| </blockquote> |
| <p><b>Under what conditions with this code fail?</b></p> |
| <p dir="ltr">It will fail if an object of type <code>T</code> has one or more |
| bit patterns that cause a failure. Failures usually occur when an invalid |
| or otherwise special bit pattern is loaded into or saved from a hardware |
| register.</p> |
| <p dir="ltr">The problem could in theory occur with both integers and floating |
| point numbers, but the <a href="http://en.wikipedia.org/wiki/Two's_complement"> |
| two's complement integers</a> ubiquitous in modern computer architectures do not |
| have any invalid or otherwise special bit patterns that cause failure when |
| byte-wise reversed.</p> |
| <p dir="ltr">But floating point numbers are a different story. Even if we limit |
| discussion to IEEE 754 (aka ISO/IEC/IEEE 60559) binary representations of 4 and |
| 8 byte sizes, several problems are easy to demonstrate:</p> |
| <ul> |
| <li dir="ltr"> |
| <p dir="ltr">...</li> |
| </ul> |
| <h2 dir="ltr">Safe interfaces and possible reference implementations</h2> |
| <h3 dir="ltr">In-place interface</h3> |
| <blockquote> |
| <pre dir="ltr">template <class T> |
| inline void endian_reverse_inplace(T& x) |
| { |
| std::reverse(reinterpret_cast<unsigned char*>(&x), |
| reinterpret_cast<unsigned char*>(&x) + sizeof(T)); |
| }</pre> |
| </blockquote> |
| <p dir="ltr">This is the same as the current (i.e integer) customization point |
| interface, so there is no need for any change.</p> |
| <p dir="ltr"><b>Warning:</b> Even thought <code>x</code> may have had a valid |
| value on the originating platform, after calling this function the value of |
| <code>x</code> may differ or be invalid on this platform.</p> |
| <h3 dir="ltr">Copy interface</h3> |
| <blockquote> |
| <pre dir="ltr">template <class T> |
| inline void endian_reverse_copy(const T& from, T& to) |
| { |
| std::reverse_copy(reinterpret_cast<const unsigned char*>(&from), |
| reinterpret_cast<const unsigned char*>(&from) + sizeof(T), |
| reinterpret_cast<unsigned char*>(&to)); |
| }</pre> |
| </blockquote> |
| <p><b>Warning:</b> Even thought <code>from</code> may have been a valid value on |
| the originating platform, after calling this function the value of <code>to</code> |
| may differ or be invalid on this platform.</p> |
| <h3>Return-by-value interface</h3> |
| <blockquote> |
| <pre>template <class T> |
| inline T endian_reverse_to_native(<span style="background-color: #FFFF00">const</span><span style="background-color: #FFFF00"> T&</span> x) BOOST_NOEXCEPT |
| { |
| T tmp; |
| std::reverse_copy(reinterpret_cast<const unsigned char*>(&x), |
| reinterpret_cast<const unsigned char*>(&x) + sizeof(T), |
| reinterpret_cast<unsigned char*>(&tmp)); |
| return tmp; |
| }</pre> |
| </blockquote> |
| <p><b>Warning:</b> Even thought <code>x</code> may have had a valid value on the |
| originating platform, the value of returned by this function may differ or be |
| invalid on this platform.</p> |
| <h2>Acknowledgements</h2> |
| <hr> |
| <p>Last revised: <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->27 March, 2015<!--webbot bot="Timestamp" endspan i-checksum="28924" --></p> |
| <p>© Copyright Beman Dawes, 2015</p> |
| <p>Distributed under the Boost Software License, Version 1.0. See <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/ LICENSE_1_0.txt</a></p> |
| |
| <p> </p> |
| |
| </body> |
| |
| </html> |