diff --git a/src/misc/Makefile.am b/src/misc/Makefile.am index d20d905ae..b6d7b1e5f 100644 --- a/src/misc/Makefile.am +++ b/src/misc/Makefile.am @@ -10,6 +10,7 @@ libmisc_la_SOURCES = \ dup2.c \ dstring.c \ dup2.h \ + engnotation.c \ hash.c \ ivars.c \ ivars.h \ diff --git a/src/misc/engnotation.c b/src/misc/engnotation.c new file mode 100644 index 000000000..78fdb5b01 --- /dev/null +++ b/src/misc/engnotation.c @@ -0,0 +1,71 @@ +/* Print a floating-point number in engineering notation. + Documentation: http://www.cs.tut.fi/~jkorpela/c/eng.html + BSD-style license */ + +#define PREFIX_START (-24) +/* Smallest power of ten for which there is a prefix defined. + If the set of prefixes will be extended, change this constant + and update the table "prefix". */ + +#include +#include +#include "ngspice/ngspice.h" + +/* Print a floating-point number in engineering notation. + Return string needs to be freed by the caller after its use. + numeric selects e3, e6, e9 etc. or k, M, G etc. */ +char *eng(double value, int digits, int numeric) +{ + static char *prefix[] = { + "y", "z", "a", "f", "p", "n", "u", "m", "", + "k", "M", "G", "T", "P", "E", "Z", "Y" + }; +#define PREFIX_END (PREFIX_START+\ +(int)((sizeof(prefix)/sizeof(char *)-1)*3)) + + double display, fract; + int expof10; + char *result, *sign; + + if(value < 0.0) { + sign = "-"; + value = -value; + } else { + sign = ""; + } + + // correctly round to desired precision + expof10 = lrint( floor( log10(value) ) ); + value *= pow(10.0, digits - 1 - expof10); + + fract = modf(value, &display); + if(fract >= 0.5) display += 1.0; + + value = display * pow(10.0, expof10 - digits + 1); + + + if(expof10 > 0) + expof10 = (expof10/3)*3; + else + expof10 = ((-expof10+3)/3)*(-3); + + value *= pow(10.0, -expof10); + if (value >= 1000.0) { + value /= 1000.0; + expof10 += 3; + } + else if(value >= 100.0) + digits -= 2; + else if(value >= 10.0) + digits -= 1; + + if(numeric || (expof10 < PREFIX_START) || (expof10 > PREFIX_END)) + if (expof10 == 0) + result = tprintf("%s%.*f", sign, digits-1, value); + else + result = tprintf("%s%.*fe%d", sign, digits-1, value, expof10); + else + result = tprintf("%s%.*f %s", sign, digits-1, value, prefix[(expof10-PREFIX_START)/3]); + + return result; +} diff --git a/src/spicelib/analysis/dcpss.c b/src/spicelib/analysis/dcpss.c index 07dbb3056..037458859 100644 --- a/src/spicelib/analysis/dcpss.c +++ b/src/spicelib/analysis/dcpss.c @@ -24,6 +24,8 @@ /* gtri - end - wbk - Add headers */ #endif +extern char* eng(double value, int digits, int numeric); + #define INIT_STATS() \ do { \ startTime = SPfrontEnd->IFseconds(); \ @@ -625,6 +627,8 @@ DCpss(CKTcircuit *ckt, /* If evolution is near shooting... */ if ((AlmostEqualUlps (ckt->CKTtime, time_temp + 1 / ckt->CKTguessedFreq, 10)) || (ckt->CKTtime > time_temp + 1 / ckt->CKTguessedFreq)) { + char* freq = NULL; + int excessive_err_nodes = 0 ; /* Calculation of error norms of RHS solution of every accepted nextTime */ @@ -798,8 +802,9 @@ DCpss(CKTcircuit *ckt, rr_history [shooting_cycle_counter] = err ; gf_history [shooting_cycle_counter] = ckt->CKTguessedFreq ; shooting_cycle_counter++ ; - - fprintf (stdout, "Updated guessed frequency: %1.10lg .\n", ckt->CKTguessedFreq) ; + freq = eng(ckt->CKTguessedFreq, 10, 1); + fprintf (stdout, "Updated guessed frequency: %s Hz.\n", freq) ; + tfree(freq); fprintf (stdout, "Next shooting evaluation time is %1.10g and current time is %1.10g.\n", time_temp + 1 / ckt->CKTguessedFreq, ckt->CKTtime) ; @@ -835,8 +840,7 @@ shootingexit: if ((shooting_cycle_counter > ckt->CKTsc_iter) || (excessive_err_nodes == 0)) { int k ; - double minimum ; - + double minimum; pss_state = PSS ; #ifdef PSSDEBUG @@ -880,10 +884,12 @@ shootingexit: pss_points_cycle++ ; CKTsetBreak (ckt, time_temp + (1 / ckt->CKTguessedFreq) * ((double)pss_points_cycle / (double)ckt->CKTpsspoints)) ; + freq = eng(ckt->CKTguessedFreq, 10, 1); /* engineering notation */ if (excessive_err_nodes == 0) - fprintf (stdout, "\nConvergence reached. Final circuit time is %1.10g seconds (iteration n° %d) and predicted fundamental frequency is %15.10g Hz\n", ckt->CKTtime, shooting_cycle_counter - 1, ckt->CKTguessedFreq) ; + fprintf (stdout, "\nConvergence reached. Final circuit time is %1.10g seconds (iteration n° %d) and predicted fundamental frequency is %s Hz\n", ckt->CKTtime, shooting_cycle_counter - 1, freq) ; else - fprintf (stdout, "\nConvergence not reached. However the most near convergence iteration has predicted (iteration %d) a fundamental frequency of %15.10g Hz\n", k, ckt->CKTguessedFreq) ; + fprintf (stdout, "\nConvergence not reached. However the most near convergence iteration has predicted (iteration %d) a fundamental frequency of %s Hz\n", k, freq) ; + tfree(freq); #ifdef PSSDEBUG fprintf (stderr, "time_temp %g\n", time_temp) ; diff --git a/visualc/sharedspice.vcxproj b/visualc/sharedspice.vcxproj index 34eb25343..b7d9d1e81 100644 --- a/visualc/sharedspice.vcxproj +++ b/visualc/sharedspice.vcxproj @@ -1454,6 +1454,7 @@ lib /machine:x64 /def:..\..\fftw-3.3-dll64\libfftw3-3.def /out:$(IntDir)libfftw3 + diff --git a/visualc/vngspice-fftw.vcxproj b/visualc/vngspice-fftw.vcxproj index a83f0d244..32095d9c1 100644 --- a/visualc/vngspice-fftw.vcxproj +++ b/visualc/vngspice-fftw.vcxproj @@ -1675,6 +1675,7 @@ lib /machine:x64 /def:..\..\fftw-3.3-dll64\libfftw3-3.def /out:$(IntDir)libfftw3 + diff --git a/visualc/vngspice.vcxproj b/visualc/vngspice.vcxproj index 0f8adb416..94de43637 100644 --- a/visualc/vngspice.vcxproj +++ b/visualc/vngspice.vcxproj @@ -1690,6 +1690,7 @@ +