ReactOS 0.4.15-dev-7842-g558ab78
num_get_float.cpp File Reference
#include "stlport_prefix.h"
#include <limits>
#include <locale>
#include <istream>
Include dependency graph for num_get_float.cpp:

Go to the source code of this file.

Classes

union  _Double_rep
 

Macros

#define bit11   ULL(0x7ff)
 
#define exponent_mask   (bit11 << 52)
 
#define TEN_1   0 /* offset to 10 ** 1 */
 
#define TEN_27   26 /* offset to 10 ** 27 */
 
#define TEN_M28   37 /* offset to 10 ** -28 */
 
#define NUM_HI_P   11
 
#define NUM_HI_N   13
 
#define _Stl_HIBITULL   (ULL(1) << 63)
 

Functions

_STLP_BEGIN_NAMESPACE _STLP_MOVE_TO_PRIV_NAMESPACE void _STLP_CALL _Initialize_get_float (const ctype< wchar_t > &ct, wchar_t &Plus, wchar_t &Minus, wchar_t &pow_e, wchar_t &pow_E, wchar_t *digits)
 
static void _Stl_mult64 (const uint64 u, const uint64 v, uint64 &high, uint64 &low)
 
void _Stl_set_exponent (uint64 &val, uint64 exp)
 
static void _Stl_norm_and_round (uint64 &p, int &norm, uint64 prodhi, uint64 prodlo)
 
static void _Stl_tenscale (uint64 &p, int exp, int &bexp)
 
static double _Stl_atod (char *buffer, ptrdiff_t ndigit, int dexp)
 
static double _Stl_string_to_double (const char *s)
 
void _STLP_CALL __string_to_float (const __iostring &v, float &val)
 
void _STLP_CALL __string_to_float (const __iostring &v, double &val)
 
void _STLP_CALL __string_to_float (const __iostring &v, long double &val)
 

Variables

static const uint64 _Stl_tenpow [80]
 
static const short _Stl_twoexp [80]
 

Macro Definition Documentation

◆ _Stl_HIBITULL

#define _Stl_HIBITULL   (ULL(1) << 63)

Definition at line 229 of file num_get_float.cpp.

◆ bit11

#define bit11   ULL(0x7ff)

Definition at line 140 of file num_get_float.cpp.

◆ exponent_mask

#define exponent_mask   (bit11 << 52)

Definition at line 141 of file num_get_float.cpp.

◆ NUM_HI_N

#define NUM_HI_N   13

Definition at line 227 of file num_get_float.cpp.

◆ NUM_HI_P

#define NUM_HI_P   11

Definition at line 226 of file num_get_float.cpp.

◆ TEN_1

#define TEN_1   0 /* offset to 10 ** 1 */

Definition at line 223 of file num_get_float.cpp.

◆ TEN_27

#define TEN_27   26 /* offset to 10 ** 27 */

Definition at line 224 of file num_get_float.cpp.

◆ TEN_M28

#define TEN_M28   37 /* offset to 10 ** -28 */

Definition at line 225 of file num_get_float.cpp.

Function Documentation

◆ __string_to_float() [1/3]

void _STLP_CALL __string_to_float ( const __iostring v,
double val 
)

Definition at line 855 of file num_get_float.cpp.

856{
857#if !defined (__linux__)
858 val = _Stl_string_to_double(v.c_str());
859#else
860 val = _Stl_string_to_doubleT<double,ieee754_double,12,IEEE754_DOUBLE_BIAS>(v.c_str());
861#endif
862}
const GLdouble * v
Definition: gl.h:2040
GLuint GLfloat * val
Definition: glext.h:7180
static double _Stl_string_to_double(const char *s)

◆ __string_to_float() [2/3]

void _STLP_CALL __string_to_float ( const __iostring v,
float val 
)

Definition at line 845 of file num_get_float.cpp.

846{
847#if !defined (__linux__)
848 val = (float)_Stl_string_to_double(v.c_str());
849#else
850 val = (float)_Stl_string_to_doubleT<double,ieee754_double,12,IEEE754_DOUBLE_BIAS>(v.c_str());
851#endif
852}
static float(__cdecl *square_half_float)(float x

Referenced by __do_get_float().

◆ __string_to_float() [3/3]

void _STLP_CALL __string_to_float ( const __iostring v,
long double val 
)

Definition at line 866 of file num_get_float.cpp.

866 {
867#if !defined (__linux__) && !defined (__MINGW32__) && !defined (__CYGWIN__) && \
868 !defined (__BORLANDC__) && !defined (__DMC__) && !defined (__HP_aCC)
869 //The following function is valid only if long double is an alias for double.
870 _STLP_STATIC_ASSERT( sizeof(long double) <= sizeof(double) )
871 val = _Stl_string_to_double(v.c_str());
872#else
873 val = _Stl_string_to_doubleT<long double,ieee854_long_double,16,IEEE854_LONG_DOUBLE_BIAS>(v.c_str());
874#endif
875}
#define _STLP_STATIC_ASSERT(expr)
Definition: features.h:313

◆ _Initialize_get_float()

_STLP_BEGIN_NAMESPACE _STLP_MOVE_TO_PRIV_NAMESPACE void _STLP_CALL _Initialize_get_float ( const ctype< wchar_t > &  ct,
wchar_t Plus,
wchar_t Minus,
wchar_t pow_e,
wchar_t pow_E,
wchar_t digits 
)

Definition at line 83 of file num_get_float.cpp.

86 {
87 char ndigits[11] = "0123456789";
88 Plus = ct.widen('+');
89 Minus = ct.widen('-');
90 pow_e = ct.widen('e');
91 pow_E = ct.widen('E');
92 ct.widen(ndigits + 0, ndigits + 10, digits);
93}
wchar_t widen(char __c) const
Definition: _ctype.h:206
static const int digits[]
Definition: decode.c:71
static size_t double int ndigits
Definition: printf.c:72

Referenced by __read_float().

◆ _Stl_atod()

static double _Stl_atod ( char buffer,
ptrdiff_t  ndigit,
int  dexp 
)
static

Definition at line 333 of file num_get_float.cpp.

333 {
334 typedef numeric_limits<double> limits;
335 _Double_rep drep;
336 uint64 &value = drep.ival; /* Value develops as follows:
337 * 1) decimal digits as an integer
338 * 2) left adjusted fraction
339 * 3) right adjusted fraction
340 * 4) exponent and fraction
341 */
342
343 uint32 guard; /* First guard bit */
344 uint64 rest; /* Remaining guard bits */
345
346 int bexp; /* binary exponent */
347 int nzero; /* number of non-zero bits */
348 int sexp; /* scaling exponent */
349
350 char *bufferend; /* pointer to char after last digit */
351
352 /* Convert the decimal digits to a binary integer. */
353 bufferend = buffer + ndigit;
354 value = 0;
355
356 while (buffer < bufferend) {
357 value *= 10;
358 value += *buffer++;
359 }
360
361 /* Check for zero and treat it as a special case */
362 if (value == 0) {
363 return 0.0;
364 }
365
366 /* Normalize value */
367 bexp = 64; /* convert from 64b int to fraction */
368
369 /* Count number of non-zeroes in value */
370 nzero = 0;
371 if ((value >> 32) != 0) { nzero = 32; } //*TY 03/25/2000 - added explicit comparison to zero to avoid uint64 to bool conversion operator
372 if ((value >> (16 + nzero)) != 0) { nzero += 16; }
373 if ((value >> ( 8 + nzero)) != 0) { nzero += 8; }
374 if ((value >> ( 4 + nzero)) != 0) { nzero += 4; }
375 if ((value >> ( 2 + nzero)) != 0) { nzero += 2; }
376 if ((value >> ( 1 + nzero)) != 0) { nzero += 1; }
377 if ((value >> ( nzero)) != 0) { nzero += 1; }
378
379 /* Normalize */
380 value <<= /*(uint64)*/ (64 - nzero); //*TY 03/25/2000 - removed extraneous cast to uint64
381 bexp -= 64 - nzero;
382
383 /* At this point we have a 64b fraction and a binary exponent
384 * but have yet to incorporate the decimal exponent.
385 */
386
387 /* multiply by 10^dexp */
388 _Stl_tenscale(value, dexp, sexp);
389 bexp += sexp;
390
391 if (bexp <= -1022) { /* HI denorm or underflow */
392 bexp += 1022;
393 if (bexp < -53) { /* guaranteed underflow */
394 value = 0;
395 }
396 else { /* denorm or possible underflow */
397 int lead0 = 12 - bexp; /* 12 sign and exponent bits */
398
399 /* we must special case right shifts of more than 63 */
400 if (lead0 > 64) {
401 rest = value;
402 guard = 0;
403 value = 0;
404 }
405 else if (lead0 == 64) {
406 rest = value & ((ULL(1)<< 63)-1);
407 guard = (uint32) ((value>> 63) & 1 );
408 value = 0;
409 }
410 else {
411 rest = value & (((ULL(1) << lead0)-1)-1);
412 guard = (uint32) (((value>> lead0)-1) & 1);
413 value >>= /*(uint64)*/ lead0; /* exponent is zero */
414 }
415
416 /* Round */
417 if (guard && ((value & 1) || rest) ) {
418 ++value;
419 if (value == (ULL(1) << (limits::digits - 1))) { /* carry created normal number */
420 value = 0;
422 }
423 }
424 }
425 }
426 else { /* not zero or denorm */
427 /* Round to 53 bits */
428 rest = value & ((1 << 10) - 1);
429 value >>= 10;
430 guard = (uint32) value & 1;
431 value >>= 1;
432
433 /* value&1 guard rest Action
434 *
435 * dc 0 dc none
436 * 1 1 dc round
437 * 0 1 0 none
438 * 0 1 !=0 round
439 */
440 if (guard) {
441 if (((value&1)!=0) || (rest!=0)) {
442 ++value; /* round */
443 if ((value >> 53) != 0) { /* carry all the way across */
444 value >>= 1; /* renormalize */
445 ++bexp;
446 }
447 }
448 }
449 /*
450 * Check for overflow
451 * IEEE Double Precision Format
452 * (From Table 7-8 of Kane and Heinrich)
453 *
454 * Fraction bits 52
455 * Emax +1023
456 * Emin -1022
457 * Exponent bias +1023
458 * Exponent bits 11
459 * Integer bit hidden
460 * Total width in bits 64
461 */
462
463 if (bexp > limits::max_exponent) { /* overflow */
464 return limits::infinity();
465 }
466 else { /* value is normal */
467 value &= ~(ULL(1) << (limits::digits - 1)); /* hide hidden bit */
468 _Stl_set_exponent(value, bexp + 1022); /* add bias */
469 }
470 }
471
472 _STLP_STATIC_ASSERT(sizeof(uint64) >= sizeof(double))
473 return drep.val;
474}
unsigned int uint32
Definition: types.h:32
unsigned long long uint64
Definition: platform.h:18
GLuint buffer
Definition: glext.h:5915
#define ULL(a, b)
Definition: format_msg.c:27
void _Stl_set_exponent(uint64 &val, uint64 exp)
static void _Stl_tenscale(uint64 &p, int exp, int &bexp)
Definition: pdh_main.c:94

Referenced by _Stl_string_to_double().

◆ _Stl_mult64()

static void _Stl_mult64 ( const uint64  u,
const uint64  v,
uint64 high,
uint64 low 
)
static

Definition at line 118 of file num_get_float.cpp.

119 {
120 const uint64 low_mask = ULL(0xffffffff);
121 const uint64 u0 = u & low_mask;
122 const uint64 u1 = u >> 32;
123 const uint64 v0 = v & low_mask;
124 const uint64 v1 = v >> 32;
125
126 uint64 t = u0 * v0;
127 low = t & low_mask;
128
129 t = u1 * v0 + (t >> 32);
130 uint64 w1 = t & low_mask;
131 uint64 w2 = t >> 32;
132
133 uint64 x = u0 * v1 + w1;
134 low += (x & low_mask) << 32;
135 high = u1 * v1 + w2 + (x >> 32);
136}
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLdouble GLdouble t
Definition: gl.h:2047
GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint GLdouble GLdouble w2
Definition: glext.h:8308
GLfloat v0
Definition: glext.h:6061
GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint GLdouble w1
Definition: glext.h:8308
GLfloat GLfloat v1
Definition: glext.h:6062
GLdouble u1
Definition: glext.h:8308
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240

Referenced by _Stl_tenscale().

◆ _Stl_norm_and_round()

static void _Stl_norm_and_round ( uint64 p,
int norm,
uint64  prodhi,
uint64  prodlo 
)
static

Definition at line 231 of file num_get_float.cpp.

231 {
232 norm = 0;
233 if ((prodhi & _Stl_HIBITULL) == 0) {
234 /* leading bit is a zero
235 * may have to normalize
236 */
237 if ((prodhi == ~_Stl_HIBITULL) &&
238 ((prodlo >> 62) == 0x3)) { /* normalization followed by round
239 * would cause carry to create
240 * extra bit, so don't normalize
241 */
243 return;
244 }
245 p = (prodhi << 1) | (prodlo >> 63); /* normalize */
246 norm = 1;
247 prodlo <<= 1;
248 }
249 else {
250 p = prodhi;
251 }
252
253 if ((prodlo & _Stl_HIBITULL) != 0) { /* first guard bit a one */
254 if (((p & 0x1) != 0) ||
255 prodlo != _Stl_HIBITULL ) { /* not borderline for round to even */
256 /* round */
257 ++p;
258 if (p == 0)
259 ++p;
260 }
261 }
262}
_Tp _STLP_CALL norm(const complex< _Tp > &__z)
Definition: _complex.h:741
GLfloat GLfloat p
Definition: glext.h:8902
#define _Stl_HIBITULL

Referenced by _Stl_tenscale().

◆ _Stl_set_exponent()

void _Stl_set_exponent ( uint64 val,
uint64  exp 
)
inline

Definition at line 148 of file num_get_float.cpp.

149{ val = (val & ~exponent_mask) | ((exp & bit11) << 52); }
DWORD exp
Definition: msg.c:16058
#define bit11

Referenced by _Stl_atod().

◆ _Stl_string_to_double()

static double _Stl_string_to_double ( const char s)
static

Definition at line 644 of file num_get_float.cpp.

644 {
645 typedef numeric_limits<double> limits;
646 const int max_digits = limits::digits10 + 2;
647 unsigned c;
648 unsigned Negate, decimal_point;
649 char *d;
650 int exp;
651 int dpchar;
652 char digits[max_digits];
653
654 c = *s++;
655
656 /* process sign */
657 Negate = 0;
658 if (c == '+') {
659 c = *s++;
660 } else if (c == '-') {
661 Negate = 1;
662 c = *s++;
663 }
664
665 d = digits;
666 dpchar = '.' - '0';
667 decimal_point = 0;
668 exp = 0;
669
670 for (;;) {
671 c -= '0';
672 if (c < 10) {
673 if (d == digits + max_digits) {
674 /* ignore more than max_digits digits, but adjust exponent */
675 exp += (decimal_point ^ 1);
676 } else {
677 if (c == 0 && d == digits) {
678 /* ignore leading zeros */
679 } else {
680 *d++ = (char) c;
681 }
682 exp -= decimal_point;
683 }
684 } else if (c == (unsigned int) dpchar && !decimal_point) { /* INTERNATIONAL */
685 decimal_point = 1;
686 } else {
687 break;
688 }
689 c = *s++;
690 }
691
692 /* strtod cant return until it finds the end of the exponent */
693 if (d == digits) {
694 return 0.0;
695 }
696
697 if (c == 'e' - '0' || c == 'E' - '0') {
698 register unsigned negate_exp = 0;
699 register int e = 0;
700 c = *s++;
701 if (c == '+' || c == ' ') {
702 c = *s++;
703 } else if (c == '-') {
704 negate_exp = 1;
705 c = *s++;
706 }
707 if (c -= '0', c < 10) {
708 do {
709 e = e * 10 + (int)c;
710 c = *s++;
711 } while (c -= '0', c < 10);
712
713 if (negate_exp) {
714 e = -e;
715 }
716 exp += e;
717 }
718 }
719
720 double x;
721 ptrdiff_t n = d - digits;
722 if ((exp + n - 1) < limits::min_exponent10) {
723 x = 0;
724 }
725 else if ((exp + n - 1) > limits::max_exponent10) {
726 x = limits::infinity();
727 }
728 else {
729 /* Let _Stl_atod diagnose under- and over-flows.
730 * If the input was == 0.0, we have already returned,
731 * so retval of +-Inf signals OVERFLOW, 0.0 UNDERFLOW */
732 x = _Stl_atod(digits, n, exp);
733 }
734
735 if (Negate) {
736 x = -x;
737 }
738
739 return x;
740}
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
unsigned char
Definition: typeof.h:29
__kernel_ptrdiff_t ptrdiff_t
Definition: linux.h:247
GLdouble s
Definition: gl.h:2039
GLdouble n
Definition: glext.h:7729
const GLubyte * c
Definition: glext.h:8905
#define d
Definition: ke_i.h:81
#define e
Definition: ke_i.h:82
#define c
Definition: ke_i.h:80
static double _Stl_atod(char *buffer, ptrdiff_t ndigit, int dexp)

Referenced by __string_to_float().

◆ _Stl_tenscale()

static void _Stl_tenscale ( uint64 p,
int  exp,
int bexp 
)
static

Definition at line 268 of file num_get_float.cpp.

268 {
269 bexp = 0;
270
271 if ( exp == 0 ) { /* no scaling needed */
272 return;
273 }
274
275 int exp_hi = 0, exp_lo = exp; /* exp = exp_hi*32 + exp_lo */
276 int tlo = TEN_1, thi; /* offsets in power of ten table */
277 int num_hi; /* number of high exponent powers */
278
279 if (exp > 0) { /* split exponent */
280 if (exp_lo > 27) {
281 exp_lo++;
282 while (exp_lo > 27) {
283 exp_hi++;
284 exp_lo -= 28;
285 }
286 }
287 thi = TEN_27;
288 num_hi = NUM_HI_P;
289 } else { // exp < 0
290 while (exp_lo < 0) {
291 exp_hi++;
292 exp_lo += 28;
293 }
294 thi = TEN_M28;
295 num_hi = NUM_HI_N;
296 }
297
298 uint64 prodhi, prodlo; /* 128b product */
299 int norm; /* number of bits of normalization */
300
301 int hi, lo; /* offsets in power of ten table */
302 while (exp_hi) { /* scale */
303 hi = (min) (exp_hi, num_hi); /* only a few large powers of 10 */
304 exp_hi -= hi; /* could iterate in extreme case */
305 hi += thi-1;
306 _Stl_mult64(p, _Stl_tenpow[hi], prodhi, prodlo);
307 _Stl_norm_and_round(p, norm, prodhi, prodlo);
308 bexp += _Stl_twoexp[hi] - norm;
309 }
310
311 if (exp_lo) {
312 lo = tlo + exp_lo -1;
313 _Stl_mult64(p, _Stl_tenpow[lo], prodhi, prodlo);
314 _Stl_norm_and_round(p, norm, prodhi, prodlo);
315 bexp += _Stl_twoexp[lo] - norm;
316 }
317
318 return;
319}
#define min(a, b)
Definition: monoChain.cc:55
static const short _Stl_twoexp[80]
static const uint64 _Stl_tenpow[80]
static void _Stl_mult64(const uint64 u, const uint64 v, uint64 &high, uint64 &low)
#define TEN_M28
#define NUM_HI_N
#define TEN_27
static void _Stl_norm_and_round(uint64 &p, int &norm, uint64 prodhi, uint64 prodlo)
#define TEN_1
#define NUM_HI_P

Referenced by _Stl_atod().

Variable Documentation

◆ _Stl_tenpow

const uint64 _Stl_tenpow[80]
static

Definition at line 159 of file num_get_float.cpp.

Referenced by _Stl_tenscale().

◆ _Stl_twoexp

const short _Stl_twoexp[80]
static
Initial value:
= {
4,7,10,14,17,20,24,27,30,34,37,40,44,47,50,54,57,60,64,67,70,74,77,80,84,87,90,
183,276,369,462,555,648,741,834,927,1020,
-93,-186,-279,-372,-465,-558,-651,-744,-837,-930,-1023,-1116,-1209
}

Definition at line 217 of file num_get_float.cpp.

Referenced by _Stl_tenscale().