Update contrib.
3 /************************************************************************
5 * valcmp.cpp - definitions of the rw_valcmp() family of helper functions
7 * $Id: valcmp.cpp 332687 2005-11-12 00:47:57Z sebor $
9 ************************************************************************
11 * Copyright (c) 1994-2005 Quovadx, Inc., acting through its Rogue Wave
12 * Software division. Licensed under the Apache License, Version 2.0 (the
13 * "License"); you may not use this file except in compliance with the
14 * License. You may obtain a copy of the License at
15 * http://www.apache.org/licenses/LICENSE-2.0. Unless required by
16 * applicable law or agreed to in writing, software distributed under
17 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
18 * CONDITIONS OF ANY KIND, either express or implied. See the License
19 * for the specific language governing permissions and limitations under
22 **************************************************************************/
24 // expand _TEST_EXPORT macros
25 #define _RWSTD_TEST_SRC
30 #include <stdio.h> // for fprintf, stderr
31 #include <stdlib.h> // for abort
32 #include <string.h> // for memcmp
34 /**************************************************************************/
36 typedef unsigned char UChar;
45 // .0 .1 .2 .3 .4 .5 .6 .7 .8 .9 .a .b .c .d .e .f
46 // --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
47 // NUL SOH STX ETX EOT ENQ ACK BEL BS TAB LF VT FF CR SO SI
48 /* 0. */ "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
49 // DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM SUB ESC FS GS RS US
50 /* 1. */ "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
51 // SPC ! " # $ % ' ' ( ) * + , - . /
52 /* 2. */ "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
53 // 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
54 /* 3. */ "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
55 // A B C D E F G H I J K L M N O
56 /* 4. */ "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
57 // P Q R S T U V W X Y Z [ \ ] ^ _
58 /* 5. */ "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
59 // ` a b c d e f g h i j k l m n o
60 /* 6. */ "\x60\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
61 // p q r s t u v w x y z { | } ~ DEL
62 /* 7. */ "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x7b\x7c\x7d\x7e\x7f"
65 /* 8. */ "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
66 /* 9. */ "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
67 /* a. */ "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
68 /* b. */ "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
69 /* c. */ "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
70 /* d. */ "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
71 /* e. */ "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef"
72 /* f. */ "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"
77 // .0 .1 .2 .3 .4 .5 .6 .7 .8 .9 .a .b .c .d .e .f
78 // --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
79 // NUL SOH STX ETX PF HT LC DEL SMM VT FF CR SO SI
80 /* 0. */ "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
81 // DLE DC1 DC2 TM RES NL BS IL CAN EM CC CU1 IFS IGS IRS IUS
82 /* 1. */ "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
83 // DS SOS FS BYP LF ETB ESC SM CU2 ENQ ACK BEL
84 /* 2. */ "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
85 // SYN PN RS UC EOT CU3 DC4 NAK SUB
86 /* 3. */ "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
88 /* 4. */ "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
90 /* 5. */ "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
92 /* 6. */ "\x60\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
94 /* 7. */ "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
96 /* 8. */ "\x80\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\x8a\x8b\x8c\x8d\x8e\x8f"
98 /* 9. */ "\x90\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\x9a\x9b\x9c\x9d\x9e\x9f"
100 /* a. */ "\xa0\xa1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xaa\xab\xac\xad\xae\xaf"
102 /* b. */ "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
104 /* c. */ "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
106 /* d. */ "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
108 /* e. */ "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef"
109 // 0 1 2 3 4 5 6 7 8 9
110 /* f. */ "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"
112 #else // 'A' != 0x41 && 'A' != 0xc1
113 # error unknown character set (neither ASCII nor EBCDIC)
114 #endif // ASCII or EBCDIC
119 // returns 1 iff all size bytes of the object pointed to by buf are 0
121 _rw_iszero (const void *buf, _RWSTD_SIZE_T size)
123 for (_RWSTD_SIZE_T i = 0; i != size; ++i)
124 if (_RWSTD_STATIC_CAST (const UChar*, buf)[i])
131 // compares two objects of equal size
133 _rw_cmpx (const void *buf1,
135 _RWSTD_SIZE_T nelems,
139 const UChar *p1 = _RWSTD_STATIC_CAST (const UChar*, buf1);
140 const UChar *p2 = _RWSTD_STATIC_CAST (const UChar*, buf2);
144 for ( ; nelems; p1 += size, p2 += size, --nelems) {
146 ret = memcmp (p1, p2, size);
148 if (flags & CMP_NULTERM) {
150 const int zero1 = _rw_iszero (p1, size);
151 const int zero2 = _rw_iszero (p2, size);
153 if (zero1 || zero2) {
159 if (ret && (flags & CMP_NOCASE)) {
162 "%s:%d: case insensitive comparison not implemented\n",
168 if (flags & CMP_RETOFF) {
171 "%s:%d: returning offset not implemented\n",
176 return ret < 0 ? -1 : ret ? +1 : 0;
180 // compares two byte arrays
182 _rw_cmp1 (const void *buf1,
184 _RWSTD_SIZE_T nelems,
187 #ifdef _RWSTD_UINT8_T
189 typedef _RWSTD_UINT8_T UI8T;
192 const int ret = memcmp (buf1, buf2, nelems);
193 return ret < 0 ? -1 : ret ? +1 : 0;
196 if (CMP_NULTERM == flags) {
198 strncmp (_RWSTD_STATIC_CAST (const char*, buf1),
199 _RWSTD_STATIC_CAST (const char*, buf2),
201 return ret < 0 ? -1 : ret ? +1 : 0;
207 const UI8T *pi1 = _RWSTD_STATIC_CAST (const UI8T*, buf1);
208 const UI8T *pi2 = _RWSTD_STATIC_CAST (const UI8T*, buf2);
210 for (; nelems; ++pi1, ++pi2, --nelems, ++inx) {
212 const UI8T ui1 = *pi1;
213 const UI8T ui2 = *pi2;
215 if (flags & CMP_NULTERM) {
229 if (flags & CMP_NOCASE) {
230 if (_rw_upper [ui1] != _rw_upper [ui2]) {
231 ret = _rw_upper [ui1] < _rw_upper [ui2] ? -1 : +1;
236 ret = ui1 < ui2 ? -1 : +1;
242 if (CMP_RETOFF & flags) {
243 ret = _RWSTD_STATIC_CAST (_RWSTD_SIZE_T, inx) < nelems ? inx : -1;
248 #else // if !defined (_RWSTD_UINT8_T)
249 # error _RWSTD_UINT8_T not #defined (configuration problem?)
250 #endif // _RWSTD_UINT8_T
255 // compares two arrays of objects each 16 bits in size
257 _rw_cmp2 (const void *buf1,
259 _RWSTD_SIZE_T nelems,
262 #ifdef _RWSTD_UINT16_T
264 typedef _RWSTD_UINT16_T UI16T;
269 const UI16T *pi1 = _RWSTD_STATIC_CAST (const UI16T*, buf1);
270 const UI16T *pi2 = _RWSTD_STATIC_CAST (const UI16T*, buf2);
272 for (; nelems; ++pi1, ++pi2, --nelems) {
274 const UI16T ui1 = *pi1;
275 const UI16T ui2 = *pi2;
277 if (flags & CMP_NULTERM) {
291 if (flags & CMP_NOCASE) {
292 if (_RWSTD_UCHAR_MAX < ui1 || _RWSTD_UCHAR_MAX < ui2) {
293 ret = ui1 < ui2 ? -1 : +1;
296 else if (_rw_upper [ui1] != _rw_upper [ui2]) {
297 ret = _rw_upper [ui1] < _rw_upper [ui2] ? -1 : +1;
302 ret = ui1 < ui2 ? -1 : +1;
308 if (CMP_RETOFF & flags) {
309 ret = _RWSTD_STATIC_CAST (_RWSTD_SIZE_T, inx) < nelems ? inx : -1;
314 #else // if !defined (_RWSTD_UINT16_T)
316 return _rw_cmpx (buf1, buf2, nelems, 2, flags);
318 #endif // _RWSTD_UINT16_T
322 // compares two arrays of objects each 32 bits in size
324 _rw_cmp4 (const void *buf1,
326 _RWSTD_SIZE_T nelems,
329 #ifdef _RWSTD_UINT32_T
331 typedef _RWSTD_UINT32_T UI32T;
336 const UI32T *pi1 = _RWSTD_STATIC_CAST (const UI32T*, buf1);
337 const UI32T *pi2 = _RWSTD_STATIC_CAST (const UI32T*, buf2);
339 for (; nelems; ++pi1, ++pi2, --nelems) {
341 const UI32T ui1 = *pi1;
342 const UI32T ui2 = *pi2;
344 if (flags & CMP_NULTERM) {
358 if (flags & CMP_NOCASE) {
359 if (_RWSTD_UCHAR_MAX < ui1 || _RWSTD_UCHAR_MAX < ui2) {
360 ret = ui1 < ui2 ? -1 : +1;
363 else if (_rw_upper [ui1] != _rw_upper [ui2]) {
364 ret = _rw_upper [ui1] < _rw_upper [ui2] ? -1 : +1;
369 ret = ui1 < ui2 ? -1 : +1;
375 if (CMP_RETOFF & flags) {
376 ret = _RWSTD_STATIC_CAST (_RWSTD_SIZE_T, inx) < nelems ? inx : -1;
381 #else // if !defined (_RWSTD_UINT32_T)
383 return _rw_cmpx (buf1, buf2, nelems, 4, flags);
385 #endif // _RWSTD_UINT32_T
389 // compares two arrays of objects each 64 bits in size
391 _rw_cmp8 (const void *buf1,
393 _RWSTD_SIZE_T nelems,
396 #ifdef _RWSTD_UINT64_T
398 typedef _RWSTD_UINT64_T UI64T;
403 const UI64T *pi1 = _RWSTD_STATIC_CAST (const UI64T*, buf1);
404 const UI64T *pi2 = _RWSTD_STATIC_CAST (const UI64T*, buf2);
406 for (; nelems; ++pi1, ++pi2, --nelems) {
408 const UI64T ui1 = *pi1;
409 const UI64T ui2 = *pi2;
411 if (flags & CMP_NULTERM) {
425 if (flags & CMP_NOCASE) {
426 if (_RWSTD_UCHAR_MAX < ui1 || _RWSTD_UCHAR_MAX < ui2) {
427 ret = ui1 < ui2 ? -1 : +1;
430 else if (_rw_upper [ui1] != _rw_upper [ui2]) {
431 ret = _rw_upper [ui1] < _rw_upper [ui2] ? -1 : +1;
436 ret = ui1 < ui2 ? -1 : +1;
442 if (CMP_RETOFF & flags) {
443 ret = _RWSTD_STATIC_CAST (_RWSTD_SIZE_T, inx) < nelems ? inx : -1;
448 #else // if !defined (_RWSTD_UINT64_T)
450 return _rw_cmpx (buf1, buf2, nelems, 8, flags);
452 #endif // _RWSTD_UINT64_T
456 // compares two arrays of objects of unequal size
458 _rw_cmpxx (const void* buf1,
460 _RWSTD_SIZE_T nelems,
468 for (; nelems; --nelems, ++inx) {
470 #ifdef _RWSTD_UINT64_T
475 #else // if !defined (_RWSTD_UINT64_T)
480 #endif // _RWSTD_UINT64_T
484 #ifdef _RWSTD_UINT8_T
487 const _RWSTD_UINT8_T* ptr =
488 _RWSTD_STATIC_CAST (const _RWSTD_UINT8_T*, buf1);
494 #endif // _RWSTD_UINT8_T
496 #ifdef _RWSTD_UINT16_T
499 const _RWSTD_UINT16_T* ptr =
500 _RWSTD_STATIC_CAST (const _RWSTD_UINT16_T*, buf1);
506 #endif // _RWSTD_UINT16_T
508 #ifdef _RWSTD_UINT32_T
511 const _RWSTD_UINT32_T* ptr =
512 _RWSTD_STATIC_CAST (const _RWSTD_UINT32_T*, buf1);
518 #endif // _RWSTD_UINT32_T
520 #ifdef _RWSTD_UINT64_T
523 const _RWSTD_UINT64_T* ptr =
524 _RWSTD_STATIC_CAST (const _RWSTD_UINT64_T*, buf1);
530 #endif // _RWSTD_UINT64_T
534 "%s:%d: comparison of objects %u and %u bytes in size "
535 "not implemented\n", __FILE__, __LINE__,
536 unsigned (size1), unsigned (size2));
542 #ifdef _RWSTD_UINT8_T
545 const _RWSTD_UINT8_T* ptr =
546 _RWSTD_STATIC_CAST (const _RWSTD_UINT8_T*, buf2);
552 #endif // _RWSTD_UINT8_T
554 #ifdef _RWSTD_UINT16_T
557 const _RWSTD_UINT16_T* ptr =
558 _RWSTD_STATIC_CAST (const _RWSTD_UINT16_T*, buf2);
564 #endif // _RWSTD_UINT16_T
566 #ifdef _RWSTD_UINT32_T
569 const _RWSTD_UINT32_T* ptr =
570 _RWSTD_STATIC_CAST (const _RWSTD_UINT32_T*, buf2);
576 #endif // _RWSTD_UINT32_T
578 #ifdef _RWSTD_UINT64_T
581 const _RWSTD_UINT64_T* ptr =
582 _RWSTD_STATIC_CAST (const _RWSTD_UINT64_T*, buf2);
588 #endif // _RWSTD_UINT64_T
592 "%s:%d: comparison of objects %u and %u bytes in size "
593 "not implemented\n", __FILE__, __LINE__,
594 unsigned (size1), unsigned (size2));
598 if (flags & CMP_NULTERM) {
612 if (flags & CMP_NOCASE) {
613 if (_RWSTD_UCHAR_MAX < ui1 || _RWSTD_UCHAR_MAX < ui2) {
614 ret = ui1 < ui2 ? -1 : +1;
617 else if (_rw_upper [ui1] != _rw_upper [ui2]) {
618 ret = _rw_upper [ui1] < _rw_upper [ui2] ? -1 : +1;
623 ret = ui1 < ui2 ? -1 : +1;
629 if (CMP_RETOFF & flags) {
630 ret = _RWSTD_STATIC_CAST (_RWSTD_SIZE_T, inx) < nelems ? inx : -1;
638 rw_valcmp (const void* buf1,
640 _RWSTD_SIZE_T nelems,
645 if (size1 == size2) {
648 case 1: return _rw_cmp1 (buf1, buf2, nelems, flags);
649 case 2: return _rw_cmp2 (buf1, buf2, nelems, flags);
650 case 4: return _rw_cmp4 (buf1, buf2, nelems, flags);
651 case 8: return _rw_cmp8 (buf1, buf2, nelems, flags);
654 return _rw_cmpx (buf1, buf2, nelems, size1, flags);
657 return _rw_cmpxx (buf1, buf2, nelems, size1, size2, flags);
662 rw_strncmp (const char* str1,
664 _RWSTD_SIZE_T nelems /* = _RWSTD_SIZE_MAX */,
665 int flags /* = CMP_NULTERM */)
667 return rw_valcmp (str1, str2, nelems, 1, 1, flags);
671 #ifndef _RWSTD_NO_WCHAR_T
674 rw_strncmp (const char* str1,
676 _RWSTD_SIZE_T nelems /* = _RWSTD_SIZE_MAX */,
677 int flags /* = CMP_NULTERM */)
679 return rw_valcmp (str1, str2, nelems, 1, sizeof (wchar_t), flags);
684 rw_strncmp (const wchar_t* str1,
686 _RWSTD_SIZE_T nelems /* = _RWSTD_SIZE_MAX */,
687 int flags /* = CMP_NULTERM */)
689 return rw_valcmp (str1, str2, nelems, sizeof (wchar_t), 1, flags);
694 rw_strncmp (const wchar_t* str1,
696 _RWSTD_SIZE_T nelems /* = _RWSTD_SIZE_MAX */,
697 int flags /* = CMP_NULTERM */)
699 return rw_valcmp (str1, str2, nelems,
700 sizeof (wchar_t), sizeof (wchar_t), flags);
703 #endif // _RWSTD_NO_WCHAR_T
706 // floating point comparison helpers based on
707 // http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
710 rw_fltcmp (float x, float y)
712 #if _RWSTD_SHRT_SIZE == _RWSTD_INT_SIZE
715 #pragma diag_suppress 68
717 const IntT imin = _RWSTD_SHRT_MIN;
719 #elif _RWSTD_FLT_SIZE == _RWSTD_INT_SIZE
721 const IntT imin = _RWSTD_INT_MIN;
722 #elif _RWSTD_FLT_SIZE == _RWSTD_LONG_SIZE
724 const IntT imin = _RWSTD_LONG_MIN;
725 #elif _RWSTD_FLT_SIZE == _RWSTD_LLONG_SIZE
726 typedef _RWSTD_LONG_LONG IntT;
727 const IntT imin = _RWSTD_LLONG_MIN;
730 # error no integral type of the same size as float exists
736 // make both arguments lexicographically ordered as twos-complement ints
737 IntT x_int = *(IntT*)&x;
739 x_int = imin - x_int;
741 IntT y_int = *(IntT*)&y;
743 y_int = imin - y_int;
745 const IntT int_diff = x_int - y_int;
751 #define Abs(x) ((x) < 0 ? -(x) : (x))
755 rw_dblcmp (double x, double y)
757 #if _RWSTD_DBL_SIZE == _RWSTD_INT_SIZE
759 const IntT imin = _RWSTD_INT_MIN;
760 #elif _RWSTD_DBL_SIZE == _RWSTD_LONG_SIZE
762 const IntT imin = _RWSTD_LONG_MIN;
763 #elif _RWSTD_DBL_SIZE == _RWSTD_LLONG_SIZE
764 typedef _RWSTD_LONG_LONG IntT;
765 const IntT imin = _RWSTD_LLONG_MIN;
768 #if _RWSTD_LLONG_SIZE < _RWSTD_DBL_SIZE
773 // FIXME: use integer math as in the functions above
775 const double diff = x - y;
777 // check absolute error
778 if (Abs (diff) < _RWSTD_DBL_EPSILON)
781 // check relative error
782 const double relerr =
783 Abs (x) < Abs (y) ? Abs (diff / y) : Abs (diff / x);
785 if (relerr <= 0.0000001)
788 return x < y ? -1 : +1;
790 #else // if !(_RWSTD_LLONG_SIZE < _RWSTD_DBL_SIZE)
795 IntT x_int = *(IntT*)&x;
797 x_int = imin - x_int;
799 IntT y_int = *(IntT*)&y;
801 y_int = imin - y_int;
803 const IntT int_diff = x_int - y_int;
807 #endif // _RWSTD_LLONG_SIZE < _RWSTD_DBL_SIZE
812 #ifndef _RWSTD_NO_LONG_DOUBLE
814 rw_ldblcmp (long double x, long double y)
816 if (sizeof (long double) == sizeof (double))
817 return rw_dblcmp (double (x), double (y));
820 #pragma diag_suppress 111
827 // FIXME: use integer math as in the functions above
829 const long double diff = x - y;
831 // check absolute error
832 if (Abs (diff) < _RWSTD_LDBL_EPSILON)
835 // check relative error
836 const long double relerr =
837 Abs (x) < Abs (y) ? Abs (diff / y) : Abs (diff / x);
839 if (relerr <= 0.0000001L)
842 return x < y ? -1 : +1;
845 #endif // _RWSTD_NO_LONG_DOUBLE
849 rw_strcmp (std::basic_string<char>& x ,/*std::basic_string<char> */ long double y)
851 const char * c= x.c_str();
853 /*if(x.compare(y)==0)
856 return x.compare(y)<0?-1:+1; */
859 if ((long double)z == y)
862 // FIXME: use integer math as in the functions above
864 const long double diff =((long double)z) - y;
866 // check absolute error
867 if (Abs (diff) < _RWSTD_LDBL_EPSILON)
870 // check relative error
871 const long double relerr =
872 Abs ((long double)z) < Abs (y) ? Abs (diff / y) : Abs (diff /(long double)z);
874 if (relerr <= 0.0000001L)
877 return z < y ? -1 : +1;
882 rw_strcmp (std::basic_string<wchar_t>& x ,long double y)
884 /* if(x.compare(y)==0)
887 return x.compare(y)<0?-1:+1; */
890 const wchar_t *w=x.c_str();
896 if ((long double)z == y)
899 // FIXME: use integer math as in the functions above
901 const long double diff =((long double)z) - y;
903 // check absolute error
904 if (Abs (diff) < _RWSTD_LDBL_EPSILON)
907 // check relative error
908 const long double relerr =
909 Abs ((long double)z) < Abs (y) ? Abs (diff / y) : Abs (diff /(long double)z);
911 if (relerr <= 0.0000001L)
914 return z < y ? -1 : +1;
918 void WCtoC(const wchar_t *wstr, int len, char* str)