lmi-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[lmi-commits] [lmi] master ddb702e: Assert the two's complement assumpti


From: Greg Chicares
Subject: [lmi-commits] [lmi] master ddb702e: Assert the two's complement assumption; improve documentation
Date: Thu, 13 Apr 2017 15:27:11 -0400 (EDT)

branch: master
commit ddb702e85474cdb7e7d5af9afccf5adb2b9e2c04
Author: Gregory W. Chicares <address@hidden>
Commit: Gregory W. Chicares <address@hidden>

    Assert the two's complement assumption; improve documentation
    
    Floating-to-integral code depends on a two's complement representation
    for its adjustment of integral limits. Other integer representations
    are already handled correctly on all other paths: integral limits are
    not considered when converting to floating types, and the integral-to-
    integral code requires no adjustment of limits.
    
    An alarming lapsus calami:
      ///   argument <= maximum + 1  // i.e., <= 2^n exactly
    has been corrected:
      ///   maximum + 1 <= argument  // 'maximum + 1' == 2^digits exactly
---
 bourn_cast.hpp | 23 +++++++++++++++--------
 1 file changed, 15 insertions(+), 8 deletions(-)

diff --git a/bourn_cast.hpp b/bourn_cast.hpp
index 95db530..b19baf1 100644
--- a/bourn_cast.hpp
+++ b/bourn_cast.hpp
@@ -110,11 +110,6 @@ inline To bourn_cast(From from, std::false_type, 
std::true_type)
 
 /// Floating to integral.
 ///
-/// Assume integral types have a two's complement representation.
-/// Ones' complement might be handled thus [untested]:
-///  - if(from < to_traits::lowest())
-///  + if(from <= From(to_traits::lowest()) - 1)
-///
 /// Integral max() must be one less than an integer power of two,
 /// because C++11 [3.9.1/7] says "the representations of integral
 /// types shall define values by use of a pure binary numeration
@@ -127,10 +122,10 @@ inline To bourn_cast(From from, std::false_type, 
std::true_type)
 /// to this maximum in order to determine whether it is within range:
 /// see test_m64_neighborhood() in the accompanying unit test for a
 /// demonstration of the issues that arise in converting ULLONG_MAX to
-/// IEEE 754 binary32. Therefore, the tractable comparison
-///   argument <= maximum + 1  // i.e., <= 2^n exactly
+/// IEEE 754 binary32. Therefore, the tractable throw-condition
+///   maximum + 1 <= argument  // 'maximum + 1' == 2^digits exactly
 /// is substituted for the intractable
-///   argument < maximum       // < 0xFF... may exceed float precision
+///   maximum < argument       // 0xFF... may exceed float precision
 /// To ensure that the addition 'maximum + 1' is not done in extended
 /// precision (as actually observed with various versions of gcc), it
 /// is performed through writes to volatile memory. To ensure that
@@ -141,6 +136,15 @@ inline To bourn_cast(From from, std::false_type, 
std::true_type)
 /// static assertion rather than a throw-statement because 128-bit
 /// long long integers are not generally available, so it is not
 /// possible to test such logic today.
+///
+/// Precondition: integral type has a two's complement representation.
+/// For ones' complement and sign-and-magnitude representations, the
+/// minimum might be handled in much the same way as the maximum,
+/// throwing if
+///  (argument < 0 && !to_traits::is_signed) ||
+///   argument <= minimum - 1  // 'minimum - 1' == 2^digits exactly
+/// instead of the intractable condition
+///   argument < minimum       // limit may exceed float precision
 
 template<typename To, typename From>
 #if 201402L < __cplusplus
@@ -153,6 +157,9 @@ inline To bourn_cast(From from, std::true_type, 
std::false_type)
     static_assert(to_traits::is_integer && !from_traits::is_integer, "");
     static_assert(to_traits::digits < from_traits::max_exponent, "");
 
+    // Integral type must be two's complement.
+    static_assert(~To(0) == -To(1), "");
+
     static From const volatile raw_max = From(to_traits::max());
     static From const volatile adj_max = raw_max + From(1);
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]