Skip to content

Commit e68802f

Browse files
committed
adding an double-double ulp test case
1 parent c49c548 commit e68802f

File tree

3 files changed

+87
-41
lines changed

3 files changed

+87
-41
lines changed

include/universal/number/dd/dd_impl.hpp

+11-3
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,9 @@ namespace sw { namespace universal {
4141
}
4242

4343
// fwd references to free functions
44-
dd operator-(const dd& lhs, const dd&);
45-
dd operator*(const dd& lhs, const dd&);
44+
dd operator-(const dd&, const dd&);
45+
dd operator*(const dd&, const dd&);
46+
dd operator/(const dd&, const dd&);
4647
std::ostream& operator<<(std::ostream&, const dd&);
4748
dd pown(const dd&, int);
4849
dd frexp(const dd&, int*);
@@ -891,7 +892,14 @@ inline std::string to_binary(const dd& number, bool bNibbleMarker = false) {
891892

892893
inline dd ulp(const dd& a) {
893894
double hi{ a.high() };
894-
double nlo = std::nextafter(a.low(), INFINITY);
895+
double lo{ a.low() };
896+
double nlo;
897+
if (lo == 0.0) {
898+
nlo = std::numeric_limits<double>::epsilon() / 2.0;
899+
}
900+
else {
901+
nlo = std::nextafter(lo, INFINITY);
902+
}
895903
dd n(hi, nlo);
896904

897905
return n - a;

include/universal/verification/test_case.hpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -133,10 +133,10 @@ namespace sw { namespace universal {
133133

134134
template<typename TestType>
135135
void ReportValue(const TestType& a, const std::string& label = "", unsigned labelWidth = 20, unsigned precision = 7) {
136-
auto oldPrec = std::cout.precision();
136+
auto defaultPrecision = std::cout.precision();
137137
std::cout << std::setprecision(precision);
138138
std::cout << std::setw(labelWidth) << label << " : " << to_binary(a, true) << " : " << a << '\n';
139-
std::cout << std::setprecision(oldPrec);
139+
std::cout << std::setprecision(defaultPrecision);
140140
}
141141

142142
template<typename TestType>

static/dd/api/experiments.cpp

+74-36
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,48 @@ namespace sw {
4141
std::cout << to_pair(v) << '\n';
4242
}
4343

44+
// specialize ReportValue for double-double (dd)
45+
void ReportValue(const dd& a, const std::string& label = "", unsigned labelWidth = 20, unsigned precision = 32) {
46+
auto defaultPrecision = std::cout.precision();
47+
std::cout << std::setprecision(precision);
48+
std::cout << std::setw(labelWidth) << label << " : " << a << '\n';
49+
std::cout << std::setprecision(defaultPrecision);
50+
}
51+
52+
53+
void SettingBits() {
54+
std::cout << "+---------- Setting float bits ---------+\n";
55+
{
56+
float v{ 0.0f };
57+
setbit(v, 31);
58+
ReportValue(v);
59+
setbit(v, 23); // set min normal
60+
ReportValue(v);
61+
setbit(v, 23, false); setbit(v, 0); // set smallest denorm
62+
ReportValue(v);
63+
}
64+
std::cout << "+---------- Setting double bits ---------+\n";
65+
{
66+
double v{ 0.0 };
67+
setbit(v, 63);
68+
ReportValue(v);
69+
setbit(v, 52); // set min normal
70+
ReportValue(v);
71+
setbit(v, 52, false); setbit(v, 0); // set smallest denorm
72+
ReportValue(v);
73+
}
74+
std::cout << "+---------- Setting double-double bits ---------+\n";
75+
{
76+
dd v{ 0.0 };
77+
v.setbit(127);
78+
ReportValue(v);
79+
v.setbit(116); // set min normal
80+
ReportValue(v);
81+
v.setbit(116, false); v.setbit(64); // set smallest denorm
82+
ReportValue(v);
83+
}
84+
}
85+
4486
void adjust(dd const& a) {
4587
dd r = abs(a);
4688
dd ten(10.0);
@@ -89,7 +131,35 @@ try {
89131

90132
auto defaultPrecision = std::cout.precision();
91133

92-
std::cout << "+ ---------- - unevaluated pairs------------ +\n";
134+
std::cout << "+---------- ULP assessments ---------+\n";
135+
{
136+
double zero{ 0.0 };
137+
double next = std::nextafter(zero, +INFINITY);
138+
ReportValue(next, "nextafter 0.0");
139+
double one{ 1.0 };
140+
next = std::nextafter(one, +INFINITY);
141+
ReportValue(next, "nextafter 1.0");
142+
143+
144+
// ULP at 1.0 is 2^-106
145+
double ulpAtOne = std::pow(2.0, -106);
146+
147+
dd a{ 1.0 };
148+
a += ulpAtOne;
149+
ReportValue(a, "1.0 + eps");
150+
151+
a = 1.0;
152+
dd ddUlpAtOne = ulp(a);
153+
ReportValue(ddUlpAtOne, "ulp(1.0)");
154+
a += ulp(a);
155+
ReportValue(a, "1.0 + ulp(1.0)");
156+
157+
dd eps = std::numeric_limits<dd>::epsilon();
158+
ReportValue(eps, "epsilon");
159+
160+
}
161+
162+
std::cout << "+---------- unevaluated pairs ------------ +\n";
93163
{
94164
// what is the value that adds a delta one below the least significant fraction bit of the high double?
95165
// dd = high + lo
@@ -113,51 +183,19 @@ try {
113183
std::cout << std::setprecision(defaultPrecision);
114184
}
115185

116-
return 0;
117-
118-
std::cout << "Smallest normal number progressions\n";
186+
std::cout << "+---------- Smallest normal number progressions ---------+\n";
119187
{
120188
constexpr double smallestNormal = std::numeric_limits<double>::min();
121189
dd a(smallestNormal);
122190
for (int i = 0; i < 10; ++i) {
123191
ReportValue(a);
124192
a *= 2.0;
125193
}
126-
127194
}
128195

129-
std::cout << "Setting float bits\n";
130-
{
131-
float v{0.0f};
132-
setbit(v,31);
133-
ReportValue(v);
134-
setbit(v,23); // set min normal
135-
ReportValue(v);
136-
setbit(v,23,false); setbit(v,0); // set smallest denorm
137-
ReportValue(v);
138-
}
139-
std::cout << "Setting double bits\n";
140-
{
141-
double v{0.0};
142-
setbit(v,63);
143-
ReportValue(v);
144-
setbit(v,52); // set min normal
145-
ReportValue(v);
146-
setbit(v,52,false); setbit(v,0); // set smallest denorm
147-
ReportValue(v);
148-
}
149-
std::cout << "Setting double-double bits\n";
150-
{
151-
dd v{0.0};
152-
v.setbit(127);
153-
ReportValue(v);
154-
v.setbit(116); // set min normal
155-
ReportValue(v);
156-
v.setbit(116,false); v.setbit(64); // set smallest denorm
157-
ReportValue(v);
158-
}
159196

160-
std::cout << "subnormal exponent adjustment\n";
197+
198+
std::cout << "+---------- subnormal exponent adjustment ---------+\n";
161199
{
162200
constexpr double smallestNormal = std::numeric_limits<double>::min();
163201
dd a{ smallestNormal };

0 commit comments

Comments
 (0)