pike.git / src / stralloc.c

version» Context lines:

pike.git/src/stralloc.c:2611:    /* Note: Code duplication in strtod. */       PCHARP s;    short int sign;       /* The number so far. */    double num;       int got_dot; /* Found a decimal point. */    int got_digit; /* Seen any digits. */ +  int precision_loss;/* No more digits fit in mantissa */       /* The exponent of the number. */    long int exponent;       if (nptr.ptr == NULL)    {    errno = EINVAL;    goto noconv;    }   
pike.git/src/stralloc.c:2635:       /* Get the sign. */    sign = EXTRACT_PCHARP(s) == '-' ? -1 : 1;    if (EXTRACT_PCHARP(s) == '-' || EXTRACT_PCHARP(s) == '+')    INC_PCHARP(s,1);       num = 0.0;    got_dot = 0;    got_digit = 0;    exponent = 0; +  precision_loss = 0;    for (;; INC_PCHARP(s,1))    {    if (WIDE_ISDIGIT (EXTRACT_PCHARP(s)))    {    got_digit = 1;       /* Make sure that multiplication by 10 will not overflow. */ -  if (num > DBL_MAX * 0.1) +  if (precision_loss || num > DBL_MAX * 0.1)    /* The value of the digit doesn't matter, since we have already    gotten as many digits as can be represented in a `double'.    This doesn't necessarily mean the result will overflow.    The exponent may reduce it to within range.       We just need to record that there was another    digit so that we can multiply by 10 later. */    ++exponent; -  else -  num = (num * 10.0) + (EXTRACT_PCHARP(s) - '0'); +  else { +  int v = EXTRACT_PCHARP(s) - '0'; +  num *= 10.0; +  if (v != 0) { +  double check = num; +  num += v; +  if (num == check) +  precision_loss = 1; +  } +  }       /* Keep track of the number of digits after the decimal point.    If we just divided by 10 here, we would lose precision. */    if (got_dot)    --exponent;    }    else if (!got_dot && (char) EXTRACT_PCHARP(s) == '.')    /* Record that we have found the decimal point. */    got_dot = 1;    else
pike.git/src/stralloc.c:2768: Inside #if SIZEOF_FLOAT_TYPE > SIZEOF_DOUBLE
   /* Note: Code duplication in strtod. */       PCHARP s;    short int sign;       /* The number so far. */    long double num;       int got_dot; /* Found a decimal point. */    int got_digit; /* Seen any digits. */ +  int precision_loss;/* No more digits fit in mantissa */       /* The exponent of the number. */    long int exponent;       if (nptr.ptr == NULL)    {    errno = EINVAL;    goto noconv;    }   
pike.git/src/stralloc.c:2792: Inside #if SIZEOF_FLOAT_TYPE > SIZEOF_DOUBLE
      /* Get the sign. */    sign = EXTRACT_PCHARP(s) == '-' ? -1 : 1;    if (EXTRACT_PCHARP(s) == '-' || EXTRACT_PCHARP(s) == '+')    INC_PCHARP(s,1);       num = 0.0;    got_dot = 0;    got_digit = 0;    exponent = 0; +  precision_loss = 0;    for (;; INC_PCHARP(s,1))    {    if (WIDE_ISDIGIT (EXTRACT_PCHARP(s)))    {    got_digit = 1;       /* Make sure that multiplication by 10 will not overflow. */ -  if (num > LDBL_MAX * 0.1) +  if (precision_loss || num > LDBL_MAX * 0.1)    /* The value of the digit doesn't matter, since we have already    gotten as many digits as can be represented in a `long double'.    This doesn't necessarily mean the result will overflow.    The exponent may reduce it to within range.       We just need to record that there was another    digit so that we can multiply by 10 later. */    ++exponent; -  else -  num = (num * 10.0) + (EXTRACT_PCHARP(s) - '0'); +  else { +  int v = EXTRACT_PCHARP(s) - '0'; +  num *= 10.0; +  if (v != 0) { +  long double check = num; +  num += v; +  if (num == check) +  precision_loss = 1; +  } +  }       /* Keep track of the number of digits after the decimal point.    If we just divided by 10 here, we would lose precision. */    if (got_dot)    --exponent;    }    else if (!got_dot && (char) EXTRACT_PCHARP(s) == '.')    /* Record that we have found the decimal point. */    got_dot = 1;    else