Commit 491611cb632d41dfefbdafc60a058eee51457e0e

Test for limits qNaN and sNaN. Fix some consts.

In general, problem not resolved, due to impossible
to return sNaN via float point register on Intel-like
processor.

 #include <float.h>
 #include <stdio.h>

 #include <ieee754.h>

long double ldb()
{ return LDBL_MIN; }

/*
 * Fpr 96-bit float (extended precision) on Intel
 * this test print something like
 * 00000000000000800100d1bf
 * (two low bytes uninitialized).
 * To see this, return from function required.
 * Direct assignment give good
 * 000000000000008001000000
 */

double fdbl()
{
  union ieee754_double v1;

  v1.ieee.negative = 0;
  v1.ieee.exponent = 0x7ff;
  v1.ieee.mantissa0 = 0x40000; /* sNaN here */
  v1.ieee.mantissa1 = 0x0;

  return v1.d;
}

/*
 * I found that I can't return sNaN from function on Intel (gcc)
 * If I form sNaN, and return appropriate value
 * I will take qNaN:
 * 000000000000fc7f
 * instead of
 * 000000000000f47f
 */

int main()
{
  int i;
  long double m = /* LDBL_MIN */ ldb();
  long double m1 = LDBL_MIN;
  double d = fdbl();
  union ieee754_double v1;

  v1.ieee.negative = 0;
  v1.ieee.exponent = 0x7ff;
  v1.ieee.mantissa0 = 0x40000;
  v1.ieee.mantissa1 = 0x0;

  for ( i = 0; i < sizeof(long double); ++i ) {
    printf( "%.2x", (unsigned)(*((unsigned char*)&m + i)) );
  }
  printf( "\n" );

  for ( i = 0; i < sizeof(long double); ++i ) {
    printf( "%.2x", (unsigned)(*((unsigned char*)&m1 + i)) );
  }
  printf( "\n" );

  for ( i = 0; i < sizeof(double); ++i ) {
    printf( "%.2x", (unsigned)(*((unsigned char*)&d + i)) );
  }
  printf( "\n" );

  for ( i = 0; i < sizeof(double); ++i ) {
    printf( "%.2x", (unsigned)(*((unsigned char*)&v1.d + i)) );
  }
  printf( "\n" );

  return 0;
}
  
371371 static F qnan() _STLP_NOTHROW
372372 {
373373# if defined (_STLP_BIG_ENDIAN)
374 _access tmp = { _STLP_ADDITIONAL_OPEN_BRACKET 0x7f, 0 _STLP_ADDITIONAL_CLOSE_BRACKET };
374 _access tmp = { _STLP_ADDITIONAL_OPEN_BRACKET 0x7e, 0 _STLP_ADDITIONAL_CLOSE_BRACKET };
375375# else /* _STLP_LITTLE_ENDIAN */
376 _access tmp = { _STLP_ADDITIONAL_OPEN_BRACKET 0, 0x7f _STLP_ADDITIONAL_CLOSE_BRACKET };
376 _access tmp = { _STLP_ADDITIONAL_OPEN_BRACKET 0, 0x7e _STLP_ADDITIONAL_CLOSE_BRACKET };
377377# endif
378378 return tmp.f;
379379 }
421421 static F qnan() _STLP_NOTHROW
422422 {
423423# if defined (_STLP_BIG_ENDIAN)
424 _access tmp = { _STLP_ADDITIONAL_OPEN_BRACKET 0x7f, 0xe0, 0, 0 _STLP_ADDITIONAL_CLOSE_BRACKET };
424 _access tmp = { _STLP_ADDITIONAL_OPEN_BRACKET 0x7f, 0xc0, 0, 0 _STLP_ADDITIONAL_CLOSE_BRACKET };
425425# else /* _STLP_LITTLE_ENDIAN */
426 _access tmp = { _STLP_ADDITIONAL_OPEN_BRACKET 0, 0, 0xe0, 0x7f _STLP_ADDITIONAL_CLOSE_BRACKET };
426 _access tmp = { _STLP_ADDITIONAL_OPEN_BRACKET 0, 0, 0xc0, 0x7f _STLP_ADDITIONAL_CLOSE_BRACKET };
427427# endif
428428 return tmp.f;
429429 }
471471 static F qnan() _STLP_NOTHROW
472472 {
473473# if defined (_STLP_BIG_ENDIAN)
474 _access tmp = { _STLP_ADDITIONAL_OPEN_BRACKET 0x7f, 0xfc, 0, 0, 0, 0, 0, 0 _STLP_ADDITIONAL_CLOSE_BRACKET };
474 _access tmp = { _STLP_ADDITIONAL_OPEN_BRACKET 0x7f, 0xf8, 0, 0, 0, 0, 0, 0 _STLP_ADDITIONAL_CLOSE_BRACKET };
475475# else /* _STLP_LITTLE_ENDIAN */
476 _access tmp = { _STLP_ADDITIONAL_OPEN_BRACKET 0, 0, 0, 0, 0, 0, 0xfc, 0x7f _STLP_ADDITIONAL_CLOSE_BRACKET };
476 _access tmp = { _STLP_ADDITIONAL_OPEN_BRACKET 0, 0, 0, 0, 0, 0, 0xf8, 0x7f _STLP_ADDITIONAL_CLOSE_BRACKET };
477477# endif
478478 return tmp.f;
479479 }
481481 static F snan() _STLP_NOTHROW
482482 {
483483# if defined (_STLP_BIG_ENDIAN)
484 _access tmp = { _STLP_ADDITIONAL_OPEN_BRACKET 0x7f, 0xf6, 0, 0, 0, 0, 0, 0 _STLP_ADDITIONAL_CLOSE_BRACKET };
484 _access tmp = { _STLP_ADDITIONAL_OPEN_BRACKET 0x7f, 0xf4, 0, 0, 0, 0, 0, 0 _STLP_ADDITIONAL_CLOSE_BRACKET };
485485# else /* _STLP_LITTLE_ENDIAN */
486 _access tmp = { _STLP_ADDITIONAL_OPEN_BRACKET 0, 0, 0, 0, 0, 0, 0xf6, 0x7f _STLP_ADDITIONAL_CLOSE_BRACKET };
486 _access tmp = { _STLP_ADDITIONAL_OPEN_BRACKET 0, 0, 0, 0, 0, 0, 0xf4, 0x7f _STLP_ADDITIONAL_CLOSE_BRACKET };
487487# endif
488488 return tmp.f;
489489 }
529529 static F qnan() _STLP_NOTHROW
530530 {
531531# if defined (_STLP_BIG_ENDIAN)
532 _access tmp = { _STLP_ADDITIONAL_OPEN_BRACKET 0x7f, 0xff, 0xc0, 0, 0, 0, 0, 0, 0, 0 _STLP_ADDITIONAL_CLOSE_BRACKET };
532 _access tmp = { _STLP_ADDITIONAL_OPEN_BRACKET 0x7f, 0xff, 0x80, 0, 0, 0, 0, 0, 0, 0 _STLP_ADDITIONAL_CLOSE_BRACKET };
533533# else /* _STLP_LITTLE_ENDIAN */
534 _access tmp = { _STLP_ADDITIONAL_OPEN_BRACKET 0, 0, 0, 0, 0, 0, 0, 0xc0, 0xff, 0x7f _STLP_ADDITIONAL_CLOSE_BRACKET };
534 _access tmp = { _STLP_ADDITIONAL_OPEN_BRACKET 0, 0, 0, 0, 0, 0, 0, 0x80, 0xff, 0x7f _STLP_ADDITIONAL_CLOSE_BRACKET };
535535# endif
536536 return tmp.f;
537537 }
599599 static F snan() _STLP_NOTHROW
600600 {
601601# if defined (_STLP_BIG_ENDIAN)
602 _access tmp = { _STLP_ADDITIONAL_OPEN_BRACKET 0x7f, 0xff, 0, 0, 0x40, 0, 0, 0, 0, 0, 0, 0 _STLP_ADDITIONAL_CLOSE_BRACKET };
602 _access tmp = { _STLP_ADDITIONAL_OPEN_BRACKET 0x7f, 0xff, 0, 0, 0xa0, 0, 0, 0, 0, 0, 0, 0 _STLP_ADDITIONAL_CLOSE_BRACKET };
603603# else /* _STLP_LITTLE_ENDIAN */
604 _access tmp = { _STLP_ADDITIONAL_OPEN_BRACKET 0, 0, 0, 0, 0, 0, 0, 0x40, 0xff, 0x7f, 0, 0 _STLP_ADDITIONAL_CLOSE_BRACKET };
604 _access tmp = { _STLP_ADDITIONAL_OPEN_BRACKET 0, 0, 0, 0, 0, 0, 0, 0xa0, 0xff, 0x7f, 0, 0 _STLP_ADDITIONAL_CLOSE_BRACKET };
605605# endif
606606 return tmp.f;
607607 }
  
1616
1717#include <limits>
1818
19#include <ieee754.h>
20
1921using namespace std;
2022
2123bool valid_sign_info(bool, bool)
227227 * EXAM_CHECK_ASYNC(! (qnan <= 42));
228228 * EXAM_CHECK_ASYNC(! (qnan >= 42));
229229 */
230
231 if ( is_same<float,_Tp>::value ) {
232 ieee754_float v;
233 v.f = qnan;
234 EXAM_CHECK( v.ieee_nan.quiet_nan == 1 );
235 }
236
237 if ( is_same<double,_Tp>::value ) {
238 ieee754_double v;
239 v.d = qnan;
240 EXAM_CHECK( v.ieee_nan.quiet_nan == 1 );
241 }
242
243# if !defined ( _STLP_NO_LONG_DOUBLE )
244 if ( is_same<long double,_Tp>::value ) {
245 ieee854_long_double v;
246 v.d = qnan;
247 EXAM_CHECK( v.ieee_nan.quiet_nan == 1 );
248 }
249# endif
230250 }
251
231252 return EXAM_RESULT;
232253}
233254
255volatile const double& fdbl()
256{
257 volatile static ieee754_double v1;
234258
259 v1.ieee.negative = 0;
260 v1.ieee.exponent = 0x7ff;
261 v1.ieee.mantissa0 = 0x40000;
262 v1.ieee.mantissa1 = 0x0;
263
264 return v1.d;
265}
266
267template <class _Tp>
268int EXAM_IMPL(test_snan)
269{
270 typedef numeric_limits<_Tp> lim;
271
272 if (lim::has_signaling_NaN) {
273 const volatile _Tp snan = lim::signaling_NaN();
274
275 //if (sizeof(_Tp) == 4) {
276 // ostringstream str;
277 // str << "qnan " << qnan << ", in hexa: " << showbase << hex << *((unsigned int*)&qnan);
278 // EXAM_MESSAGE( str.str().c_str() );
279 // str.str("");
280 // float val = generate_nan(0.0f);
281 // str << "val " << val << ", in hexa: " << showbase << hex << *((unsigned int*)&val);
282 // EXAM_MESSAGE( str.str().c_str() );
283 // str.str("");
284 // val = -qnan;
285 // str << "-qnan " << val << ", in hexa: " << showbase << hex << *((unsigned int*)&val);
286 // EXAM_MESSAGE( str.str().c_str() );
287 //}
288 /* NaNs shall always compare "false" when compared for equality
289 * If one of these fail, your compiler may be optimizing incorrectly,
290 * or the STLport is incorrectly configured.
291 */
292 EXAM_CHECK( !(snan == 42));
293 EXAM_CHECK( !(snan == snan));
294 EXAM_CHECK( snan != 42);
295 EXAM_CHECK( snan != snan);
296
297 /* The following tests may cause arithmetic traps.
298 * EXAM_CHECK_ASYNC(! (snan < 42));
299 * EXAM_CHECK_ASYNC(! (snan > 42));
300 * EXAM_CHECK_ASYNC(! (snan <= 42));
301 * EXAM_CHECK_ASYNC(! (snan >= 42));
302 */
303
304 if ( is_same<float,_Tp>::value ) {
305 ieee754_float v;
306 v.f = snan;
307 EXAM_CHECK( v.ieee_nan.quiet_nan == 0 );
308 }
309
310 if ( is_same<double,_Tp>::value ) {
311 ieee754_double v;
312 v.d = snan;
313 printf( "%1x %03x %05x %08x\n", v.ieee.negative, v.ieee.exponent, v.ieee.mantissa0, v.ieee.mantissa1 );
314
315 ieee754_double v1;
316
317 v1.ieee.negative = 0;
318 v1.ieee.exponent = 0x7ff;
319 v1.ieee.mantissa0 = 0x40000;
320 v1.ieee.mantissa1 = 0x0;
321
322 printf( "%1x %03x %05x %08x\n", v1.ieee.negative, v1.ieee.exponent, v1.ieee.mantissa0, v1.ieee.mantissa1 );
323
324 // double db = v1.d;
325
326 v1.d = fdbl();
327
328 printf( "%1x %03x %05x %08x\n", v1.ieee.negative, v1.ieee.exponent, v1.ieee.mantissa0, v1.ieee.mantissa1 );
329
330 EXAM_CHECK( v.ieee_nan.quiet_nan == 0 );
331 }
332
333# if !defined ( _STLP_NO_LONG_DOUBLE )
334 if ( is_same<long double,_Tp>::value ) {
335 ieee854_long_double v;
336 v.d = snan;
337 EXAM_CHECK( v.ieee_nan.quiet_nan == 0 );
338 }
339# endif
340 }
341
342 return EXAM_RESULT;
343}
344
235345class ArbitraryType
236346{};
237347
406406 EXAM_RESULT |= test_qnan<double>( __exam_ts, 0 );
407407# if !defined ( _STLP_NO_LONG_DOUBLE )
408408 EXAM_RESULT |= test_qnan<long double>( __exam_ts, 0 );
409# endif
410
411 EXAM_RESULT |= test_snan<float>( __exam_ts, 0 );
412 EXAM_RESULT |= test_snan<double>( __exam_ts, 0 );
413# if !defined ( _STLP_NO_LONG_DOUBLE )
414 EXAM_RESULT |= test_snan<long double>( __exam_ts, 0 );
409415# endif
410416
411417# if defined (__BORLANDC__)