add expr_eng4() operator in addition to expr_eng() that returns 4 significant digits instead of 5

This commit is contained in:
stefan schippers 2026-01-27 17:19:07 +01:00
parent 0c25490c9d
commit fc5c5b97fe
6 changed files with 45 additions and 31 deletions

View File

@ -482,12 +482,12 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
if(gr->unitx != 1.0)
my_snprintf(sx, S(sx), "%.5g%c", gr->unitx * xval, gr->unitx_suffix);
else
my_strncpy(sx, dtoa_eng(xval), S(sx));
my_strncpy(sx, dtoa_eng(xval, 5), S(sx));
if(gr->unitx != 1.0)
my_snprintf(sy, S(sy), "%.4g%c", gr->unity * yval, gr->unity_suffix);
else
my_strncpy(sy, dtoa_eng(yval), S(sy));
my_strncpy(sy, dtoa_eng(yval, 5), S(sy));
tclvareval("set measure_text \"y=", sy, "\nx=", sx, "\"", NULL);
tcleval("graph_show_measure");
@ -650,7 +650,7 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
logcursor = mylog10(cursor);
}
if(fabs(xctx->mousex - W_X(logcursor)) < 10) {
tclvareval("input_line {Pos:} {} ", dtoa_eng(cursor), NULL);
tclvareval("input_line {Pos:} {} ", dtoa_eng(cursor, 5), NULL);
cursor = atof_eng(tclresult());
if(r->flags & 4) {
my_strdup(_ALLOC_ID_, &r->prop_ptr, subst_token(r->prop_ptr, "cursor1_x", dtoa(cursor)));
@ -680,7 +680,7 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
logcursor = mylog10(cursor);
}
if(fabs(xctx->mousex - W_X(logcursor)) < 10) {
tclvareval("input_line {Pos:} {} ", dtoa_eng(cursor), NULL);
tclvareval("input_line {Pos:} {} ", dtoa_eng(cursor, 5), NULL);
cursor = atof_eng(tclresult());
if(r->flags & 4) {
my_strdup(_ALLOC_ID_, &r->prop_ptr, subst_token(r->prop_ptr, "cursor2_x", dtoa(cursor)));
@ -705,7 +705,7 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
logcursor = mylog10(cursor);
}
if(fabs(xctx->mousey - W_Y(logcursor)) < 10) {
tclvareval("input_line {Pos:} {} ", dtoa_eng(cursor), NULL);
tclvareval("input_line {Pos:} {} ", dtoa_eng(cursor, 5), NULL);
cursor = atof_eng(tclresult());
my_strdup(_ALLOC_ID_, &r->prop_ptr, subst_token(r->prop_ptr, "hcursor1_y", dtoa(cursor)));
event = 0; button = 0; /* avoid further processing ButtonPress that might set GRAPHPAN */
@ -720,7 +720,7 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int
logcursor = mylog10(cursor);
}
if(fabs(xctx->mousey - W_Y(logcursor)) < 10) {
tclvareval("input_line {Pos:} {} ", dtoa_eng(cursor), NULL);
tclvareval("input_line {Pos:} {} ", dtoa_eng(cursor, 5), NULL);
cursor = atof_eng(tclresult());
my_strdup(_ALLOC_ID_, &r->prop_ptr, subst_token(r->prop_ptr, "hcursor2_y", dtoa(cursor)));
event = 0; button = 0; /* avoid further processing ButtonPress that might set GRAPHPAN */

View File

@ -3137,10 +3137,10 @@ static void draw_graph_grid(Graph_ctx *gr, void *ct)
drawline(GRIDLAYER, ADD, W_X(wx), W_Y(gr->gy1), W_X(wx), W_Y(gr->gy1) + mark_size, 0.0, 0, ct); /* axis marks */
/* X-axis labels */
if(gr->logx)
draw_string(3, NOW, dtoa_eng(pow(10, wx) * gr->unitx), 0, 0, 1, 0, W_X(wx),
draw_string(3, NOW, dtoa_eng(pow(10, wx) * gr->unitx, 5), 0, 0, 1, 0, W_X(wx),
gr->y2 + mark_size + 5 * gr->txtsizex, gr->txtsizex, gr->txtsizex);
else
draw_string(3, NOW, dtoa_eng(wx * gr->unitx), 0, 0, 1, 0, W_X(wx), gr->y2 + mark_size + 5 * gr->txtsizex,
draw_string(3, NOW, dtoa_eng(wx * gr->unitx, 5), 0, 0, 1, 0, W_X(wx), gr->y2 + mark_size + 5 * gr->txtsizex,
gr->txtsizex, gr->txtsizex);
}
/* first and last vertical box delimiters */
@ -3169,10 +3169,10 @@ static void draw_graph_grid(Graph_ctx *gr, void *ct)
drawline(GRIDLAYER, ADD, W_X(gr->gx1) - mark_size, W_Y(wy), W_X(gr->gx1), W_Y(wy), 0.0, 0, ct); /* axis marks */
/* Y-axis labels */
if(gr->logy)
draw_string(3, NOW, dtoa_eng(pow(10, wy) * gr->unity), 0, 1, 0, 1,
draw_string(3, NOW, dtoa_eng(pow(10, wy) * gr->unity, 5), 0, 1, 0, 1,
gr->x1 - mark_size - 5 * gr->txtsizey, W_Y(wy), gr->txtsizey, gr->txtsizey);
else
draw_string(3, NOW, dtoa_eng(wy * gr->unity), 0, 1, 0, 1, gr->x1 - mark_size - 5 * gr->txtsizey, W_Y(wy),
draw_string(3, NOW, dtoa_eng(wy * gr->unity, 5), 0, 1, 0, 1, gr->x1 - mark_size - 5 * gr->txtsizey, W_Y(wy),
gr->txtsizey, gr->txtsizey);
}
}
@ -3403,7 +3403,7 @@ static void draw_cursor(double active_cursorx, double other_cursorx, int cursor_
if(gr->unitx != 1.0)
my_snprintf(tmpstr, S(tmpstr), "%.5g%c", gr->unitx * active_cursorx , gr->unitx_suffix);
else
my_snprintf(tmpstr, S(tmpstr), "%s", dtoa_eng(active_cursorx));
my_snprintf(tmpstr, S(tmpstr), "%s", dtoa_eng(active_cursorx, 5));
text_bbox(tmpstr, txtsize, txtsize, 2, flip, 0, 0, xx + xoffs, gr->ry2-1, &tx1, &ty1, &tx2, &ty2, &tmp, &dtmp);
filledrect(0, NOW, tx1, ty1, tx2, ty2, 2, -1, -1);
draw_string(cursor_color, NOW, tmpstr, 2, flip, 0, 0, xx + xoffs, gr->ry2-1, txtsize, txtsize);
@ -3435,7 +3435,7 @@ static void draw_cursor_difference(double c1, double c2, Graph_ctx *gr)
if(gr->unitx != 1.0)
my_snprintf(tmpstr, S(tmpstr), "%.4g%c", gr->unitx * diffw , gr->unitx_suffix);
else
my_snprintf(tmpstr, S(tmpstr), "%s", dtoa_eng(diffw));
my_snprintf(tmpstr, S(tmpstr), "%s", dtoa_eng(diffw, 5));
text_bbox(tmpstr, txtsize, txtsize, 2, 0, 1, 0, xx, yy, &tx1, &ty1, &tx2, &ty2, &tmp, &dtmp);
if( tx2 - tx1 < diff ) {
draw_string(3, NOW, tmpstr, 2, 0, 1, 0, xx, yy, txtsize, txtsize);
@ -3465,7 +3465,7 @@ static void draw_hcursor(double active_cursory, int cursor_color, Graph_ctx *gr)
if(gr->unity != 1.0)
my_snprintf(tmpstr, S(tmpstr), " %.5g%c ", gr->unity * active_cursory , gr->unity_suffix);
else
my_snprintf(tmpstr, S(tmpstr), " %s ", dtoa_eng(active_cursory));
my_snprintf(tmpstr, S(tmpstr), " %s ", dtoa_eng(active_cursory, 5));
text_bbox(tmpstr, txtsize, txtsize, 0, 0, 0, 0, gr->rx1 + 5, yy, &tx1, &ty1, &tx2, &ty2, &tmp, &dtmp);
th = (ty2 - ty1) / 2.; /* half text height */
ty1 -= th;
@ -3499,7 +3499,7 @@ static void draw_hcursor_difference(double c1, double c2, Graph_ctx *gr)
if(gr->unity != 1.0)
my_snprintf(tmpstr, S(tmpstr), " %.4g%c ", gr->unity * diffh , gr->unity_suffix);
else
my_snprintf(tmpstr, S(tmpstr), " %s ", dtoa_eng(diffh));
my_snprintf(tmpstr, S(tmpstr), " %s ", dtoa_eng(diffh, 5));
text_bbox(tmpstr, txtsize, txtsize, 0, 0, 0, 1, xx, yy, &tx1, &ty1, &tx2, &ty2, &tmp, &dtmp);
if( 2 * (ty2 - ty1) < diff ) {
filledrect(0, NOW, tx1, ty1, tx2, ty2, 2, -1, -1);

View File

@ -328,7 +328,6 @@ size_t my_snprintf(char *str, size_t size, const char *fmt, ...)
va_list args;
va_start(args, fmt);
size_of_print = vsnprintf(str, size, fmt, args);
if(has_x && size_of_print >=size) { /* output was truncated */
snprintf(s, S(s), "alert_ { Warning: overflow in my_snprintf print size=%d, buffer size=%d} {}",
size_of_print, size);
@ -583,13 +582,13 @@ char *dtoa(double i)
return s;
}
char *dtoa_eng(double i)
char *dtoa_eng(double i, int precision)
{
static char s[70];
static char s[80];
size_t n;
int suffix = 0;
double absi = fabs(i);
dbg(1, "dtoa_eng(): i=%.17g, absi=%.17g\n", i, absi);
dbg(1, "dtoa_eng(): i=%.17g, absi=%.17g, precision=%d\n", i, absi, precision);
if (absi == 0.0) { suffix = 0 ;}
else if(absi < 0.999999e-23) { i = 0.0 ; suffix = 0 ;}
else if(absi > 0.999999e12) { i /= 1e12; suffix = 'T';}
@ -604,9 +603,10 @@ char *dtoa_eng(double i)
else if(absi > 0.999999e-15) { i *= 1e15; suffix = 'f';}
else { i *= 1e18; suffix = 'a';}
if(suffix) {
n = my_snprintf(s, S(s), "%.5g%c", i, suffix);
/* can not use my_snprintf() here due to indirect precision */
n = sprintf(s, "%.*g%c", precision, i, suffix);
} else {
n = my_snprintf(s, S(s), "%.5g", i);
n = sprintf(s, "%.*g", precision, i);
}
if(xctx) xctx->tok_size = n;
return s;

View File

@ -127,9 +127,9 @@ static void get_char(int c)
static void get_expr(double x)
{
char xx[100];
dbg(dbglev,"get_expr(): x=%g\n", x);
dbg(dbglev,"get_expr(): x=%g, enginenering=%d\n", x, engineering);
if(engineering) {
my_snprintf(xx, S(xx), "%s", dtoa_eng(x));
my_snprintf(xx, S(xx), "%s", dtoa_eng(x, engineering));
} else {
my_snprintf(xx, S(xx), "%.15g", x);
}
@ -157,6 +157,11 @@ static void remove_expr(char *s)
ptr += 9;
plev++;
}
else if(strstr(ptr, "expr_eng4(") == ptr) {
ptr += 10;
plev++;
}
if(*ptr == '(') plev++;
if(*ptr == ')') {
plev--;
@ -242,7 +247,15 @@ static int kklex()
lex_state = 1;
str += 9;
dbg(dbglev, "lex(): EXPR_ENG\n");
engineering = 1;
engineering = 5;
return EXPR;
}
else if(strstr(str, "expr_eng4(") == str) {
lex_state = 1;
str += 10;
dbg(dbglev, "lex(): EXPR_ENG4\n");
engineering = 4;
return EXPR;
}

View File

@ -929,6 +929,7 @@ char *is_expr(const char *str)
if(str) {
ret = strstr(str, "expr(");
if(!ret) ret = strstr(str, "expr_eng(");
if(!ret) ret = strstr(str, "expr_eng4(");
}
return ret;
}
@ -4243,7 +4244,7 @@ static char *get_pin_attr(const char *token, int inst, int engineering)
else if(idx < 0) {
valstr = "-";
} else {
valstr = engineering? dtoa_eng(val) : dtoa(val);
valstr = engineering? dtoa_eng(val, 5) : dtoa(val);
}
my_strdup2(_ALLOC_ID_, &pin_attr_value, valstr);
dbg(1, "inst %d, net=%s, fqnet=%s idx=%d valstr=%s\n", inst, net, fqnet, idx, valstr);
@ -4357,7 +4358,7 @@ const char *spice_get_node(const char *token)
} else {
/* always use engineering as these tokens are generated from single
* @spice_get_node(...) patterns */
valstr = dtoa_eng(val);
valstr = dtoa_eng(val, 5);
}
dbg(1, "valstr=%s\n", valstr);
my_strdup2(_ALLOC_ID_, &token2, str_replace(token, "@spice_get_node ", "", 0, 1));
@ -4736,7 +4737,7 @@ const char *translate(int inst, const char* s)
xctx->tok_size = 5;
len = 5;
} else {
valstr = engineering ? dtoa_eng(val) : dtoa(val);
valstr = engineering ? dtoa_eng(val, 5) : dtoa(val);
len = xctx->tok_size;
}
if(len) {
@ -4837,7 +4838,7 @@ const char *translate(int inst, const char* s)
} else {
/* always use engineering as these tokens are generated from single
* @spice_get_voltage patterns */
valstr = dtoa_eng(val);
valstr = dtoa_eng(val, 5);
len = xctx->tok_size;
}
if(len) {
@ -4938,7 +4939,7 @@ const char *translate(int inst, const char* s)
} else {
/* always use engineering as these tokens are generated from single
* @spice_get_voltage patterns */
valstr = dtoa_eng(val);
valstr = dtoa_eng(val, 5);
len = xctx->tok_size;
}
if(len) {
@ -5004,7 +5005,7 @@ const char *translate(int inst, const char* s)
double val1 = gnd1 ? 0.0 : xctx->raw->cursor_b_val[idx1];
double val2 = gnd2 ? 0.0 : xctx->raw->cursor_b_val[idx2];
val = val1 - val2;
valstr = engineering ? dtoa_eng(val) : dtoa(val);
valstr = engineering ? dtoa_eng(val, 5) : dtoa(val);
len = xctx->tok_size;
}
if(len) {
@ -5137,7 +5138,7 @@ const char *translate(int inst, const char* s)
xctx->tok_size = 1;
len = 1;
} else {
valstr = engineering ? dtoa_eng(val) : dtoa(val);
valstr = engineering ? dtoa_eng(val, 5) : dtoa(val);
len = xctx->tok_size;
}
if(len) {

View File

@ -1701,7 +1701,7 @@ extern char *my_itoa(int i);
extern double atof_spice(const char *s);
extern double atof_eng(const char *s); /* same as atof_spice, but recognizes 'M' as Mega and 'm' as Milli */
extern char *dtoa(double i);
extern char *dtoa_eng(double i);
extern char *dtoa_eng(double i, int precision);
extern char *dtoa_prec(double i);
extern double my_round(double a);
extern double round_to_n_digits(double x, int n);