ReactOS  0.4.13-dev-698-g77671f0
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,
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 }
GLuint GLfloat * val
Definition: glext.h:7180
const GLdouble * v
Definition: gl.h:2040
static double _Stl_string_to_double(const char *s)

Referenced by __do_get_float().

◆ __string_to_float() [2/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 }
GLuint GLfloat * val
Definition: glext.h:7180
const GLdouble * v
Definition: gl.h:2040
static double _Stl_string_to_double(const char *s)

◆ __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 }
GLuint GLfloat * val
Definition: glext.h:7180
_STLP_STATIC_ASSERT(sizeof(nl_catd_type)<=sizeof(int)) class _STLP_CLASS_DECLSPEC _Catalog_nl_catd_map
const GLdouble * v
Definition: gl.h:2040
static double _Stl_string_to_double(const char *s)

◆ _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 }
static size_t double int ndigits
Definition: printf.c:64
wchar_t widen(char __c) const
Definition: _ctype.h:206
static const int digits[]
Definition: decode.c:71

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 long long uint64
Definition: platform.h:18
unsigned int uint32
Definition: types.h:32
GLuint buffer
Definition: glext.h:5915
void _Stl_set_exponent(uint64 &val, uint64 exp)
#define ULL(a, b)
Definition: format_msg.c:27
_STLP_STATIC_ASSERT(sizeof(nl_catd_type)<=sizeof(int)) class _STLP_CLASS_DECLSPEC _Catalog_nl_catd_map
static void _Stl_tenscale(uint64 &p, int exp, int &bexp)
GLsizei const GLfloat * value
Definition: glext.h:6069
static const int digits[]
Definition: decode.c:71

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 }
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
unsigned long long uint64
Definition: platform.h:18
GLfloat v0
Definition: glext.h:6061
GLdouble GLdouble t
Definition: gl.h:2047
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLdouble u1
Definition: glext.h:8308
#define ULL(a, b)
Definition: format_msg.c:27
GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint GLdouble GLdouble w2
Definition: glext.h:8308
const GLdouble * v
Definition: gl.h:2040
GLfloat GLfloat v1
Definition: glext.h:6062
GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint GLdouble w1
Definition: glext.h:8308

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  */
242  p = _Stl_HIBITULL;
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
#define _Stl_HIBITULL
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG x1
Definition: winddi.h:3706
GLfloat GLfloat p
Definition: glext.h:8902

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); }
#define bit11
GLuint GLfloat * val
Definition: glext.h:7180
#define exponent_mask
DWORD exp
Definition: msg.c:15681

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 }
static double _Stl_atod(char *buffer, ptrdiff_t ndigit, int dexp)
GLdouble n
Definition: glext.h:7729
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
#define e
Definition: ke_i.h:82
unsigned char
Definition: typeof.h:29
#define d
Definition: ke_i.h:81
const GLubyte * c
Definition: glext.h:8905
GLdouble s
Definition: gl.h:2039
__kernel_ptrdiff_t ptrdiff_t
Definition: linux.h:247
DWORD exp
Definition: msg.c:15681
#define c
Definition: ke_i.h:80
static const int digits[]
Definition: decode.c:71
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31

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 }
unsigned long long uint64
Definition: platform.h:18
#define TEN_1
_Tp _STLP_CALL norm(const complex< _Tp > &__z)
Definition: _complex.h:741
#define TEN_27
static void _Stl_norm_and_round(uint64 &p, int &norm, uint64 prodhi, uint64 prodlo)
static const uint64 _Stl_tenpow[80]
#define TEN_M28
static const short _Stl_twoexp[80]
static void _Stl_mult64(const uint64 u, const uint64 v, uint64 &high, uint64 &low)
#define min(a, b)
Definition: monoChain.cc:55
DWORD exp
Definition: msg.c:15681
#define NUM_HI_N
GLfloat GLfloat p
Definition: glext.h:8902
#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().