@@ -114,6 +114,16 @@ namespace sw {
114
114
}
115
115
}
116
116
}
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
+ }
117
127
}
118
128
}
119
129
@@ -135,50 +145,96 @@ try {
135
145
{
136
146
double zero{ 0.0 };
137
147
double next = std::nextafter (zero, +INFINITY);
138
- ReportValue (next, " nextafter 0.0" );
148
+ ReportValue (next, " nextafter 0.0" , 40 );
139
149
double one{ 1.0 };
140
150
next = std::nextafter (one, +INFINITY);
141
- ReportValue (next, " nextafter 1.0" );
142
-
151
+ ReportValue (next, " nextafter 1.0" , 40 );
152
+ std::cout << ' \n ' ;
143
153
144
154
// ULP at 1.0 is 2^-106
145
155
double ulpAtOne = std::pow (2.0 , -106 );
146
156
147
157
dd a{ 1.0 };
148
158
a += ulpAtOne;
149
- ReportValue (a, " 1.0 + eps " );
159
+ ReportValue (a, " reference of 1.0 + ulp(1.0) " , 40 );
150
160
151
161
a = 1.0 ;
152
162
dd ddUlpAtOne = ulp (a);
153
- ReportValue (ddUlpAtOne, " ulp(1.0)" );
163
+ ReportValue (ddUlpAtOne, " ulp(1.0)" , 40 );
154
164
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 );
156
177
157
- dd eps = std::numeric_limits<dd>::epsilon ();
158
- ReportValue (eps, " epsilon" );
159
178
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" );
160
195
}
161
196
197
+ return 0 ;
162
198
std::cout << " +---------- unevaluated pairs ------------ +\n " ;
163
199
{
164
200
// what is the value that adds a delta one below the least significant fraction bit of the high double?
165
201
// dd = high + lo
166
202
// = 1*2^0 + 1*2^-53
167
203
// = 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 )));
174
210
std::cout << " exponent : " << exponent << ' \n ' ;
175
211
176
212
// 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 ' ;
178
234
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 ' ;
182
238
}
183
239
std::cout << std::setprecision (defaultPrecision);
184
240
}
@@ -193,8 +249,6 @@ try {
193
249
}
194
250
}
195
251
196
-
197
-
198
252
std::cout << " +---------- subnormal exponent adjustment ---------+\n " ;
199
253
{
200
254
constexpr double smallestNormal = std::numeric_limits<double >::min ();
0 commit comments