Commit 9b4a29b6f7dc37d47ff7d92feb17a0b705097455

Fix qNaN and sNaN limits for x86_64

It's known, that for 32-bit mode of x86 return
double via FP register convert sNaN into qNaN,
so skip check qnan bit in this case;
problem not happens for float or long double for x86;
and this not happens for x86_64.

Not checked for non-x86* arch.
  
631631# if defined (_STLP_BIG_ENDIAN)
632632 _access tmp = { _STLP_ADDITIONAL_OPEN_BRACKET 0x7f, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 _STLP_ADDITIONAL_CLOSE_BRACKET };
633633# else /* _STLP_LITTLE_ENDIAN */
634 _access tmp = { _STLP_ADDITIONAL_OPEN_BRACKET 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0x7f _STLP_ADDITIONAL_CLOSE_BRACKET };
634 _access tmp = { _STLP_ADDITIONAL_OPEN_BRACKET 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0x7f, 0, 0, 0, 0, 0, 0 _STLP_ADDITIONAL_CLOSE_BRACKET };
635635# endif
636636 return tmp.f;
637637 }
639639 static F qnan() _STLP_NOTHROW
640640 {
641641# if defined (_STLP_BIG_ENDIAN)
642 _access tmp = { _STLP_ADDITIONAL_OPEN_BRACKET 0x7f, 0xff, 0xc0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 _STLP_ADDITIONAL_CLOSE_BRACKET };
642 _access tmp = { _STLP_ADDITIONAL_OPEN_BRACKET 0x7f, 0xff, 0, 0, 0, 0, 0xc0, 0, 0, 0, 0, 0, 0, 0, 0, 0 _STLP_ADDITIONAL_CLOSE_BRACKET };
643643# else /* _STLP_LITTLE_ENDIAN */
644 _access tmp = { _STLP_ADDITIONAL_OPEN_BRACKET 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xc0, 0xff, 0x7f _STLP_ADDITIONAL_CLOSE_BRACKET };
644 _access tmp = { _STLP_ADDITIONAL_OPEN_BRACKET 0, 0, 0, 0, 0, 0, 0, 0xc0, 0xff, 0x7f, 0, 0, 0, 0, 0, 0 _STLP_ADDITIONAL_CLOSE_BRACKET };
645645# endif
646646 return tmp.f;
647647 }
649649 static F snan() _STLP_NOTHROW
650650 {
651651# if defined (_STLP_BIG_ENDIAN)
652 _access tmp = { _STLP_ADDITIONAL_OPEN_BRACKET 0x7f, 0xff, 0x40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 _STLP_ADDITIONAL_CLOSE_BRACKET };
652 _access tmp = { _STLP_ADDITIONAL_OPEN_BRACKET 0x7f, 0xff, 0, 0, 0, 0, 0xa0, 0, 0, 0, 0, 0, 0, 0, 0, 0 _STLP_ADDITIONAL_CLOSE_BRACKET };
653653# else /* _STLP_LITTLE_ENDIAN */
654 _access tmp = { _STLP_ADDITIONAL_OPEN_BRACKET 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x40, 0xff, 0x7f _STLP_ADDITIONAL_CLOSE_BRACKET };
654 _access tmp = { _STLP_ADDITIONAL_OPEN_BRACKET 0, 0, 0, 0, 0, 0, 0, 0xa0, 0xff, 0x7f, 0, 0, 0, 0, 0, 0 _STLP_ADDITIONAL_CLOSE_BRACKET };
655655# endif
656656 return tmp.f;
657657 }
659659 static F denorm_min() _STLP_NOTHROW
660660 {
661661# if defined (_STLP_BIG_ENDIAN)
662 _access tmp = { _STLP_ADDITIONAL_OPEN_BRACKET 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1 _STLP_ADDITIONAL_CLOSE_BRACKET };
662 _access tmp = { _STLP_ADDITIONAL_OPEN_BRACKET 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1, 0, 0 _STLP_ADDITIONAL_CLOSE_BRACKET };
663663# else /* _STLP_LITTLE_ENDIAN */
664664 _access tmp = { _STLP_ADDITIONAL_OPEN_BRACKET 0x1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 _STLP_ADDITIONAL_CLOSE_BRACKET };
665665# endif
  
188188 return EXAM_RESULT;
189189}
190190
191//float generate_nan(float f) {
192// return 0.0f / f;
193//}
194template <class _Tp>
195int EXAM_IMPL(test_qnan)
196{
197 typedef numeric_limits<_Tp> lim;
198
199 if (lim::has_quiet_NaN) {
200 const volatile _Tp qnan = lim::quiet_NaN();
201
202 //if (sizeof(_Tp) == 4) {
203 // ostringstream str;
204 // str << "qnan " << qnan << ", in hexa: " << showbase << hex << *((unsigned int*)&qnan);
205 // EXAM_MESSAGE( str.str().c_str() );
206 // str.str("");
207 // float val = generate_nan(0.0f);
208 // str << "val " << val << ", in hexa: " << showbase << hex << *((unsigned int*)&val);
209 // EXAM_MESSAGE( str.str().c_str() );
210 // str.str("");
211 // val = -qnan;
212 // str << "-qnan " << val << ", in hexa: " << showbase << hex << *((unsigned int*)&val);
213 // EXAM_MESSAGE( str.str().c_str() );
214 //}
215 /* NaNs shall always compare "false" when compared for equality
216 * If one of these fail, your compiler may be optimizing incorrectly,
217 * or the STLport is incorrectly configured.
218 */
219 EXAM_CHECK( !(qnan == 42));
220 EXAM_CHECK( !(qnan == qnan));
221 EXAM_CHECK( qnan != 42);
222 EXAM_CHECK( qnan != qnan);
223
224 /* The following tests may cause arithmetic traps.
225 * EXAM_CHECK_ASYNC(! (qnan < 42));
226 * EXAM_CHECK_ASYNC(! (qnan > 42));
227 * EXAM_CHECK_ASYNC(! (qnan <= 42));
228 * EXAM_CHECK_ASYNC(! (qnan >= 42));
229 */
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
250 }
251
252 return EXAM_RESULT;
253}
254
255volatile const double& fdbl()
256{
257 volatile static ieee754_double v1;
258
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
345191class ArbitraryType
346192{};
347193
348int EXAM_IMPL(limits_test::limits) {
349# if defined (__BORLANDC__)
194int EXAM_IMPL(limits_test::limits)
195{
196#if defined (__BORLANDC__)
350197 /* Ignore FPU exceptions, set FPU precision to 64 bits */
351198 unsigned int _float_control_word = _control87(0, 0);
352199 _control87(PC_64|MCW_EM|IC_AFFINE, MCW_PC|MCW_EM|MCW_IC);
353# endif
200#endif
354201
355202 EXAM_CHECK(test_integral_limits_base(bool()));
356203 EXAM_CHECK(test_integral_limits(char()));
205205 EXAM_CHECK(test_signed_integral_limits(signed_char()));
206206 typedef unsigned char unsigned_char;
207207 EXAM_CHECK(test_unsigned_integral_limits(unsigned_char()));
208# if defined (_STLP_HAS_WCHAR_T) && !defined (_STLP_WCHAR_T_IS_USHORT)
208#if defined (_STLP_HAS_WCHAR_T) && !defined (_STLP_WCHAR_T_IS_USHORT)
209209 EXAM_CHECK(test_integral_limits(wchar_t()));
210# endif
210#endif
211211 EXAM_CHECK(test_signed_integral_limits(short()));
212212 typedef unsigned short unsigned_short;
213213 EXAM_CHECK(test_unsigned_integral_limits(unsigned_short()));
217217 EXAM_CHECK(test_signed_integral_limits(long()));
218218 typedef unsigned long unsigned_long;
219219 EXAM_CHECK(test_unsigned_integral_limits(unsigned_long()));
220# if defined (_STLP_LONG_LONG)
220#if defined (_STLP_LONG_LONG)
221221 typedef _STLP_LONG_LONG long_long;
222222 EXAM_CHECK(test_signed_integral_limits(long_long()));
223223 typedef unsigned _STLP_LONG_LONG unsigned_long_long;
226226
227227 EXAM_RESULT |= test_float_limits<float>( __exam_ts, 0 );
228228 EXAM_RESULT |= test_float_limits<double>( __exam_ts, 0 );
229# if !defined ( _STLP_NO_LONG_DOUBLE )
229#if !defined ( _STLP_NO_LONG_DOUBLE )
230230 EXAM_RESULT |= test_float_limits<long double>( __exam_ts, 0 );
231# endif
231#endif
232232
233233 EXAM_CHECK( !numeric_limits<ArbitraryType>::is_specialized );
234234
235# if defined (__BORLANDC__)
235#if defined (__BORLANDC__)
236236 /* Reset floating point control word */
237237 _clear87();
238238 _control87(_float_control_word, MCW_PC|MCW_EM|MCW_IC);
239# endif
240
241 return EXAM_RESULT;
242}
243
244int EXAM_IMPL(limits_test::qnan_test)
245{
246# if defined (__BORLANDC__)
247 /* Ignore FPU exceptions, set FPU precision to 64 bits */
248 unsigned int _float_control_word = _control87(0, 0);
249 _control87(PC_64|MCW_EM|IC_AFFINE, MCW_PC|MCW_EM|MCW_IC);
250# endif
251
252 EXAM_RESULT |= test_qnan<float>( __exam_ts, 0 );
253 EXAM_RESULT |= test_qnan<double>( __exam_ts, 0 );
254# if !defined ( _STLP_NO_LONG_DOUBLE )
255 EXAM_RESULT |= test_qnan<long double>( __exam_ts, 0 );
256# endif
257
258 EXAM_RESULT |= test_snan<float>( __exam_ts, 0 );
259 EXAM_RESULT |= test_snan<double>( __exam_ts, 0 );
260# if !defined ( _STLP_NO_LONG_DOUBLE )
261 EXAM_RESULT |= test_snan<long double>( __exam_ts, 0 );
262# endif
263
264# if defined (__BORLANDC__)
265 /* Reset floating point control word */
266 _clear87();
267 _control87(_float_control_word, MCW_PC|MCW_EM|MCW_IC);
268# endif
239#endif
269240
270241 return EXAM_RESULT;
271242}
  
1// -*- C++ -*- Time-stamp: <09/01/27 12:59:29 ptr>
1// -*- C++ -*- Time-stamp: <10/01/23 02:17:01 ptr>
22
33/*
4 * Copyright (c) 2004-2009
4 * Copyright (c) 2004-2010
55 * Petr Ovtchenkov
66 *
77 * Copyright (c) 2004-2008
1818
1919#include <exam/suite.h>
2020
21#include <limits>
22#include <type_traits>
23#include <ieee754.h>
24
2125class limits_test
2226{
2327 public:
2428 int EXAM_DECL(limits);
25 int EXAM_DECL(qnan_test);
29
30
31 template <class _Tp>
32 int EXAM_DECL(qNaN);
33
34 template <class _Tp>
35 int EXAM_DECL(sNaN);
2636};
37
38template <class _Tp>
39int EXAM_IMPL(limits_test::qNaN)
40{
41 typedef std::numeric_limits<_Tp> lim;
42
43 if ( !lim::has_quiet_NaN ) {
44 throw exam::skip_exception();
45 }
46
47#if defined (__BORLANDC__)
48 /* Ignore FPU exceptions, set FPU precision to 64 bits */
49 unsigned int _float_control_word = _control87(0, 0);
50 _control87(PC_64|MCW_EM|IC_AFFINE, MCW_PC|MCW_EM|MCW_IC);
51#endif
52
53 const volatile _Tp qnan = lim::quiet_NaN();
54
55 /* NaNs shall always compare "false" when compared for equality
56 * If one of these fail, your compiler may be optimizing incorrectly,
57 * or the STLport is incorrectly configured.
58 */
59 EXAM_CHECK( !(qnan == 42));
60 EXAM_CHECK( !(qnan == qnan));
61 EXAM_CHECK( qnan != 42);
62 EXAM_CHECK( qnan != qnan);
63
64 /* The following tests may cause arithmetic traps.
65 * EXAM_CHECK_ASYNC(! (qnan < 42));
66 * EXAM_CHECK_ASYNC(! (qnan > 42));
67 * EXAM_CHECK_ASYNC(! (qnan <= 42));
68 * EXAM_CHECK_ASYNC(! (qnan >= 42));
69 */
70
71 if ( std::is_same<float,_Tp>::value ) {
72 ieee754_float v;
73 v.f = qnan;
74 EXAM_CHECK( v.ieee_nan.quiet_nan == 1 );
75 }
76
77 if ( std::is_same<double,_Tp>::value ) {
78 ieee754_double v;
79 v.d = qnan;
80 EXAM_CHECK( v.ieee_nan.quiet_nan == 1 );
81 }
82
83#if !defined ( _STLP_NO_LONG_DOUBLE )
84 if ( std::is_same<long double,_Tp>::value ) {
85 ieee854_long_double v;
86 v.d = qnan;
87 EXAM_CHECK( v.ieee_nan.quiet_nan == 1 );
88 }
89#endif
90
91#if defined (__BORLANDC__)
92 /* Reset floating point control word */
93 _clear87();
94 _control87(_float_control_word, MCW_PC|MCW_EM|MCW_IC);
95#endif
96
97 return EXAM_RESULT;
98}
99
100template <class _Tp>
101int EXAM_IMPL(limits_test::sNaN)
102{
103 typedef std::numeric_limits<_Tp> lim;
104
105 if ( !lim::has_signaling_NaN ) {
106 throw exam::skip_exception();
107 }
108
109#if defined (__BORLANDC__)
110 /* Ignore FPU exceptions, set FPU precision to 64 bits */
111 unsigned int _float_control_word = _control87(0, 0);
112 _control87(PC_64|MCW_EM|IC_AFFINE, MCW_PC|MCW_EM|MCW_IC);
113#endif
114
115 const volatile _Tp snan = lim::signaling_NaN();
116
117 /* NaNs shall always compare "false" when compared for equality
118 * If one of these fail, your compiler may be optimizing incorrectly,
119 * or the STLport is incorrectly configured.
120 */
121 EXAM_CHECK( !(snan == 42));
122 EXAM_CHECK( !(snan == snan));
123 EXAM_CHECK( snan != 42);
124 EXAM_CHECK( snan != snan);
125
126 /* The following tests may cause arithmetic traps.
127 * EXAM_CHECK_ASYNC(! (snan < 42));
128 * EXAM_CHECK_ASYNC(! (snan > 42));
129 * EXAM_CHECK_ASYNC(! (snan <= 42));
130 * EXAM_CHECK_ASYNC(! (snan >= 42));
131 */
132
133 if ( std::is_same<float,_Tp>::value ) {
134 ieee754_float v;
135 v.f = snan;
136 EXAM_CHECK( v.ieee_nan.quiet_nan == 0 );
137 }
138
139#if (defined (__amd64__) || defined (_M_AMD64) || defined (__x86_64__)) || \
140 !(defined (__i386) || defined (_M_IX86) || defined (_M_ARM))
141 // It's known, that for 32-bit mode of x86 return
142 // via FP register convert sNaN into qNaN,
143 // so skip this check.
144 if ( std::is_same<double,_Tp>::value ) {
145 ieee754_double v;
146 v.d = snan;
147 EXAM_CHECK( v.ieee_nan.quiet_nan == 0 );
148 }
149#endif
150
151#if !defined ( _STLP_NO_LONG_DOUBLE )
152 if ( std::is_same<long double,_Tp>::value ) {
153 ieee854_long_double v;
154 v.d = snan;
155 EXAM_CHECK( v.ieee_nan.quiet_nan == 0 );
156 }
157#endif
158
159#if defined (__BORLANDC__)
160 /* Reset floating point control word */
161 _clear87();
162 _control87(_float_control_word, MCW_PC|MCW_EM|MCW_IC);
163#endif
164
165 return EXAM_RESULT;
166}
27167
28168#endif // __TEST_LIMITS_TEST_H
  
1// -*- C++ -*- Time-stamp: <09/10/16 22:18:36 ptr>
1// -*- C++ -*- Time-stamp: <10/01/23 02:25:50 ptr>
22
33/*
44 * Copyright (c) 2008, 2009
708708 limits_test lt_test;
709709
710710 t.add( &limits_test::limits, lt_test, "limits_test::limits" );
711 t.add( &limits_test::qnan_test, lt_test, "limits_test::qnan_test" );
712711
712 t.add( &limits_test::qNaN<float>, lt_test, "numeric_limits<float>::quiet_NaN()" );
713 t.add( &limits_test::qNaN<double>, lt_test, "numeric_limits<double>::quiet_NaN()" );
714#if !defined ( _STLP_NO_LONG_DOUBLE )
715 t.add( &limits_test::qNaN<long double>, lt_test, "numeric_limits<long double>::quiet_NaN()" );
716#endif
717 t.add( &limits_test::sNaN<float>, lt_test, "numeric_limits<float>::signaling_NaN()" );
718 t.add( &limits_test::sNaN<double>, lt_test, "numeric_limits<double>::signaling_NaN()" );
719#if !defined ( _STLP_NO_LONG_DOUBLE )
720 t.add( &limits_test::sNaN<long double>, lt_test, "numeric_limits<long double>::signaling_NaN()" );
721#endif
722
713723 mem_fun_ptr_test mf_test;
714724
715725 t.add( &mem_fun_ptr_test::mem_ptr_fun, mf_test, "mem_ptr_fun" );
761761
762762 num_put_get_test nmg_test;
763763
764 t.add( &num_put_get_test::num_put_float, nmg_test, "num_put_float" );
764 // t.add( &num_put_get_test::scientific_precision, nmg_test, "scientific precision",
765 t.add( &num_put_get_test::num_put_float, nmg_test, "num_put_float" ); // );
765766 t.add( &num_put_get_test::num_put_integer, nmg_test, "num_put_integer" );
766767 t.add( &num_put_get_test::num_get_float, nmg_test, "num_get_float" );
767768 t.add( &num_put_get_test::num_get_integer, nmg_test, "num_get_integer" );
810810 t.add( &locale_test::combine, ltest, "combine" );
811811
812812 if ( opts.is_set( 'l' ) ) {
813 t.print_graph( std::cerr );
813 t.print_graph( std::cout );
814814 return 0;
815815 }
816816