[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);
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [lmi-commits] [lmi] master ddb702e: Assert the two's complement assumption; improve documentation,
Greg Chicares <=