public inbox for ecos-discuss@sourceware.org
 help / color / mirror / Atom feed
From: Hugo Tyson <hmt@redhat.com>
To: jlarmour@redhat.com
Cc: borg@int.spb.ru, ecos-discuss@sourceware.cygnus.com, hmt@redhat.com
Subject: Re: [ECOS] cyg_ticks_to_timespec()
Date: Thu, 19 Apr 2001 03:11:00 -0000	[thread overview]
Message-ID: <200104191010.f3JAAdn10455@masala.cambridge.redhat.com> (raw)
In-Reply-To: <3ADDEE7C.4D31174C@redhat.com>

> From: Jonathan Larmour <jlarmour@redhat.com>

> > For example: for ticks=454 the function should calculate tv_sec=4
> > tv_nsec=0.54e9,
> > but it calculate  tv_sec=5  tv_nsec=3834967296.
> 
> You're right. Out of interest, if you interpret tv_nsec as a signed rather
> than unsigned long it comes out as -460000000 which is a more interesting
> value. i.e. it is negative.

In other words, 5S + -460,000,000nS = 4.54S is the right answer, in some
sense.
 
> Hugo, the code for cyg_ticks_to_timespec() just uses your scary clock
> convertors. The convertor is:
> 
> (gdb) p sec_inverter 
> $1 = {mul1 = 1, div1 = 100, mul2 = 1, div2 = 1}
> 
> and the conversion is:
> 
>     cyg_uint64 t = (cyg_uint64)value;
>     // Do this in an order to prevent overflow at the expense of
>     // accuracy:
>     t *= pcc->mul1;
>     t += pcc->div1 / 2;
>     t /= pcc->div1;
>     t *= pcc->mul2;
>     t += pcc->div2 / 2;
>     t /= pcc->div2;
>     // The alternative would be to do the 2 multiplies first
>     // for smaller arguments.
>     return (cyg_tick_count)t;

Which is identical to
	t = (t+50)/100;
which can only be correct.  How can it be wrong?

> So it seems that rounding off is intentional. In which case I should just

Oh, I get it now.  The code in cyg_ticks_to_timespec() is using a clock
converter to convert to whole seconds, then subtracting to get the nS part
left over!  No wonder it gives a "wrong" answer, of course the whole
seconds answer is rounded.

Use it to convert to nS and do a divide by 10^9 - that way the right answer
would emerge, that's what clock converters are meant for.

> tweak cyg_ticks_to_timespec to fix up the value if tv_nsec is negative.
> Before I do it, I just want to check my understanding that the convertors
> are doing the right thing by rounding not truncating.

Of course they are.  Someone misunderstood the purpose of the converters.
They do conversion taking care that overflow will be avoided at all costs,
even if it means discarding trailing digits; ie. they will be right at the
cost of precision even if the conversion factor is great in either
direction and the arguments are large.

They try to work over a great range of values and factors, sacrificing
trailing digits for this ability.

They're meant for converting from "my units" to "his units" and then giving
the answer to "him" *without further manipulation*.

They're certainly NOT meant for calculating intermediate values in a
greater calculation - consistency of that type was not a goal.

Example: you want to convert by a factor of 909,090/1000 (1.1kHz ticks to
uS) my intent was that the converter would end up doing something like:
	t *= 3367;
	t = (t+5)/10;
	t *= 27;      // this stage magnifies the rounding error above
	t = (t+5/10);
or even, to minimize overflow likelihood my making the first intermediate
the largest:
	t *= 3367;
	t = (t+50)/100;
	t *= 27;      // this stage magnifies the rounding error above
	// last factor is 1; all done

So it divides twice in order to make the intermediates smaller and so less
likely to overflow.  To get anything like the right answer it *must* round
at every stage.  OK?

	- Huge

  reply	other threads:[~2001-04-19  3:11 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2001-04-18  1:12 Boris V. Guzhov
2001-04-18 12:44 ` Jonathan Larmour
2001-04-19  3:11   ` Hugo Tyson [this message]
2001-04-19 14:14     ` Jonathan Larmour
2001-04-19  0:40 Nielsen Linus
2001-04-19 14:56 ` Jonathan Larmour

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=200104191010.f3JAAdn10455@masala.cambridge.redhat.com \
    --to=hmt@redhat.com \
    --cc=borg@int.spb.ru \
    --cc=ecos-discuss@sourceware.cygnus.com \
    --cc=jlarmour@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).