Skip to content

Commit

Permalink
code hygiene and creating a string_utils.hpp to collect string utilities
Browse files Browse the repository at this point in the history
  • Loading branch information
Ravenwater committed Aug 23, 2024
1 parent b7b1ab4 commit 679b788
Show file tree
Hide file tree
Showing 18 changed files with 131 additions and 64 deletions.
1 change: 1 addition & 0 deletions include/universal/SPDX
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
// SPDX-License-Identifier: MIT
3 changes: 2 additions & 1 deletion include/universal/common/enumerate_encodings.hpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
#pragma once
// enumerate_encodings.hpp: enumerate the ordered encodings of an arithmetic type
//
// Copyright (C) 2017-2023 Stillwater Supercomputing, Inc.
// Copyright (C) 2017 Stillwater Supercomputing, Inc.
// SPDX-License-Identifier: MIT
//
// This file is part of the universal numbers project, which is released under an MIT Open Source license.

Expand Down
9 changes: 9 additions & 0 deletions include/universal/common/number_traits_reports.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ template<typename Scalar, size_t ColumnWidth = 40>
void numberTraits(std::ostream& ostr) {
using namespace std;

auto defaultPrecision = ostr.precision();
ostr << std::scientific << std::setprecision(numeric_limits<Scalar>::max_digits10);
ostr << "std::numeric_limits< " << typeid(Scalar).name() << " >\n";
ostr << "min exponent " << setw(ColumnWidth) << numeric_limits<Scalar>::min_exponent << '\n';
ostr << "max exponent " << setw(ColumnWidth) << numeric_limits<Scalar>::max_exponent << '\n';
Expand All @@ -28,13 +30,16 @@ void numberTraits(std::ostream& ostr) {
ostr << "quiet_NAN " << setw(ColumnWidth) << numeric_limits<Scalar>::quiet_NaN() << '\n';
ostr << "signaling_NAN " << setw(ColumnWidth) << numeric_limits<Scalar>::signaling_NaN() << '\n';
ostr << '\n';
ostr << std::setprecision(defaultPrecision);
}

// compare numeric_limits of two Real types
template<typename Type1, typename Type2, size_t ColumnWidth = 30>
void compareNumberTraits(std::ostream& ostr) {
using namespace std;

auto defaultPrecision = ostr.precision();
ostr << std::scientific << std::setprecision(numeric_limits<Type1>::max_digits10);
ostr << "comparing numeric_limits between " << typeid(Type1).name() << " and " << typeid(Type2).name() << '\n';
ostr << " " << setw(ColumnWidth) << typeid(Type1).name() << " vs " << setw(ColumnWidth) << typeid(Type2).name() << '\n';
ostr << "min exponent " << setw(ColumnWidth) << numeric_limits< Type1 >::min_exponent << " vs " << setw(ColumnWidth) << numeric_limits< Type2 >::min_exponent << '\n';
Expand All @@ -51,13 +56,16 @@ void compareNumberTraits(std::ostream& ostr) {
ostr << "quiet_NAN " << setw(ColumnWidth) << numeric_limits< Type1 >::quiet_NaN() << " vs " << setw(ColumnWidth) << numeric_limits< Type2 >::quiet_NaN() << '\n';
ostr << "signaling_NAN " << setw(ColumnWidth) << numeric_limits< Type1 >::signaling_NaN() << " vs " << setw(ColumnWidth) << numeric_limits< Type2 >::signaling_NaN() << '\n';
ostr << '\n';
ostr << std::setprecision(defaultPrecision);
}

// compare numeric_limits of three Real types
template<typename Type1, typename Type2, typename Type3, size_t ColumnWidth = 30>
void threeWayCompareNumberTraits(std::ostream& ostr) {
using namespace std;

auto defaultPrecision = ostr.precision();
ostr << std::scientific << std::setprecision(numeric_limits<Type1>::max_digits10);
ostr << "comparing numeric_limits between " << typeid(Type1).name() << " and " << typeid(Type2).name() << " and " << typeid(Type3).name() << '\n';
ostr << " " << setw(ColumnWidth) << typeid(Type1).name() << " vs " << setw(ColumnWidth) << typeid(Type2).name() << " vs " << setw(ColumnWidth) << typeid(Type3).name() << '\n';
ostr << "min exponent " << setw(ColumnWidth) << numeric_limits< Type1 >::min_exponent << setw(ColumnWidth) << numeric_limits< Type2 >::min_exponent << setw(ColumnWidth) << numeric_limits< Type3 >::min_exponent << '\n';
Expand All @@ -74,6 +82,7 @@ void threeWayCompareNumberTraits(std::ostream& ostr) {
ostr << "quiet_NAN " << setw(ColumnWidth) << numeric_limits< Type1 >::quiet_NaN() << setw(ColumnWidth) << numeric_limits< Type2 >::quiet_NaN() << setw(ColumnWidth) << numeric_limits< Type3 >::quiet_NaN() << '\n';
ostr << "signaling_NAN " << setw(ColumnWidth) << numeric_limits< Type1 >::signaling_NaN() << setw(ColumnWidth) << numeric_limits< Type2 >::signaling_NaN() << setw(ColumnWidth) << numeric_limits< Type3 >::signaling_NaN() << '\n';
ostr << '\n';
ostr << std::setprecision(defaultPrecision);
}

}} // namespace sw::universal
22 changes: 22 additions & 0 deletions include/universal/common/string_utils.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#pragma once
// string_utils.hpp: utilities to work with std::string
//
// Copyright (C) 2017 Stillwater Supercomputing, Inc.
// SPDX-License-Identifier: MIT
//
// This file is part of the universal numbers project, which is released under an MIT Open Source license.
#include <string>

namespace sw { namespace universal {

std::string centered(const std::string& label, unsigned columnWidth) {
unsigned length = static_cast<unsigned>(label.length());
if (columnWidth < length) return label;

unsigned padding = columnWidth - length;
unsigned leftPadding = (padding >> 1);
unsigned rightPadding = padding - leftPadding;
return std::string(leftPadding, ' ') + label + std::string(rightPadding, ' ');
}

}} // namespace sw::universal
1 change: 1 addition & 0 deletions include/universal/copyright
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
// Copyright (C) 2017 Stillwater Supercomputing, Inc.
3 changes: 2 additions & 1 deletion include/universal/utility/boolean_logic_operators.hpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
#pragma once
// boolean_logic_operators.hpp : full set of boolean logic operators
//
// Copyright (C) 2017-2023 Stillwater Supercomputing, Inc.
// Copyright (C) 2017 Stillwater Supercomputing, Inc.
// SPDX-License-Identifier: MIT
//
// This file is part of the universal numbers project, which is released under an MIT Open Source license.

Expand Down
2 changes: 2 additions & 0 deletions include/universal/utility/cmdline.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#pragma once
// Copyright (C) 2017 Stillwater Supercomputing, Inc.
// SPDX-License-Identifier: MIT

#include <iostream>

Expand Down
3 changes: 2 additions & 1 deletion include/universal/utility/convert_to.hpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
#pragma once
// convert_to.hpp: more convenient conversion
//
// Copyright (C) 2017-2021 Stillwater Supercomputing, Inc.
// Copyright (C) 2017 Stillwater Supercomputing, Inc.
// SPDX-License-Identifier: MIT
//
// This file is part of the universal numbers project, which is released under an MIT Open Source license.

Expand Down
2 changes: 2 additions & 0 deletions include/universal/utility/directives.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#pragma once
// Copyright (C) 2017 Stillwater Supercomputing, Inc.
// SPDX-License-Identifier: MIT

// compiler directives
#if defined(_MSC_VER)
Expand Down
3 changes: 2 additions & 1 deletion include/universal/utility/error.hpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
#pragma once
// error.hpp: utility functions to calculate relative and absolute error
//
// Copyright (C) 2017-2021 Stillwater Supercomputing, Inc.
// Copyright (C) 2017 Stillwater Supercomputing, Inc.
// SPDX-License-Identifier: MIT
//
// This file is part of the universal numbers project, which is released under an MIT Open Source license.

Expand Down
5 changes: 3 additions & 2 deletions include/universal/utility/occurrence.hpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
#pragma once
// occurrence.hpp: utility object to track arithmetic operation counts during execution of a specific number system
//
// Copyright (C) 2017-2021 Stillwater Supercomputing, Inc.
// Copyright (C) 2017 Stillwater Supercomputing, Inc.
// SPDX-License-Identifier: MIT
//
// This file is part of the universal numbers project, which is released under an MIT Open Source license.

Expand Down Expand Up @@ -42,4 +43,4 @@ namespace sw { namespace universal {
}
};

}} // namespace sw::universal
}} // namespace sw::universal
3 changes: 2 additions & 1 deletion include/universal/utility/reverse_view.hpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
#pragma once
// reverse_view.hpp: wrapper function to reverse a container iteration for range based loops
//
// Copyright (C) 2017-2021 Stillwater Supercomputing, Inc.
// Copyright (C) 2017 Stillwater Supercomputing, Inc.
// SPDX-License-Identifier: MIT
//
// This file is part of the universal numbers project, which is released under an MIT Open Source license.

Expand Down
5 changes: 3 additions & 2 deletions include/universal/utility/sampleviz.hpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
#pragma once
// sampleviz.hpp: utility
//
// Copyright (C) 2017-2021 Stillwater Supercomputing, Inc.
// Copyright (C) 2017 Stillwater Supercomputing, Inc.
// SPDX-License-Identifier: MIT
//
// This file is part of the universal numbers project, which is released under an MIT Open Source license.
namespace sw {
Expand Down Expand Up @@ -49,4 +50,4 @@ namespace sw {
}
}

} } // namespace sw::universal
} } // namespace sw::universal
3 changes: 2 additions & 1 deletion include/universal/utility/scale_tracker.hpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
#pragma once
// occurrence.hpp: utility object to track arithmetic operation counts during execution of a specific number system
//
// Copyright (C) 2017-2021 Stillwater Supercomputing, Inc.
// Copyright (C) 2017 Stillwater Supercomputing, Inc.
// SPDX-License-Identifier: MIT
//
// This file is part of the universal numbers project, which is released under an MIT Open Source license.
#include <iostream>
Expand Down
3 changes: 2 additions & 1 deletion include/universal/utility/scientific.hpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
#pragma once
// scientific.hpp: transform a value into a scientific format string
//
// Copyright (C) 2017-2021 Stillwater Supercomputing, Inc.
// Copyright (C) 2017 Stillwater Supercomputing, Inc.
// SPDX-License-Identifier: MIT
//
// This file is part of the universal numbers project, which is released under an MIT Open Source license.
#include <string>
Expand Down
96 changes: 67 additions & 29 deletions static/dd/api/api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
#include <universal/number/dd/dd.hpp>
#include <universal/number/cfloat/cfloat.hpp>
#include <universal/verification/test_suite.hpp>
#include <universal/native/error_free_ops.hpp>
//#include <universal/native/error_free_ops.hpp> // integral part of double-double and quad-double but can be used standalone
#include <universal/common/string_utils.hpp>

namespace sw {
namespace universal {
Expand Down Expand Up @@ -114,9 +115,6 @@ namespace sw {
}
}




int main()
try {
using namespace sw::universal;
Expand Down Expand Up @@ -196,35 +194,77 @@ try {
// fraction bit behavior
std::cout << "+--------- fraction bit progressions ---------+\n";
{
float fulp = ulp(1.0f);
Progression(1.0f + fulp);
Progression(1.0 + ulp(2.0));
double v = ulp(1.0);
Progression( 1.0 - v/2.0 );
std::cout << to_pair(dd(1.0 - v / 2.0)) << '\n';
// what is the value that adds a delta one below the least significant fraction bit of the high double?
// dd = high + lo
// = 1*2^0 + 1*2^-53
// = 1.0e00 + 1.0elog10(2^-53)
double x0{ std::pow(2.0, 0.0) };
double x1{ std::pow(2.0, -53.0) };

// now let's walk that bit down to the ULP
int precisionForRange = 16;
std::cout << std::setprecision(precisionForRange);
x0 = 1.0;
dd a(x0, x1);
std::cout << centered("double-double", precisionForRange + 6) << " : ";
std::cout << centered("binary form of x0", 68) << " : ";
std::cout << centered("real value of x0", 15) << '\n';
std::cout << a << " : " << to_binary(x0) << " : " << x0 << '\n';
for (int i = 1; i < 53; ++i) {
x0 = 1.0 + (std::pow(2.0, -double(i)));
a.set(x0, x1);
std::cout << a << " : " << to_binary(x0) << " : " << std::setprecision(7) << x0 << std::setprecision(precisionForRange) << '\n';
}
// x0 is 1.0 + eps() at this point
std::cout << to_binary(dd(x0, x1)) << '\n';
x0 = 1.0;
precisionForRange = 32;
std::cout << std::setprecision(precisionForRange);
std::cout << centered("double-double", precisionForRange + 6) << " : ";
std::cout << centered("binary form of x1", 68) << " : ";
std::cout << centered("real value of x1", 15) << '\n';
for (int i = 0; i < 54; ++i) {
x1 = (std::pow(2.0, -53.0 - double(i)));
a.set(x0, x1);
std::cout << a << " : " << to_binary(x1) << " : " << std::setprecision(7) << x1 << std::setprecision(precisionForRange) << '\n';
}
std::cout << std::setprecision(defaultPrecision);
}

// report on the dynamic range of some standard configurations
std::cout << "+--------- Dynamic range double-double configurations ---------+\n";

std::cout << "+--------- set specific values of interest --------+\n";
{
dd a; // uninitialized

std::cout << std::setprecision(32);
a.maxpos();
std::cout << "maxpos double-double : " << to_binary(a) << " : " << a << '\n';
std::cout << "maxpos double-double : " << to_binary(a) << " : " << a << " : " << scale(a) << '\n';
a.setbits(0x0080); // positive min normal
std::cout << "minnorm double-double : " << to_binary(a) << " : " << a << '\n';
std::cout << "minnorm double-double : " << to_binary(a) << " : " << a << " : " << scale(a) << '\n';
a.minpos();
std::cout << "minpos double-double : " << to_binary(a) << " : " << a << '\n';
std::cout << "minpos double-double : " << to_binary(a) << " : " << a << " : " << scale(a) << '\n';
a.zero();
std::cout << "zero : " << to_binary(a) << " : " << a << '\n';
std::cout << "zero : " << to_binary(a) << " : " << a << " : " << scale(a) << '\n';
a.minneg();
std::cout << "minneg double-double : " << to_binary(a) << " : " << a << '\n';
std::cout << "minneg double-double : " << to_binary(a) << " : " << a << " : " << scale(a) << '\n';
a.maxneg();
std::cout << "maxneg double-double : " << to_binary(a) << " : " << a << '\n';

std::cout << "maxneg double-double : " << to_binary(a) << " : " << a << " : " << scale(a) << '\n';
std::cout << std::setprecision(defaultPrecision);
std::cout << "---\n";
}

std::cout << "+--------- Dynamic range double-double configuration ---------+\n";
{
std::cout << dynamic_range<float>() << '\n';
std::cout << dynamic_range<double>() << '\n';
std::cout << dynamic_range<dd>() << '\n';

std::cout << '\n';
std::cout << symmetry_range<float>() << '\n';
std::cout << symmetry_range<double>() << '\n';
std::cout << symmetry_range<dd>() << '\n';
}

// constexpr and specific values
std::cout << "+--------- constexpr and specific values ---------+\n";
{
Expand Down Expand Up @@ -313,16 +353,7 @@ try {
std::cout << std::setprecision(defaultPrecision);
}

std::cout << "+--------- set specific values of interest --------+\n";
{
dd a{ 0 }; // initialized
std::cout << "maxpos : " << a.maxpos() << " : " << scale(a) << '\n';
std::cout << "minpos : " << a.minpos() << " : " << scale(a) << '\n';
std::cout << "zero : " << a.zero() << " : " << scale(a) << '\n';
std::cout << "minneg : " << a.minneg() << " : " << scale(a) << '\n';
std::cout << "maxneg : " << a.maxneg() << " : " << scale(a) << '\n';
std::cout << dynamic_range<dd>() << std::endl;
}


std::cout << "+--------- double-double subnormal behavior --------+\n";
{
Expand Down Expand Up @@ -364,6 +395,13 @@ try {
std::cout << "---------- Unit in the Last Place --------+\n";
{
ulp_progression("\nULP progression for dd:\n", dd(10.0));

for (int i = -5; i < 6; ++i) {
dd a(std::pow(2.0, double(i)));
dd ulpAtI = ulp(a);
std::string label = "ulpAt<dd>(2^" + std::to_string(i) + ")";
ReportValue(ulpAtI, label, 20, 32);
}
}

std::cout << "+--------- numeric_limits of double-double vs IEEE-754 --------+\n";
Expand Down
18 changes: 5 additions & 13 deletions static/dd/api/experiments.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
#include <universal/number/dd/dd.hpp>
#include <universal/number/cfloat/cfloat.hpp>
#include <universal/verification/test_suite.hpp>
#include <universal/native/error_free_ops.hpp>
//#include <universal/native/error_free_ops.hpp> // integral part of double-double and quad-double but can be used standalone
#include <universal/common/string_utils.hpp>

namespace sw {
namespace universal {
Expand Down Expand Up @@ -115,15 +116,6 @@ namespace sw {
}
}

std::string centered(const std::string& label, unsigned columnWidth) {
unsigned length = static_cast<unsigned>(label.length());
if (columnWidth < length) return label;

unsigned padding = columnWidth - length;
unsigned leftPadding = (padding >> 1);
unsigned rightPadding = padding - leftPadding;
return std::string(leftPadding, ' ') + label + std::string(rightPadding, ' ');
}
}
}

Expand Down Expand Up @@ -182,10 +174,11 @@ try {
double nlo;
if (lo == 0.0) {
nlo = std::numeric_limits<double>::epsilon() / 2.0;
nlo /= double(1ull << 53);
int binaryExponent = scale(hi) - 53;
nlo /= std::pow(2.0, -binaryExponent);
}
else {
nlo = std::nextafter(lo, INFINITY);
nlo = (hi < 0.0 ? std::nextafter(lo, -INFINITY) : std::nextafter(lo, +INFINITY));
}
dd n(hi, nlo);
ReportValue(a, "a = 1.0");
Expand Down Expand Up @@ -227,7 +220,6 @@ try {
}
}

return 0;
std::cout << "+---------- unevaluated pairs ------------ +\n";
{
// what is the value that adds a delta one below the least significant fraction bit of the high double?
Expand Down
Loading

0 comments on commit 679b788

Please sign in to comment.