From: <ai...@us...> - 2009-02-28 03:11:56
|
Revision: 9641 http://plplot.svn.sourceforge.net/plplot/?rev=9641&view=rev Author: airwin Date: 2009-02-28 03:11:55 +0000 (Sat, 28 Feb 2009) Log Message: ----------- Apply Tony Allen's patch to properly normalize strfMJD results using pre-rounding. The implementation uses the most lightly rounded seconds value in the format string to set the degree of rounding used. This change should yield proper normalization of the strfMJD formatted results in all cases. To give an example, that is tested with Test 05 of qsastime_testlib, if H:M:S = 0:59:59.99999999000, internally, that will format as a properly normalized 1:00:00.0000 if sufficient rounding (e.g., %S%4 which corresponds to rounding errors of 50 ms) is used, and will format as a properly normalized 0:59:59.999999990 if light rounding (e.g., %S%9 which corresponds to rounding errors of 0.5 ns) is used. In the latter case, just like in any floating-point calculation, reducing the rounding means you will see more details, but those details potentially include numerical errors. Modified Paths: -------------- trunk/lib/qsastime/qsastime.c Modified: trunk/lib/qsastime/qsastime.c =================================================================== --- trunk/lib/qsastime/qsastime.c 2009-02-28 02:38:37 UTC (rev 9640) +++ trunk/lib/qsastime/qsastime.c 2009-02-28 03:11:55 UTC (rev 9641) @@ -325,6 +325,8 @@ int y1, ifleapyear; int i, count,secsSince1970; int nplaces,fmtlen,slen; + int resolution; + double shiftPlaces; char * ptr; double sec, sec_fraction; int w,doy,days_in_wk1; @@ -334,10 +336,41 @@ size_t posn = 0; size_t last = len -1; MJDtime nMJD, *pnMJD=&nMJD; + MJDtime roundMJD; char dynamic_format[10]; - normalize_MJD(pnMJD, MJD); + /* Find required resolution */ + resolution = 0; + fmtlen = strlen(format); + i=0; + while(i<fmtlen) + { + char next = format[i]; + if( next == '%') + { + /* find seconds format if used */ + i++; + next = format[i]; + if( isdigit(next) != 0 ) + { + nplaces = strtol(&(format[i]), NULL, 10); + if(nplaces > resolution) resolution = nplaces; + } + else if( next == '.' ) + { + resolution = 9; /* maximum resolution allowed */ + } + } + i++; + } + /* ensure rounding is done before breakdown */ + shiftPlaces = pow(10,(double)resolution); + roundMJD = *MJD; + roundMJD.time_sec += 0.5/shiftPlaces; + + normalize_MJD(pnMJD, &roundMJD); + buf[last] = '\0'; buf[0] = '\0'; /* force overwrite of old buffer since strnctat() used hereafter */ @@ -349,10 +382,11 @@ } else ysign = 0; + /*truncate seconds to resolution to stop formatting rounding up */ + sec = floor(sec *shiftPlaces) / shiftPlaces; second = (int) sec; /* Read format string, character at a time */ - fmtlen = strlen(format); i=0; while(i<fmtlen) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |