hmmer-3.3/easel/esl_json.c
/* Function:  esl_json_ReadFloat()
 * Synopsis:  Read a float from a valid JSON number token.
 * Incept:    SRE, Tue 14 Aug 2018
 *
 * Purpose:   Given a parse tree <pi>, where token <idx> is a validated
 *            JSON number in input buffer <bf>, convert the decimal
 *            string representation to a float; return the float in
 *            <*ret_x>.
 *            
 *            This function is adapted from <esl_mem_strtof()>.
 *            Because the input was already validated as a JSON
 *            number, and all JSON numbers are valid floating-point
 *            decimal string representations, so no error checking is
 *            needed, and the complete token is converted. JSON does
 *            not have a representation for "NaN" or "infinity".
 *            
 *            If the representation overflows (e.g. "1e999") the
 *            result is +/-infinity. If it underflows (e.g. "1e-999")
 *            the result is 0.  These conversions still return
 *            <eslOK>.
 *            
 *            Like <esl_mem_strtof()>, this conversion incurs a small
 *            roundoff error (usually within +/-1 ulp) that a strictly
 *            correct <strtof()> implementation does not. See
 *            <esl_mem.md> for discussion.
 *
 * Returns:   <eslOK>.
 */
esl_json_ReadFloat()
Synopsis:  Read a float from a valid JSON number token.
Incept:    SRE, Tue 14 Aug 2018

Given a parse tree , where token  is a validated
JSON number in input buffer , convert the decimal
string representation to a float; return the float in
<*ret_x>.

This function is adapted from .
Because the input was already validated as a JSON
number, and all JSON numbers are valid floating-point
decimal string representations, so no error checking is
needed, and the complete token is converted. JSON does
not have a representation for "NaN" or "infinity".

If the representation overflows  the
result is +/-infinity. If it underflows
the result is 0.  These conversions still return
.

Like , this conversion incurs a small
roundoff error (usually within +/-1 ulp) that a strictly
correct  implementation does not. See
 for discussion.


esl_json_ReadFloat () Synopsis : Read a float from a valid JSON number token . Incept : SRE Tue 14 Aug 2018 Given a parse tree where token is a validated JSON number in input buffer convert the decimal string representation to a float ; return the float in < * ret_x > . This function is adapted from . Because the input was already validated as a JSON number and all JSON numbers are valid floating - point decimal string representations so no error checking is needed and the complete token is converted . JSON does not have a representation for " NaN " or " infinity " . If the representation overflows the result is + / - infinity . If it underflows the result is 0 . These conversions still return . Like this conversion incurs a small roundoff error ( usually within + / - 1 ulp ) that a strictly correct implementation does not . See for discussion .
int
esl_json_ReadFloat(const ESL_JSON *pi, int idx, ESL_BUFFER *bf, float *ret_x)
{
  esl_pos_t n        = esl_json_GetLen(pi, idx, bf);
  char     *p        = esl_json_GetMem(pi, idx, bf);
  int       i        = 0;
  float     sign     = 1.0;
  float     val      = 0.0;
  float     frac     = 0.1;
  float     expsign  = 1.;
  float     exponent = 0.;
  if (p[i] == '-') { sign = -1.0; i++; }
  while (i < n && isdigit(p[i]))  val = 10. * val + (p[i++]-'0');
  if (i < n && p[i] == '.')
    while (++i < n && isdigit(p[i]))
      {
	val  += (p[i]-'0') * frac;
	frac *= 0.1;   
      }
  if (i < n && (p[i] == 'e' || p[i] == 'E'))
    {
      i++;
      if       (p[i] == '-') { expsign = -1.; i++; }
      else if  (p[i] == '+') { expsign =  1.; i++; }
      while (i < n && isdigit(p[i]))
	exponent = 10.*exponent + (p[i++]-'0') ;
      exponent = exponent * expsign;
      if (isfinite(val)) while ( val >= 10. ) { exponent += 1.; val /= 10.; }  
      if (val != 0.0)    while ( val <  1.  ) { exponent -= 1.; val *= 10.; }
    }
  ESL_DASSERT1(( i == n ));
  *ret_x = sign * val * powf(10.,exponent);  
  return eslOK;
}
int esl_json_ReadFloat ( const ESL_JSON * pi , int idx , ESL_BUFFER * bf , float * ret_x ) { esl_pos_t n = esl_json_GetLen ( pi , idx , bf ) ; char * p = esl_json_GetMem ( pi , idx , bf ) ; int i = 0 ; float sign = 1.0 ; float val = 0.0 ; float frac = 0.1 ; float expsign = 1. ; float exponent = 0. ; if ( p [ i ] == ' ' ) { sign = -1.0 ; i ++ ; } while ( i < n && isdigit ( p [ i ] ) ) val = 10. * val + ( p [ i ++ ] - ' ' ) ; if ( i < n && p [ i ] == ' ' ) while ( ++ i < n && isdigit ( p [ i ] ) ) { val += ( p [ i ] - ' ' ) * frac ; frac *= 0.1 ; } if ( i < n && ( p [ i ] == ' ' || p [ i ] == ' ' ) ) { i ++ ; if ( p [ i ] == ' ' ) { expsign = -1. ; i ++ ; } else if ( p [ i ] == ' ' ) { expsign = 1. ; i ++ ; } while ( i < n && isdigit ( p [ i ] ) ) exponent = 10. * exponent + ( p [ i ++ ] - ' ' ) ; exponent = exponent * expsign ; if ( isfinite ( val ) ) while ( val >= 10. ) { exponent += 1. ; val /= 10. ; } if ( val != 0.0 ) while ( val < 1. ) { exponent -= 1. ; val *= 10. ; } } ESL_DASSERT1 ( ( i == n ) ) ; * ret_x = sign * val * powf ( 10. , exponent ) ; return eslOK ; }
Function:  esl_json_ReadFloat()
 Synopsis:  Read a float from a valid JSON number token.
Function : esl_json_ReadFloat () Synopsis : Read a float from a valid JSON number token .
/* Parser already verified p[0..n-1] is valid JSON number, so we can
   * use a stripped-down copy of esl_mem_strtof(); we don't need to
   * check for inf|nan|infinity, for example. Large speed win.
   */ // this is a source of roundoff error. // renormalization. (and another source of roundoff error) // range errors (over/underflow) aren't checked for; just let it go to +/-inf.