@@ -207,6 +207,8 @@ extern (C++) struct CTFloat
207
207
// implemented in gen/ctfloat.cpp
208
208
@system
209
209
static real_t parse (const (char )* literal, bool * isOutOfRange = null );
210
+ @system
211
+ static int sprint (char * str, char fmt, real_t x);
210
212
}
211
213
else
212
214
{
@@ -230,7 +232,6 @@ extern (C++) struct CTFloat
230
232
* isOutOfRange = (errno == ERANGE );
231
233
return r;
232
234
}
233
- }
234
235
235
236
@system
236
237
static int sprint (char * str, char fmt, real_t x)
@@ -258,6 +259,7 @@ extern (C++) struct CTFloat
258
259
}
259
260
}
260
261
}
262
+ }
261
263
262
264
// Constant real values 0, 1, -1 and 0.5.
263
265
__gshared real_t zero;
@@ -288,3 +290,106 @@ extern (C++) struct CTFloat
288
290
}
289
291
}
290
292
}
293
+
294
+ version (IN_LLVM)
295
+ {
296
+ version (Android ) { /* double/quadruple real_t */ } else
297
+ {
298
+ version (X86 ) version = real_t_X87;
299
+ version (X86_64 ) version = real_t_X87;
300
+ }
301
+
302
+ // Test parsing and printing of real_t values.
303
+ unittest
304
+ {
305
+ CTFloat.initialize();
306
+
307
+ static void printAndCheck (char format, real_t x, string expected) nothrow
308
+ {
309
+ char [32 ] buffer = void ;
310
+ const length = CTFloat.sprint(buffer.ptr, format, x);
311
+ assert (length < buffer.length);
312
+ printf(" '%s', expected '%.*s'\n " , buffer.ptr, cast (int ) expected.length, expected.ptr);
313
+ assert (buffer[0 .. length] == expected);
314
+ assert (buffer[length] == 0 );
315
+ }
316
+
317
+ static struct T
318
+ {
319
+ nothrow :
320
+
321
+ real_t x;
322
+ string expected_g, expected_a, expected_A;
323
+
324
+ this (real_t x, string g, string a, string A)
325
+ {
326
+ this .x = x;
327
+ expected_g = g;
328
+ expected_a = a;
329
+ expected_A = A;
330
+ }
331
+
332
+ this (string x, string g, string a, string A)
333
+ {
334
+ this .x = CTFloat.parse(x.ptr);
335
+ expected_g = g;
336
+ expected_a = a;
337
+ expected_A = A;
338
+ }
339
+
340
+ void test () const
341
+ {
342
+ printAndCheck(' g' , x, expected_g);
343
+ printAndCheck(' a' , x, expected_a);
344
+ printAndCheck(' A' , x, expected_A);
345
+ }
346
+ }
347
+
348
+ immutable T[] generic_ts = [
349
+ T( CTFloat.nan, " nan" , " nan" , " NAN" ),
350
+ T(- CTFloat.nan, " -nan" , " -nan" , " -NAN" ),
351
+ T( CTFloat.infinity, " inf" , " inf" , " INF" ),
352
+ T(- CTFloat.infinity, " -inf" , " -inf" , " -INF" ),
353
+ T( " 0.0" , " 0.0" , " 0x0p+0" , " 0X0P+0" ),
354
+ T(" -0.0" , " -0.0" , " -0x0p+0" , " -0X0P+0" ),
355
+ T( " 0x1p-1" , " 0.5" , " 0x1p-1" , " 0X1P-1" ),
356
+ T( " 0x3p-3" , " 0.375" , " 0x1.8p-2" , " 0X1.8P-2" ),
357
+ T( " 0x1p+0" , " 1.0" , " 0x1p+0" , " 0X1P+0" ),
358
+ T( " 0x3p-1" , " 1.5" , " 0x1.8p+0" , " 0X1.8P+0" ),
359
+ T(" -0x3p-2" , " -0.75" , " -0x1.8p-1" , " -0X1.8P-1" ),
360
+ T( " 100.0" , " 100.0" , " 0x1.9p+6" , " 0X1.9P+6" ),
361
+ ];
362
+
363
+ foreach (t; generic_ts)
364
+ {
365
+ version (AArch64 )
366
+ {
367
+ // FPU may not preserve NaN sign (depending on 'default NaN mode' control bit)
368
+ if (t.expected_g == " -nan" )
369
+ continue ;
370
+ }
371
+ t.test();
372
+ }
373
+
374
+ version (real_t_X87)
375
+ {
376
+ immutable T[] x87_ts = [
377
+ T( " 1e+300" , " 1e+300" , " 0x1.7e43c8800759ba5ap+996" , " 0X1.7E43C8800759BA5AP+996" ),
378
+ T( " 1e-300" , " 9.99999e-301" , " 0x1.56e1fc2f8f358d94p-997" , " 0X1.56E1FC2F8F358D94P-997" ),
379
+ T( " 1.2345678901234567890123456789" , " 1.23457" , " 0x1.3c0ca428c59fb71ap+0" , " 0X1.3C0CA428C59FB71AP+0" ),
380
+ T(" -12.345678901234567890123456789" , " -12.3457" , " -0x1.8b0fcd32f707a4e2p+3" , " -0X1.8B0FCD32F707A4E2P+3" ),
381
+ T( " 123456.78901234567890123456789" , " 123457.0" , " 0x1.e240c9fcb68cd4c4p+16" , " 0X1.E240C9FCB68CD4C4P+16" ),
382
+ T(" -123456.78901234567890123456789" , " -123457.0" , " -0x1.e240c9fcb68cd4c4p+16" , " -0X1.E240C9FCB68CD4C4P+16" ),
383
+ T( " 1234567.8901234567890123456789" , " 1.23457e+06" , " 0x1.2d687e3df21804fap+20" , " 0X1.2D687E3DF21804FAP+20" ),
384
+ T(" -1234567.8901234567890123456789" , " -1.23457e+06" , " -0x1.2d687e3df21804fap+20" , " -0X1.2D687E3DF21804FAP+20" ),
385
+ T( " 0.0001234567890123456789012345" , " 0.000123457" , " 0x1.02e85be180b7447cp-13" , " 0X1.02E85BE180B7447CP-13" ),
386
+ T(" -0.0001234567890123456789012345" , " -0.000123457" , " -0x1.02e85be180b7447cp-13" , " -0X1.02E85BE180B7447CP-13" ),
387
+ T( " 0.0000123456789012345678901234" , " 1.23457e-05" , " 0x1.9e409302678ba0c8p-17" , " 0X1.9E409302678BA0C8P-17" ),
388
+ T(" -0.0000123456789012345678901234" , " -1.23457e-05" , " -0x1.9e409302678ba0c8p-17" , " -0X1.9E409302678BA0C8P-17" ),
389
+ ];
390
+
391
+ foreach (t; x87_ts)
392
+ t.test();
393
+ }
394
+ }
395
+ }
0 commit comments