[cff] Implement in-house power of 10
A minimal power only for natural numbers exponents of ten, for portability. Found the idea in Tcl/Tk but wrote it myself after weeks and it turned out being a different implementation, reverse direction, constexpr, etc.
This commit is contained in:
parent
f441a7c008
commit
d80a3ea983
|
@ -75,6 +75,37 @@ struct top_dict_values_t : dict_values_t<OPSTR>
|
||||||
unsigned int FDArrayOffset;
|
unsigned int FDArrayOffset;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Compile time calculating 10^n for n = 2^i */
|
||||||
|
constexpr double
|
||||||
|
pow10_of_2i (unsigned int n)
|
||||||
|
{
|
||||||
|
return n == 1 ? 10. : pow10_of_2i (n >> 1) * pow10_of_2i (n >> 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const double powers_of_10[] =
|
||||||
|
{
|
||||||
|
pow10_of_2i (0x100),
|
||||||
|
pow10_of_2i (0x80),
|
||||||
|
pow10_of_2i (0x40),
|
||||||
|
pow10_of_2i (0x20),
|
||||||
|
pow10_of_2i (0x10),
|
||||||
|
pow10_of_2i (0x8),
|
||||||
|
pow10_of_2i (0x4),
|
||||||
|
pow10_of_2i (0x2),
|
||||||
|
pow10_of_2i (0x1),
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Works for x < 512 */
|
||||||
|
inline double
|
||||||
|
_hb_pow10 (unsigned int x)
|
||||||
|
{
|
||||||
|
unsigned int mask = 0x100; /* Should be same with the first element */
|
||||||
|
unsigned long result = 1;
|
||||||
|
const double *power = powers_of_10;
|
||||||
|
for (; mask; ++power, mask >>= 1) if (mask & x) result *= *power;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
struct dict_opset_t : opset_t<number_t>
|
struct dict_opset_t : opset_t<number_t>
|
||||||
{
|
{
|
||||||
static void process_op (op_code_t op, interp_env_t<number_t>& env)
|
static void process_op (op_code_t op, interp_env_t<number_t>& env)
|
||||||
|
@ -137,7 +168,7 @@ struct dict_opset_t : opset_t<number_t>
|
||||||
value = (double) (neg ? -int_part : int_part);
|
value = (double) (neg ? -int_part : int_part);
|
||||||
if (frac_count > 0)
|
if (frac_count > 0)
|
||||||
{
|
{
|
||||||
double frac = (frac_part / pow (10.0, (double) frac_count));
|
double frac = frac_part / _hb_pow10 (frac_count);
|
||||||
if (neg) frac = -frac;
|
if (neg) frac = -frac;
|
||||||
value += frac;
|
value += frac;
|
||||||
}
|
}
|
||||||
|
@ -153,9 +184,9 @@ struct dict_opset_t : opset_t<number_t>
|
||||||
if (exp_part != 0)
|
if (exp_part != 0)
|
||||||
{
|
{
|
||||||
if (exp_neg)
|
if (exp_neg)
|
||||||
value /= pow (10.0, (double) exp_part);
|
value /= _hb_pow10 (exp_part);
|
||||||
else
|
else
|
||||||
value *= pow (10.0, (double) exp_part);
|
value *= _hb_pow10 (exp_part);
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue