check overflow & clamp
This commit is contained in:
parent
32cc46c75a
commit
5a7c371e4c
|
@ -105,16 +105,17 @@ struct DictOpSet : OpSet<Number>
|
||||||
|
|
||||||
static inline double parse_bcd (SubByteStr& substr)
|
static inline double parse_bcd (SubByteStr& substr)
|
||||||
{
|
{
|
||||||
double v = 0.0;
|
|
||||||
|
|
||||||
bool neg = false;
|
bool neg = false;
|
||||||
double int_part = 0;
|
double int_part = 0;
|
||||||
long frac_part = 0;
|
long frac_part = 0;
|
||||||
unsigned int frac_count = 0;
|
unsigned int frac_count = 0;
|
||||||
bool exp_neg = false;
|
bool exp_neg = false;
|
||||||
unsigned int exp_part = 0;
|
unsigned int exp_part = 0;
|
||||||
|
bool exp_overflow = false;
|
||||||
enum Part { INT_PART=0, FRAC_PART, EXP_PART } part = INT_PART;
|
enum Part { INT_PART=0, FRAC_PART, EXP_PART } part = INT_PART;
|
||||||
enum Nibble { DECIMAL=10, EXP_POS, EXP_NEG, RESERVED, NEG, END };
|
enum Nibble { DECIMAL=10, EXP_POS, EXP_NEG, RESERVED, NEG, END };
|
||||||
|
const unsigned long MAX_FRACT = 0xFFFFFFFFFFFFFlu; /* 1^52-1 */
|
||||||
|
const unsigned int MAX_EXP = 0x7FFu; /* 1^11-1 */
|
||||||
|
|
||||||
double value = 0.0;
|
double value = 0.0;
|
||||||
unsigned char byte = 0;
|
unsigned char byte = 0;
|
||||||
|
@ -139,12 +140,21 @@ struct DictOpSet : OpSet<Number>
|
||||||
{
|
{
|
||||||
case RESERVED:
|
case RESERVED:
|
||||||
substr.set_error ();
|
substr.set_error ();
|
||||||
return v;
|
return value;
|
||||||
|
|
||||||
case END:
|
case END:
|
||||||
value = (double)(neg? -int_part: int_part);
|
value = (double)(neg? -int_part: int_part);
|
||||||
if (frac_count > 0)
|
if (frac_count > 0)
|
||||||
value += (frac_part / pow (10.0, (double)frac_count));
|
value += (frac_part / pow (10.0, (double)frac_count));
|
||||||
|
if (unlikely (exp_overflow))
|
||||||
|
{
|
||||||
|
if (value == 0.0)
|
||||||
|
return value;
|
||||||
|
if (exp_neg)
|
||||||
|
return neg? -DBL_MIN: DBL_MIN;
|
||||||
|
else
|
||||||
|
return neg? -DBL_MAX: DBL_MAX;
|
||||||
|
}
|
||||||
if (exp_part != 0)
|
if (exp_part != 0)
|
||||||
{
|
{
|
||||||
if (exp_neg)
|
if (exp_neg)
|
||||||
|
@ -167,7 +177,7 @@ struct DictOpSet : OpSet<Number>
|
||||||
if (part != INT_PART)
|
if (part != INT_PART)
|
||||||
{
|
{
|
||||||
substr.set_error ();
|
substr.set_error ();
|
||||||
return v;
|
return value;
|
||||||
}
|
}
|
||||||
part = FRAC_PART;
|
part = FRAC_PART;
|
||||||
break;
|
break;
|
||||||
|
@ -180,7 +190,7 @@ struct DictOpSet : OpSet<Number>
|
||||||
if (part == EXP_PART)
|
if (part == EXP_PART)
|
||||||
{
|
{
|
||||||
substr.set_error ();
|
substr.set_error ();
|
||||||
return v;
|
return value;
|
||||||
}
|
}
|
||||||
part = EXP_PART;
|
part = EXP_PART;
|
||||||
break;
|
break;
|
||||||
|
@ -193,18 +203,26 @@ struct DictOpSet : OpSet<Number>
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FRAC_PART:
|
case FRAC_PART:
|
||||||
frac_part = (frac_part * 10) + d;
|
if (likely ((fract_count <= MAX_FRACT / 10)))
|
||||||
frac_count++;
|
{
|
||||||
|
frac_part = (frac_part * 10) + d;
|
||||||
|
frac_count++;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EXP_PART:
|
case EXP_PART:
|
||||||
exp_part = (exp_part * 10) + d;
|
if (likely (exp_part * 10) + d <= MAX_EXP)
|
||||||
|
{
|
||||||
|
exp_part = (exp_part * 10) + d;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
exp_overflow = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return v;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool is_hint_op (OpCode op)
|
static inline bool is_hint_op (OpCode op)
|
||||||
|
|
Loading…
Reference in New Issue