Better calcuation of dec string width (Larry Doolittle)
This commit is contained in:
parent
fcf64c0c38
commit
4f28f6a770
|
|
@ -17,7 +17,7 @@
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
#if !defined(WINNT) && !defined(macintosh)
|
#if !defined(WINNT) && !defined(macintosh)
|
||||||
#ident "$Id: sys_display.c,v 1.33 2002/01/15 03:23:34 steve Exp $"
|
#ident "$Id: sys_display.c,v 1.34 2002/01/22 00:18:10 steve Exp $"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
|
|
@ -36,13 +36,43 @@ struct strobe_cb_info {
|
||||||
unsigned nitems;
|
unsigned nitems;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int calc_dec_size(int nr_bits)
|
// The number of decimal digits needed to represent a
|
||||||
|
// nr_bits binary number is floor(nr_bits*log_10(2))+1,
|
||||||
|
// where log_10(2) = 0.30102999566398.... and I approximate
|
||||||
|
// this transcendental number as 146/485, to avoid the vagaries
|
||||||
|
// of floating-point. The smallest nr_bits for which this
|
||||||
|
// approximation fails is 2621,
|
||||||
|
// 2621*log_10(2)=789.9996, but (2621*146+484)/485=790 (exactly).
|
||||||
|
// In cases like this, all that happens is we allocate one
|
||||||
|
// unneeded char for the output. I add a "L" suffix to 146
|
||||||
|
// to make sure the computation is done as long ints, otherwise
|
||||||
|
// on a 16-bit int machine (allowed by ISO C) we would mangle
|
||||||
|
// this computation for bit-length of 224. I'd like to put
|
||||||
|
// in a test for nr_bits < LONG_MAX/146, but don't know how
|
||||||
|
// to fail, other than crashing.
|
||||||
|
//
|
||||||
|
// In an April 2000 thread in comp.unix.programmer, with subject
|
||||||
|
// "integer -> string", I <LRDoolittle@lbl.gov> give the 28/93
|
||||||
|
// approximation, but overstate its accuracy: that version first
|
||||||
|
// fails when the number of bits is 289, not 671.
|
||||||
|
//
|
||||||
|
// This result does not include space for a trailing '\0', if any.
|
||||||
|
//
|
||||||
|
inline static int calc_dec_size(int nr_bits, int is_signed)
|
||||||
{
|
{
|
||||||
// over-the-top accuracy... :-)
|
int r;
|
||||||
//
|
if (is_signed) --nr_bits;
|
||||||
// nr of bits = floor(log10(2^nr_bits) + 1.0)
|
r = (nr_bits * 146L + 484) / 485;
|
||||||
// = floor(nr_bits * ln(2)/ln(10) + 1.0)
|
if (is_signed) ++r;
|
||||||
return (int)( ((double)nr_bits) * 0.301029996 + 1.0);
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vpi_get_dec_size(vpiHandle item)
|
||||||
|
{
|
||||||
|
return calc_dec_size(
|
||||||
|
vpi_get(vpiSize, item),
|
||||||
|
vpi_get(vpiSigned, item)==1
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void array_from_iterator(struct strobe_cb_info*info, vpiHandle argv)
|
static void array_from_iterator(struct strobe_cb_info*info, vpiHandle argv)
|
||||||
|
|
@ -271,14 +301,7 @@ static int format_str(vpiHandle scope, unsigned int mcd,
|
||||||
// simple %d parameter.
|
// simple %d parameter.
|
||||||
// Size is now determined by the width
|
// Size is now determined by the width
|
||||||
// of the vector or integer
|
// of the vector or integer
|
||||||
fsize = vpi_get(vpiSize, argv[idx]);
|
fsize = vpi_get_dec_size(argv[idx]);
|
||||||
fsize = calc_dec_size(fsize);
|
|
||||||
|
|
||||||
if ( vpi_get(vpiSigned, argv[idx]) ==1){
|
|
||||||
// Pure integers need one more position
|
|
||||||
// for an optional '-' bit
|
|
||||||
fsize++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vpi_mcd_printf(mcd, "%*s", fsize,
|
vpi_mcd_printf(mcd, "%*s", fsize,
|
||||||
|
|
@ -423,11 +446,7 @@ static void do_display(unsigned int mcd, struct strobe_cb_info*info)
|
||||||
|
|
||||||
switch(info->default_format){
|
switch(info->default_format){
|
||||||
case vpiDecStrVal:
|
case vpiDecStrVal:
|
||||||
size = vpi_get(vpiSize, item);
|
size = vpi_get_dec_size(item);
|
||||||
size = calc_dec_size(size);
|
|
||||||
if ( vpi_get(vpiSigned, item) ==1){
|
|
||||||
size++;
|
|
||||||
}
|
|
||||||
vpi_mcd_printf(mcd, "%*s", size, value.value.str);
|
vpi_mcd_printf(mcd, "%*s", size, value.value.str);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -1102,6 +1121,9 @@ void sys_display_register()
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* $Log: sys_display.c,v $
|
* $Log: sys_display.c,v $
|
||||||
|
* Revision 1.34 2002/01/22 00:18:10 steve
|
||||||
|
* Better calcuation of dec string width (Larry Doolittle)
|
||||||
|
*
|
||||||
* Revision 1.33 2002/01/15 03:23:34 steve
|
* Revision 1.33 2002/01/15 03:23:34 steve
|
||||||
* Default widths pad out as per the standard,
|
* Default widths pad out as per the standard,
|
||||||
* add $displayb/o/h et al., and some better
|
* add $displayb/o/h et al., and some better
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue