lmi-commits
[Top][All Lists]
Advanced

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

[lmi-commits] [lmi] master ce9ed5c 07/13: Add an inchoate test of power-


From: Greg Chicares
Subject: [lmi-commits] [lmi] master ce9ed5c 07/13: Add an inchoate test of power-of-ten scaling
Date: Fri, 9 Apr 2021 18:42:37 -0400 (EDT)

branch: master
commit ce9ed5cbc6fff3916926870624c2d93eb2321d71
Author: Gregory W. Chicares <gchicares@sbcglobal.net>
Commit: Gregory W. Chicares <gchicares@sbcglobal.net>

    Add an inchoate test of power-of-ten scaling
    
    Compare numerical results of
      scaled = (1e8 * unscaled) / 1e8
      scaled = (1e8 * unscaled) * (1 / 1e8)
    using e as the value of 'unscaled', caching the reciprocal both
    as double and as long double.
    
    The result is a lossless round trip for i686, and for x86_64 with a
    long double reciprocal but not with a double reciprocal. Changing the
    'unscaled' value can produce different outcomes; e.g., with 1.0, 4/3,
    and 10/9, all results were lossless round trips.
---
 round_to_test.cpp | 34 ++++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/round_to_test.cpp b/round_to_test.cpp
index 54c5db8..41d0b1c 100644
--- a/round_to_test.cpp
+++ b/round_to_test.cpp
@@ -118,6 +118,7 @@ class round_to_test
     static void test();
 
   private:
+    static void test_scaling();
     static void test_fundamentals();
     static void test_all_modes(bool synchronize);
     static void test_rounding();
@@ -543,6 +544,38 @@ void round_to_test::test_all_modes(bool synchronize)
     test_rounding();
 }
 
+void round_to_test::test_scaling()
+{
+    double const volatile d0 = 2.71828'18284'59045'23536;
+    double const lo = nextafter(d0, -INFINITY);
+    double const hi = nextafter(d0,  INFINITY);
+
+    double const volatile d1 = (d0 * 1.0e8) / 1.0e8;
+    double const volatile dreciprocal = 1.0 / 1.0e8;
+    double const volatile d2 = (d0 * 1.0e8) * dreciprocal;
+
+    double const volatile d3 = static_cast<double>((d0 * 1.0e8L) / 1.0e8L);
+    long double const volatile lreciprocal = 1.0L / 1.0e8L;
+    double const volatile d4 = static_cast<double>((d0 * 1.0e8L) * 
lreciprocal);
+
+    std::streamsize old_precision = std::cout.precision(DECIMAL_DIG);
+    std::ios_base::fmtflags old_flags = std::cout.flags();
+
+    std::cout
+        << lo << std::hexfloat << '\t' << lo << std::defaultfloat << " lo\n"
+        << d0 << std::hexfloat << '\t' << d0 << std::defaultfloat << " d0\n"
+        << hi << std::hexfloat << '\t' << hi << std::defaultfloat << " hi\n"
+        << d1 << std::hexfloat << '\t' << d1 << std::defaultfloat << " d1\n"
+        << d2 << std::hexfloat << '\t' << d2 << std::defaultfloat << " d2\n"
+        << d3 << std::hexfloat << '\t' << d3 << std::defaultfloat << " d3\n"
+        << d4 << std::hexfloat << '\t' << d4 << std::defaultfloat << " d4\n"
+        ;
+
+    std::cout.setf(old_flags);
+    std::cout.precision(old_precision);
+    std::cout << std::endl;
+}
+
 void round_to_test::test_fundamentals()
 {
     default_rounding_style() = r_indeterminate;
@@ -600,6 +633,7 @@ void round_to_test::test_fundamentals()
 
 void round_to_test::test()
 {
+    test_scaling();
     test_fundamentals();
 
     // The software default rounding style and the hardware rounding



reply via email to

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