[En-Nut-Discussion] NutGetTickClock rounding (again)

Henrik Maier hmlists at focus-sw.com
Wed Jul 16 09:37:09 CEST 2008


After putting more thought into that, I realised that the rounding-up method
is only suitable for the case where NutGetTickClock is <= 1000. For the case
NutGetTickClock > 1000 we would need a different handling and have to round
down. This would make the function more complex as we have to handle the two
cases. The Linux kernel code covers that nicely and efficiently with
conditional compilation.

The previously proposed arithmetic rounding method did not require two cases
and I don't consider it that bad after all as NutGetTickClock is actually
constant and we can assume that it is always close to 1000 or multiples of
it. So I think your argument that arithmetic rounding will be wrong 50% of
the time does not apply to this use case.

The following table illustrates the error for the arithmetic rounding method
and the current truncation method for NutGetTickClock of 997 and 1003:

Arithmetic Rounding (+0.5)				
				
ms	997	Error		1003	Error
1	1	-0.30%		1	0.30%
2	2	-0.30%		2	0.30%
5	5	-0.30%		5	0.30%
10	10	-0.30%		10	0.30%
50	50	-0.30%		50	0.30%
100	100	-0.30%		100	0.30%
1000	997	0.00%		1003	0.00%
				
				
Truncation (current implementation)				
				
ms	997	Error		1003	Error
1	0	100.00%	1	0.30%
2	1	49.85%		2	0.30%
5	4	19.76%		5	0.30%
10	9	9.73%		10	0.30%
50	49	1.71%		50	0.30%
100	99	0.70%		100	0.30%
1000	997	0.00%		1003	0.00%

Henrik

> -----Original Message-----
> From: Henrik Maier [mailto:hmlists at focus-sw.com]
> Sent: Wednesday, 16 July 2008 4:23 PM
> To: 'ethernut at duaneellis.com'; 'Ethernut User Chat (English)'
> Subject: RE: [En-Nut-Discussion] NutGetTickClock rounding (again)
> 
> > NO - i disagree.  I would call this *WRONG*  You are doing 'traditional
> > rounding' at the 0.5 point. While mathematically that seems correct (ie:
> > rounding money). Most developers Timeouts will be wrong 50% of the time.
> 
> Duane,
> 
> You are right it is more accurate for timing purposes not to use
> traditional arithmetic rounding. Also my code broke when Nut/OS changed
the
> NutTimerMillisToTicks implementation from 4.2.1 to 4.4.1 because time-outs
> were suddenly too short not because they were too long.
> 
> Thank you for the very good explanation and constructive contribution. I
> had another close look at the Linux kernel code and they are also using
the
> 'rounding-up' method:
> 
>    (m * HZ + MSEC_PER_SEC - 1) / MSEC_PER_SEC.
> 
> In our case HZ is NutGetTickClock and MSEC_PER_SEC is 1000.
> 
> So the rounding should then be done this way I suppose:
> 
> ---------------------------------------------------
>  u_long NutTimerMillisToTicks(u_long ms)
>  {
>     if (ms >= 0x3E8000UL)
>        return (ms / 1000UL) * NutGetTickClock();
>     else
>        return (ms * NutGetTickClock() + (1000UL - 1UL)) / 1000UL;
>  }
> -----------------------------------------------------
> 
> Henrik





More information about the En-Nut-Discussion mailing list