fix decfloat_to_int, Less divisions in decfloat_to_int.
Signed-off-by: Michael Moon <triffid.hunter@gmail.com>
This commit is contained in:
parent
c364e8f873
commit
4febbea2f8
|
|
@ -25,10 +25,10 @@
|
|||
which is about the worst case we have. All other machines have a bigger build volume.
|
||||
*/
|
||||
|
||||
#define STEPS_PER_M_X ((uint32_t) (STEPS_PER_MM_X * 1000.0))
|
||||
#define STEPS_PER_M_Y ((uint32_t) (STEPS_PER_MM_Y * 1000.0))
|
||||
#define STEPS_PER_M_Z ((uint32_t) (STEPS_PER_MM_Z * 1000.0))
|
||||
#define STEPS_PER_M_E ((uint32_t) (STEPS_PER_MM_E * 1000.0))
|
||||
#define STEPS_PER_M_X ((uint32_t) ((STEPS_PER_MM_X * 1000.0) + 0.5))
|
||||
#define STEPS_PER_M_Y ((uint32_t) ((STEPS_PER_MM_Y * 1000.0) + 0.5))
|
||||
#define STEPS_PER_M_Z ((uint32_t) ((STEPS_PER_MM_Z * 1000.0) + 0.5))
|
||||
#define STEPS_PER_M_E ((uint32_t) ((STEPS_PER_MM_E * 1000.0) + 0.5))
|
||||
|
||||
/*
|
||||
mm -> inch conversion
|
||||
|
|
@ -50,8 +50,10 @@ GCODE_COMMAND next_target __attribute__ ((__section__ (".bss")));
|
|||
/*
|
||||
utility functions
|
||||
*/
|
||||
extern const uint32_t powers[]; // defined in sermsg.c
|
||||
const int32_t rounding[DECFLOAT_EXP_MAX] = {0, 5, 50, 500, 5000, 50000, 500000};
|
||||
|
||||
int32_t decfloat_to_int(decfloat *df, int32_t multiplicand, int32_t denominator) {
|
||||
static int32_t decfloat_to_int(decfloat *df, int32_t multiplicand, uint32_t denominator) {
|
||||
int32_t r = df->mantissa;
|
||||
uint8_t e = df->exponent;
|
||||
|
||||
|
|
@ -59,36 +61,21 @@ int32_t decfloat_to_int(decfloat *df, int32_t multiplicand, int32_t denominator)
|
|||
if (e)
|
||||
e--;
|
||||
|
||||
// scale factors
|
||||
// if (multiplicand != 1)
|
||||
// r *= multiplicand;
|
||||
// if (denominator != 1)
|
||||
// r /= denominator;
|
||||
|
||||
int32_t rnew1 = r * (multiplicand / denominator);
|
||||
int32_t rnew2 = r * (multiplicand % denominator) / denominator;
|
||||
r = rnew1 + rnew2;
|
||||
if (e)
|
||||
{
|
||||
int32_t rnew2 = r * (multiplicand % denominator) / denominator;
|
||||
r = rnew1 + rnew2;
|
||||
|
||||
// sign
|
||||
if (df->sign)
|
||||
r = -r;
|
||||
|
||||
// exponent- try to keep divides to a minimum for common (small) values at expense of slightly more code
|
||||
while (e >= 5) {
|
||||
r /= 100000;
|
||||
e -= 5;
|
||||
r = (r + rounding[e]) / powers[e];
|
||||
}
|
||||
else
|
||||
{
|
||||
int32_t rnew2 = (r * (multiplicand % denominator) + (denominator / 2)) / denominator;
|
||||
r = rnew1 + rnew2;
|
||||
}
|
||||
|
||||
if (e == 1)
|
||||
r /= 10;
|
||||
else if (e == 2)
|
||||
r /= 100;
|
||||
else if (e == 3)
|
||||
r /= 1000;
|
||||
else if (e == 4)
|
||||
r /= 10000;
|
||||
|
||||
return r;
|
||||
return df->sign ? -r : r;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
@ -292,10 +279,11 @@ void gcode_parse_char(uint8_t c) {
|
|||
#endif
|
||||
|
||||
default:
|
||||
// can't do ranges in switch..case, so process actual digits here. Limit the digits right of the decimal to avoid variable overflow in decfloat_to_int() due to excess precision
|
||||
if (c >= '0' && c <= '9' &&
|
||||
((next_target.option_inches == 0 && read_digit.exponent < 4) ||
|
||||
(next_target.option_inches && read_digit.exponent < 5))) {
|
||||
// can't do ranges in switch..case, so process actual digits here.
|
||||
if ( c >= '0'
|
||||
&& c <= '9'
|
||||
&& read_digit.mantissa < (DECFLOAT_MANT_MAX / 10)
|
||||
&& read_digit.exponent < DECFLOAT_EXP_MAX ) {
|
||||
// this is simply mantissa = (mantissa * 10) + atoi(c) in different clothes
|
||||
read_digit.mantissa = (read_digit.mantissa << 3) + (read_digit.mantissa << 1) + (c - '0');
|
||||
if (read_digit.exponent)
|
||||
|
|
|
|||
|
|
@ -16,11 +16,18 @@
|
|||
// wether to insist on a checksum
|
||||
//#define REQUIRE_CHECKSUM
|
||||
|
||||
// this is a very crude decimal-based floating point structure. a real floating point would at least have signed exponent
|
||||
// this is a very crude decimal-based floating point structure.
|
||||
// a real floating point would at least have signed exponent.
|
||||
// max (DECFLOAT_EXP_MAX - 1) digits after decimal point, because point is
|
||||
// counted as well
|
||||
#define DECFLOAT_EXP_WIDTH 3
|
||||
#define DECFLOAT_EXP_MAX ((1 << DECFLOAT_EXP_WIDTH) - 1)
|
||||
#define DECFLOAT_MANT_WIDTH (32 - 1 - DECFLOAT_EXP_WIDTH)
|
||||
#define DECFLOAT_MANT_MAX (((uint32_t)1 << DECFLOAT_MANT_WIDTH) - 1)
|
||||
typedef struct {
|
||||
uint32_t sign :1;
|
||||
uint32_t mantissa :24;
|
||||
uint32_t exponent :7;
|
||||
uint32_t mantissa :DECFLOAT_MANT_WIDTH;
|
||||
uint32_t exponent :DECFLOAT_EXP_WIDTH;
|
||||
} decfloat;
|
||||
|
||||
// this holds all the possible data from a received command
|
||||
|
|
@ -67,9 +74,6 @@ typedef struct {
|
|||
// the command being processed
|
||||
extern GCODE_COMMAND next_target;
|
||||
|
||||
// utility functions
|
||||
int32_t decfloat_to_int(decfloat *df, int32_t multiplicand, int32_t denominator);
|
||||
|
||||
// accept the next character and process it
|
||||
void gcode_parse_char(uint8_t c);
|
||||
|
||||
|
|
|
|||
72
sermsg.c
72
sermsg.c
|
|
@ -25,72 +25,22 @@ void serwrite_hex32(uint32_t v) {
|
|||
serwrite_hex8(v & 0xFFFF);
|
||||
}
|
||||
|
||||
const uint32_t powers[] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000};
|
||||
|
||||
void serwrite_uint32(uint32_t v) {
|
||||
uint8_t t = 0;
|
||||
if (v >= 1000000000) {
|
||||
for (t = 0; v >= 1000000000; v -= 1000000000, t++);
|
||||
serial_writechar(t + '0');
|
||||
uint8_t e, t;
|
||||
|
||||
for (e = 9; e > 0; e--) {
|
||||
if (v >= powers[e])
|
||||
break;
|
||||
}
|
||||
|
||||
if (v >= 100000000) {
|
||||
for (t = 0; v >= 100000000; v -= 100000000, t++);
|
||||
do
|
||||
{
|
||||
for (t = 0; v >= powers[e]; v -= powers[e], t++);
|
||||
serial_writechar(t + '0');
|
||||
}
|
||||
else if (t != 0)
|
||||
serial_writechar('0');
|
||||
|
||||
if (v >= 10000000) {
|
||||
for (t = 0; v >= 10000000; v -= 10000000, t++);
|
||||
serial_writechar(t + '0');
|
||||
}
|
||||
else if (t != 0)
|
||||
serial_writechar('0');
|
||||
|
||||
if (v >= 1000000) {
|
||||
for (t = 0; v >= 1000000; v -= 1000000, t++);
|
||||
serial_writechar(t + '0');
|
||||
}
|
||||
else if (t != 0)
|
||||
serial_writechar('0');
|
||||
|
||||
if (v >= 100000) {
|
||||
for (t = 0; v >= 100000; v -= 100000, t++);
|
||||
serial_writechar(t + '0');
|
||||
}
|
||||
else if (t != 0)
|
||||
serial_writechar('0');
|
||||
|
||||
if (v >= 10000) {
|
||||
for (t = 0; v >= 10000; v -= 10000, t++);
|
||||
serial_writechar(t + '0');
|
||||
}
|
||||
else if (t != 0)
|
||||
serial_writechar('0');
|
||||
|
||||
if (v >= 1000) {
|
||||
for (t = 0; v >= 1000; v -= 1000, t++);
|
||||
serial_writechar(t + '0');
|
||||
}
|
||||
else if (t != 0)
|
||||
serial_writechar('0');
|
||||
|
||||
if (v >= 100) {
|
||||
t = v / 100;
|
||||
serial_writechar(t + '0');
|
||||
v -= (t * 100);
|
||||
}
|
||||
else if (t != 0)
|
||||
serial_writechar('0');
|
||||
|
||||
if (v >= 10) {
|
||||
t = v / 10;
|
||||
serial_writechar(t + '0');
|
||||
v -= (t * 10);
|
||||
}
|
||||
else if (t != 0)
|
||||
serial_writechar('0');
|
||||
|
||||
serial_writechar(v + '0');
|
||||
while (e--);
|
||||
}
|
||||
|
||||
void serwrite_int32(int32_t v) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue