[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[lmi-commits] [lmi] master 8922e7a1 06/11: Explain restrictions on bin_e
From: |
Greg Chicares |
Subject: |
[lmi-commits] [lmi] master 8922e7a1 06/11: Explain restrictions on bin_exp() argument types |
Date: |
Tue, 31 May 2022 17:52:05 -0400 (EDT) |
branch: master
commit 8922e7a182196404424faa2b4860798141c95e57
Author: Gregory W. Chicares <gchicares@sbcglobal.net>
Commit: Gregory W. Chicares <gchicares@sbcglobal.net>
Explain restrictions on bin_exp() argument types
The deleted unit tests demonstrated some pitfalls avoided by bin_exp(),
but served no other purpose.
---
bin_exp.hpp | 6 ++++++
bin_exp_test.cpp | 45 ++-------------------------------------------
2 files changed, 8 insertions(+), 43 deletions(-)
diff --git a/bin_exp.hpp b/bin_exp.hpp
index 4027e5a1..ba337a61 100644
--- a/bin_exp.hpp
+++ b/bin_exp.hpp
@@ -28,6 +28,12 @@
/// Binary method for exponentiation.
///
+/// Allow only floating-point types for the base argument, because
+/// integer types can overflow. Allow only 'int' for the exponent
+/// argument, because it can't be narrower than 32 bits in any
+/// environment where lmi builds, and exponents over 2^32 aren't
+/// needed in practice.
+///
/// See Knuth, TAOCP volume 2, section 4.6.3, which notes (p. 443
/// in 2nd ed.):
/// "The number of multiplications required by Algorithm A
diff --git a/bin_exp_test.cpp b/bin_exp_test.cpp
index 9b7582e0..9c90e259 100644
--- a/bin_exp_test.cpp
+++ b/bin_exp_test.cpp
@@ -24,7 +24,6 @@
#include "bin_exp.hpp"
#include "materially_equal.hpp"
-#include "stl_extensions.hpp" // nonstd::power()
#include "test_tools.hpp"
#include "timer.hpp"
@@ -264,7 +263,7 @@ void test_quodlibet()
// Wolfram: 1748.219590818327062731185606025974266231060028076171875
LMI_TEST_EQUAL(1748.2195908183271, bin_exp(12.04662322998046875, 3));
- // Compare bin_exp() to std::pow() and nonstd::power().
+ // Compare bin_exp() to std::pow().
double a0 = bin_exp
(static_cast<double>(std::numeric_limits<double>::radix)
, std::numeric_limits<double>::digits
@@ -273,38 +272,8 @@ void test_quodlibet()
(static_cast<double>(std::numeric_limits<double>::radix)
,static_cast<double>(std::numeric_limits<double>::digits)
);
- double a2 = nonstd::power
- (static_cast<double>(std::numeric_limits<double>::radix)
- , std::numeric_limits<double>::digits
- );
-#if 0
- // This compiles, but its behavior is undefined unless an int
- // is at least 54 bits (53, + 1 for sign). Otherwise it cannot
- // return the hoped-for answer, and may return zero.
- auto a3 = nonstd::power
- ( std::numeric_limits<double>::radix
- , std::numeric_limits<double>::digits
- );
- stifle_unused_warning(a3);
- // This compiles, but its behavior is undefined unless a long int
- // is at least 54 bits (53, + 1 for sign). Otherwise it cannot
- // return the hoped-for answer, and may return zero.
- auto a4 = nonstd::power
- (static_cast<long int>(std::numeric_limits<double>::radix)
- ,static_cast<long int>(std::numeric_limits<double>::digits)
- );
- stifle_unused_warning(a4);
-#endif // 0
- // Type long long int is required to be at least 64 bits wide,
- // so this cannot overflow.
- auto a5 = nonstd::power
- (static_cast<long long int>(std::numeric_limits<double>::radix)
- ,static_cast<long long int>(std::numeric_limits<double>::digits)
- );
LMI_TEST_EQUAL(9007199254740992, a0);
LMI_TEST_EQUAL(9007199254740992, a1);
- LMI_TEST_EQUAL(9007199254740992, a2);
- LMI_TEST_EQUAL(9007199254740992, a5);
}
void mete0()
@@ -317,15 +286,6 @@ void mete0()
}
void mete1()
-{
- double volatile x;
- for(int j = 0; j < 100000; ++j)
- for(int k = 0; k < 32; ++k)
- {x = nonstd::power(2.0, 1 + k);}
- stifle_unused_warning(x);
-}
-
-void mete2()
{
double volatile x;
for(int j = 0; j < 100000; ++j)
@@ -338,8 +298,7 @@ void assay_speed()
{
std::cout << "Speed tests ['power' limits the domain]:\n";
std::cout << " bin_exp " << TimeAnAliquot(mete0) << '\n';
- std::cout << " power " << TimeAnAliquot(mete1) << '\n';
- std::cout << " pow " << TimeAnAliquot(mete2) << '\n';
+ std::cout << " pow " << TimeAnAliquot(mete1) << '\n';
std::cout << std::flush;
}
- [lmi-commits] [lmi] master updated (44ea8a5b -> fd325f5e), Greg Chicares, 2022/05/31
- [lmi-commits] [lmi] master d36e5145 03/11: Suppress undefined behavior; add a test with defined behavior, Greg Chicares, 2022/05/31
- [lmi-commits] [lmi] master 28055a62 02/11: Realize the actual intention of a comparison, Greg Chicares, 2022/05/31
- [lmi-commits] [lmi] master a3278e2b 10/11: Expunge 'stl_extensions.hpp', Greg Chicares, 2022/05/31
- [lmi-commits] [lmi] master c6dc35ea 05/11: Demonstrate equivalence of bin_exp() to SGI's power(), Greg Chicares, 2022/05/31
- [lmi-commits] [lmi] master 8922e7a1 06/11: Explain restrictions on bin_exp() argument types,
Greg Chicares <=
- [lmi-commits] [lmi] master 8cbc3001 07/11: Make a value definitely exact and definitely constexpr, Greg Chicares, 2022/05/31
- [lmi-commits] [lmi] master 2c8cc917 04/11: Don't bother calculating 2^64 - 1, Greg Chicares, 2022/05/31
- [lmi-commits] [lmi] master 7727d36d 08/11: Prefer bin_exp() to SGI's power(), Greg Chicares, 2022/05/31
- [lmi-commits] [lmi] master d9655b77 01/11: Refactor: rename local variables, Greg Chicares, 2022/05/31
- [lmi-commits] [lmi] master 2576d70c 09/11: Prefer bin_exp() to SGI's power(), Greg Chicares, 2022/05/31
- [lmi-commits] [lmi] master fd325f5e 11/11: Record speed measurements, Greg Chicares, 2022/05/31