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.
|
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_X ((uint32_t) ((STEPS_PER_MM_X * 1000.0) + 0.5))
|
||||||
#define STEPS_PER_M_Y ((uint32_t) (STEPS_PER_MM_Y * 1000.0))
|
#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))
|
#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))
|
#define STEPS_PER_M_E ((uint32_t) ((STEPS_PER_MM_E * 1000.0) + 0.5))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
mm -> inch conversion
|
mm -> inch conversion
|
||||||
|
|
@ -50,8 +50,10 @@ GCODE_COMMAND next_target __attribute__ ((__section__ (".bss")));
|
||||||
/*
|
/*
|
||||||
utility functions
|
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;
|
int32_t r = df->mantissa;
|
||||||
uint8_t e = df->exponent;
|
uint8_t e = df->exponent;
|
||||||
|
|
||||||
|
|
@ -59,36 +61,21 @@ int32_t decfloat_to_int(decfloat *df, int32_t multiplicand, int32_t denominator)
|
||||||
if (e)
|
if (e)
|
||||||
e--;
|
e--;
|
||||||
|
|
||||||
// scale factors
|
|
||||||
// if (multiplicand != 1)
|
|
||||||
// r *= multiplicand;
|
|
||||||
// if (denominator != 1)
|
|
||||||
// r /= denominator;
|
|
||||||
|
|
||||||
int32_t rnew1 = r * (multiplicand / denominator);
|
int32_t rnew1 = r * (multiplicand / denominator);
|
||||||
int32_t rnew2 = r * (multiplicand % denominator) / denominator;
|
if (e)
|
||||||
r = rnew1 + rnew2;
|
{
|
||||||
|
int32_t rnew2 = r * (multiplicand % denominator) / denominator;
|
||||||
|
r = rnew1 + rnew2;
|
||||||
|
|
||||||
// sign
|
r = (r + rounding[e]) / powers[e];
|
||||||
if (df->sign)
|
}
|
||||||
r = -r;
|
else
|
||||||
|
{
|
||||||
// exponent- try to keep divides to a minimum for common (small) values at expense of slightly more code
|
int32_t rnew2 = (r * (multiplicand % denominator) + (denominator / 2)) / denominator;
|
||||||
while (e >= 5) {
|
r = rnew1 + rnew2;
|
||||||
r /= 100000;
|
|
||||||
e -= 5;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e == 1)
|
return df->sign ? -r : r;
|
||||||
r /= 10;
|
|
||||||
else if (e == 2)
|
|
||||||
r /= 100;
|
|
||||||
else if (e == 3)
|
|
||||||
r /= 1000;
|
|
||||||
else if (e == 4)
|
|
||||||
r /= 10000;
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
|
@ -292,10 +279,11 @@ void gcode_parse_char(uint8_t c) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
default:
|
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
|
// can't do ranges in switch..case, so process actual digits here.
|
||||||
if (c >= '0' && c <= '9' &&
|
if ( c >= '0'
|
||||||
((next_target.option_inches == 0 && read_digit.exponent < 4) ||
|
&& c <= '9'
|
||||||
(next_target.option_inches && read_digit.exponent < 5))) {
|
&& read_digit.mantissa < (DECFLOAT_MANT_MAX / 10)
|
||||||
|
&& read_digit.exponent < DECFLOAT_EXP_MAX ) {
|
||||||
// this is simply mantissa = (mantissa * 10) + atoi(c) in different clothes
|
// this is simply mantissa = (mantissa * 10) + atoi(c) in different clothes
|
||||||
read_digit.mantissa = (read_digit.mantissa << 3) + (read_digit.mantissa << 1) + (c - '0');
|
read_digit.mantissa = (read_digit.mantissa << 3) + (read_digit.mantissa << 1) + (c - '0');
|
||||||
if (read_digit.exponent)
|
if (read_digit.exponent)
|
||||||
|
|
|
||||||
|
|
@ -16,11 +16,18 @@
|
||||||
// wether to insist on a checksum
|
// wether to insist on a checksum
|
||||||
//#define REQUIRE_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 {
|
typedef struct {
|
||||||
uint32_t sign :1;
|
uint32_t sign :1;
|
||||||
uint32_t mantissa :24;
|
uint32_t mantissa :DECFLOAT_MANT_WIDTH;
|
||||||
uint32_t exponent :7;
|
uint32_t exponent :DECFLOAT_EXP_WIDTH;
|
||||||
} decfloat;
|
} decfloat;
|
||||||
|
|
||||||
// this holds all the possible data from a received command
|
// this holds all the possible data from a received command
|
||||||
|
|
@ -67,9 +74,6 @@ typedef struct {
|
||||||
// the command being processed
|
// the command being processed
|
||||||
extern GCODE_COMMAND next_target;
|
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
|
// accept the next character and process it
|
||||||
void gcode_parse_char(uint8_t c);
|
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);
|
serwrite_hex8(v & 0xFFFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const uint32_t powers[] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000};
|
||||||
|
|
||||||
void serwrite_uint32(uint32_t v) {
|
void serwrite_uint32(uint32_t v) {
|
||||||
uint8_t t = 0;
|
uint8_t e, t;
|
||||||
if (v >= 1000000000) {
|
|
||||||
for (t = 0; v >= 1000000000; v -= 1000000000, t++);
|
for (e = 9; e > 0; e--) {
|
||||||
serial_writechar(t + '0');
|
if (v >= powers[e])
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (v >= 100000000) {
|
do
|
||||||
for (t = 0; v >= 100000000; v -= 100000000, t++);
|
{
|
||||||
|
for (t = 0; v >= powers[e]; v -= powers[e], t++);
|
||||||
serial_writechar(t + '0');
|
serial_writechar(t + '0');
|
||||||
}
|
}
|
||||||
else if (t != 0)
|
while (e--);
|
||||||
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');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void serwrite_int32(int32_t v) {
|
void serwrite_int32(int32_t v) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue