[M3devel] ROUND vs. FLOOR in ThreadPThread.m3 nano vs. micro time conversions?
Jay K
jay.krell at cornell.edu
Sat Apr 17 06:26:59 CEST 2010
I've gone ahead and "rewritten" this code (it's only a few lines), and I removed this distinction.
New form uses modf to split floating point at the decimal point and then multiplies the fractional part by a million (struct timeval) or a billion (struct timespec). Should be equivalent to
seconds = (int)floatseconds;
microsseconds = (floatseconds - seconds) * billion or million
or such
I ended up not using the C99 stuff.
Sometimes we know the time is less than a second and greater than 0 and so just pass around a microsecond or nanosecond count.
Hm. Maybe it has to do with negative times? Rounding down vs. toward zero?
I'll probably rereread the code with negative times in mind.
Not too worried, as the select uses in the thread code doesn't pass negative times, gettimeofday can't return a negative time, the user thread scheduling intervals I believe are all positive, etc.
- Jay
From: jay.krell at cornell.edu
To: m3devel at elegosoft.com
Subject: ROUND vs. FLOOR in ThreadPThread.m3 nano vs. micro time conversions?
Date: Fri, 9 Apr 2010 10:52:09 +0000
Why does UTimeFromTime use FLOOR but ToNTime uses ROUND?
PROCEDURE ToNTime (n: LONGREAL; VAR ts: Utime.struct_timespec) =
BEGIN
ts.tv_sec := TRUNC(n);
ts.tv_nsec := ROUND((n - FLOAT(ts.tv_sec, LONGREAL)) * 1.0D9);
END ToNTime;
TYPE UTime = Utime.struct_timeval;
PROCEDURE UTimeFromTime (time: Time.T): UTime =
VAR floor := FLOOR(time);
BEGIN
RETURN UTime{floor, FLOOR(1.0D6 * (time - FLOAT(floor, LONGREAL)))};
END UTimeFromTime;
I've changed this code to pass doubles to C and do the conversion
there. To reduce/eliminate use of cloned headers.
For ROUND I'm using C99:
/* C99, very portable */
long lround(double);
long long llround(double);
#ifdef __CYGWIN__
#define ROUND lround
#else
#define ROUND llround
#endif
typedef double FloatSeconds, LONGREAL;
typedef struct timeval MicrosecondsStruct_t;
#define FLOAT(value, type) ((type)value)
#define FLOOR floor
static
MicrosecondsStruct_t*
FloatSecondsToNanosecondsStruct(LONGREAL n,
MicrosecondsStruct_t* ts)
{
ts->tv_sec = (time_t)n;
ts->tv_nsec = ROUND((n - FLOAT(ts->tv_sec, LONGREAL)) * 1.0E9);
return ts;
}
static
MicrosecondsStruct_t*
FloatSecondsToMicrosecondsStruct(FloatSeconds timeout,
MicrosecondsStruct_t* utime)
{
LONGINT sec = FLOOR(timeout);
utime->tv_sec = (time_t)sec;
utime->tv_usec = (suseconds_t)FLOOR(1.0E6 * (timeout - FLOAT(sec, LONGREAL)));
return utime;
}
Just arbitrarily a little more correct in the nano case vs. the micro case?
Matters little? Would matter more for micro due to lower resolution?
Thanks,
- Jay
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://m3lists.elegosoft.com/pipermail/m3devel/attachments/20100417/27162994/attachment-0002.html>
More information about the M3devel
mailing list