Skip to content

Commit 2ddd4b3

Browse files
committed
WIP: still trying to deduce the ulp algorithm for double-double
1 parent 76f759c commit 2ddd4b3

File tree

2 files changed

+75
-21
lines changed

2 files changed

+75
-21
lines changed

include/universal/number/dd/dd_impl.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ class dd {
298298
constexpr void setinf(bool sign = true) noexcept { hi = (sign ? -INFINITY : INFINITY); lo = 0.0; }
299299
constexpr void setnan(int NaNType = NAN_TYPE_SIGNALLING) noexcept { hi = (NaNType == NAN_TYPE_SIGNALLING ? std::numeric_limits<double>::signaling_NaN() : std::numeric_limits<double>::quiet_NaN()); lo = 0.0; }
300300
constexpr void setsign(bool sign = true) noexcept { if (sign && hi > 0.0) hi = -hi; }
301-
301+
constexpr void set(double high, double low) noexcept { hi = high; lo = low; }
302302
constexpr void setbit(unsigned index, bool b = true) noexcept {
303303
if (index < 64) { // set bit in lower limb
304304
sw::universal::setbit(lo, index, b);

static/dd/api/experiments.cpp

+74-20
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,16 @@ namespace sw {
114114
}
115115
}
116116
}
117+
118+
std::string centered(const std::string& label, unsigned columnWidth) {
119+
unsigned length = static_cast<unsigned>(label.length());
120+
if (columnWidth < length) return label;
121+
122+
unsigned padding = columnWidth - length;
123+
unsigned leftPadding = (padding >> 1);
124+
unsigned rightPadding = padding - leftPadding;
125+
return std::string(leftPadding, ' ') + label + std::string(rightPadding, ' ');
126+
}
117127
}
118128
}
119129

@@ -135,50 +145,96 @@ try {
135145
{
136146
double zero{ 0.0 };
137147
double next = std::nextafter(zero, +INFINITY);
138-
ReportValue(next, "nextafter 0.0");
148+
ReportValue(next, "nextafter 0.0", 40);
139149
double one{ 1.0 };
140150
next = std::nextafter(one, +INFINITY);
141-
ReportValue(next, "nextafter 1.0");
142-
151+
ReportValue(next, "nextafter 1.0", 40);
152+
std::cout << '\n';
143153

144154
// ULP at 1.0 is 2^-106
145155
double ulpAtOne = std::pow(2.0, -106);
146156

147157
dd a{ 1.0 };
148158
a += ulpAtOne;
149-
ReportValue(a, "1.0 + eps");
159+
ReportValue(a, "reference of 1.0 + ulp(1.0)", 40);
150160

151161
a = 1.0;
152162
dd ddUlpAtOne = ulp(a);
153-
ReportValue(ddUlpAtOne, "ulp(1.0)");
163+
ReportValue(ddUlpAtOne, "ulp(1.0)", 40);
154164
a += ulp(a);
155-
ReportValue(a, "1.0 + ulp(1.0)");
165+
ReportValue(a, "ulp function of 1.0 + ulp(1.0)", 40);
166+
167+
double d_ulpAtOne = ulp(1.0);
168+
ReportValue(d_ulpAtOne, "ulp<double>(1.0)", 40);
169+
double d_epsilon = std::numeric_limits<double>::epsilon();
170+
ReportValue(d_epsilon, "epsilon<double>", 40);
171+
ReportValue(1.0 + d_epsilon, "1.0 + eps", 40);
172+
dd dd_epsilon = std::numeric_limits<dd>::epsilon();
173+
ReportValue(dd_epsilon, "epsilon<double-double>", 40);
174+
a = 1.0;
175+
a += dd_epsilon;
176+
ReportValue(a, "1.0 + eps", 40);
156177

157-
dd eps = std::numeric_limits<dd>::epsilon();
158-
ReportValue(eps, "epsilon");
159178

179+
double hi{ 1.0 };
180+
double lo{ 0.0 };
181+
a.set(hi, lo);
182+
double nlo;
183+
if (lo == 0.0) {
184+
nlo = std::numeric_limits<double>::epsilon() / 2.0;
185+
nlo /= double(1ull << 53);
186+
}
187+
else {
188+
nlo = std::nextafter(lo, INFINITY);
189+
}
190+
dd n(hi, nlo);
191+
ReportValue(a, "a = 1.0");
192+
ReportValue(nlo, "new low");
193+
ReportValue(n, "n");
194+
ReportValue(n - a, "n - a");
160195
}
161196

197+
return 0;
162198
std::cout << "+---------- unevaluated pairs ------------ +\n";
163199
{
164200
// what is the value that adds a delta one below the least significant fraction bit of the high double?
165201
// dd = high + lo
166202
// = 1*2^0 + 1*2^-53
167203
// = 1.0e00 + 1.0elog10(2^-53)
168-
double high{ std::pow(2.0, 0.0) };
169-
ReportValue(high, "2^0");
170-
double low{ std::pow(2.0, -53.0) };
171-
ReportValue(low, "2^-53");
172-
std::cout << std::log10(low) << '\n';
173-
double exponent = -std::ceil(std::abs(std::log10(low)));
204+
double x0{ std::pow(2.0, 0.0) };
205+
ReportValue(x0, "2^0");
206+
double x1{ std::pow(2.0, -53.0) };
207+
ReportValue(x1, "2^-53");
208+
std::cout << std::log10(x1) << '\n';
209+
double exponent = -std::ceil(std::abs(std::log10(x1)));
174210
std::cout << "exponent : " << exponent << '\n';
175211

176212
// now let's walk that bit down to the ULP
177-
std::cout << std::setprecision(32);
213+
int precisionForRange = 16;
214+
std::cout << std::setprecision(precisionForRange);
215+
x0 = 1.0;
216+
dd a(x0, x1);
217+
std::cout << centered("double-double", precisionForRange + 6) << " : ";
218+
std::cout << centered("binary form of x0", 68) << " : ";
219+
std::cout << centered("real value of x0", 15) << '\n';
220+
std::cout << a << " : " << to_binary(x0) << " : " << x0 << '\n';
221+
for (int i = 1; i < 53; ++i) {
222+
x0 = 1.0 + (std::pow(2.0, -double(i)));
223+
a.set(x0, x1);
224+
std::cout << a << " : " << to_binary(x0) << " : " << std::setprecision(7) << x0 << std::setprecision(precisionForRange) << '\n';
225+
}
226+
// x0 is 1.0 + eps() at this point
227+
std::cout << to_binary(dd(x0, x1)) << '\n';
228+
x0 = 1.0;
229+
precisionForRange = 32;
230+
std::cout << std::setprecision(precisionForRange);
231+
std::cout << centered("double-double", precisionForRange + 6) << " : ";
232+
std::cout << centered("binary form of x1", 68) << " : ";
233+
std::cout << centered("real value of x1", 15) << '\n';
178234
for (int i = 0; i < 54; ++i) {
179-
low = (std::pow(2.0, -53.0 - double(i)));
180-
dd a(high, low);
181-
std::cout << a << '\n';
235+
x1 = (std::pow(2.0, -53.0 - double(i)));
236+
a.set(x0, x1);
237+
std::cout << a << " : " << to_binary(x1) << " : " << std::setprecision(7) << x1 << std::setprecision(precisionForRange) << '\n';
182238
}
183239
std::cout << std::setprecision(defaultPrecision);
184240
}
@@ -193,8 +249,6 @@ try {
193249
}
194250
}
195251

196-
197-
198252
std::cout << "+---------- subnormal exponent adjustment ---------+\n";
199253
{
200254
constexpr double smallestNormal = std::numeric_limits<double>::min();

0 commit comments

Comments
 (0)