32-bit IEEE float multiplication

G

glen herrmannsfeldt

#define USECS_PER_TICK 17321
static unsigned long seconds = 0, excess = 0;

/* At each tick: */
excess += USECS_PER_TICK;
if (excess >= 1000000) {
excess -= 1000000;
++seconds;
}

Even better than the multiply/divide I suggested.

Just like a phase accumulator.

-- glen
 
A

Andy

That's good stuff Eric. I'm tempted to use this
method to keep a milliseconds counter, but the problem
is that if I do that, then I'll end up using unsigned
long divisions to convert the milliseconds count
to seconds. This requires 200 bytes more ROM
space than if I were to use float division. (I'm
working with 8K ROM at the present). Do you
know another way to divide an unsigned long value by
1000 using say, short or unsigned short operations?

TIA
Andy
 
G

glen herrmannsfeldt

Andy said:
That's good stuff Eric. I'm tempted to use this
method to keep a milliseconds counter, but the problem
is that if I do that, then I'll end up using unsigned
long divisions to convert the milliseconds count
to seconds. This requires 200 bytes more ROM
space than if I were to use float division. (I'm
working with 8K ROM at the present). Do you
know another way to divide an unsigned long value by
1000 using say, short or unsigned short operations?
(snip)

Yes, the trick is to use a power of 2, or of 256, for the unit, so
that the long division is by a power of 2 or 256.

Instead of microseconds per tick, use a unit if 1/16777216 of a second.

At each tick, add 290598 to the accumulator, seconds will accumulate
three bytes from the least significant byte.

Though the above code doesn't require a division. The seconds are
incremented at the appropriate time, such that they are the result
of dividing a large number by 1000000, and excess is the remainder.

Using add with carry it is very easy to add multibyte numbers.

-- glen
 
D

Dan Pop

In said:
That's good stuff Eric. I'm tempted to use this
method to keep a milliseconds counter, but the problem
is that if I do that, then I'll end up using unsigned
long divisions to convert the milliseconds count
to seconds.

I'm afraid I don't understand your problem. What millisecond count are
you talking about and why do you need to convert it to seconds?

Eric's code has a microsecond count and a second count. Do you need to
deal with fractions of a second or what?

Dan
 
C

CBFalconer

*** RUDE top-posting fixed ***
That's good stuff Eric. I'm tempted to use this
method to keep a milliseconds counter, but the problem
is that if I do that, then I'll end up using unsigned
long divisions to convert the milliseconds count
to seconds. This requires 200 bytes more ROM
space than if I were to use float division. (I'm
working with 8K ROM at the present). Do you
know another way to divide an unsigned long value by
1000 using say, short or unsigned short operations?

PLEASE STOP THE TOP-POSTING. It is very annoying and rude. Your
answer goes after the material to which you are replying, after
snipping non-germane stuff.

Simply change the constants to maintain a counter in 1/1024 second
intervals. This won't be too accurate, because your fundamental
resolution is about 17 millisecs. The idea is to maintain
something that can be converted to seconds with only a shift
(power of 2 factor).
 
D

Dan Pop

In said:
What would you do then if you needed to know the milliseconds?

Use a microsecond counter and a millisecond counter. Update the
microsecond counter first and then update the millisecond counter.
Still no need for any multiplication or division, either integer of
floating point.

Sorry, but if you can't figure these things out yourself, after all the
advice you have received, you're in the wrong business.

Dan
 
A

Andy

I was thinking of keeping only the excess counter and
not the second counter. I guess I should keep both
and compare to the millisecond counter if I need
millisecond resolution and compare to the second counter
if I need seconds resolution. That would work. I'm
sorry if I seemed stupid, but all along I was thinking
of using only one counter for both milliseconds and
seconds resolution. I didn't stop and think..

TIA
Andy
 
A

Andy

In <[email protected]> (e-mail address removed) >
I'm afraid I don't understand your problem. What millisecond count are
you talking about and why do you need to convert it to seconds?

Eric's code has a microsecond count and a second count. Do you need to
deal with fractions of a second or what?

Yes, I'd need a way to measure from milliseconds to days.

Andy
 
A

Andy

Sorry, but if you can't figure these things out yourself, after all the
advice you have received, you're in the wrong business.

Please stop wasting bandwidth with your senseless remarks.
If I understand you correctly, I would compare to the microseconds
counter if I need milliseconds resolution and I would compare
to the milliseconds counter if I need seconds resolution? But
ideally, I'd want a single counter to compare against for all
my timing needs from milliseconds, to seconds, to days. I guess
I can put these two counters in a struct, but then I'd have
a 64-bit timing variable. Too wastful..
If I missed your point completely, then maybe I'm too stupid for
this business and should look for something else soon...
Anyone needs a "no-good-for-low-level, but maybe good for high-level
programmer"? :)

TIA
Andy
 
E

E. Robert Tisdale

Andy said:
Please stop wasting bandwidth with your senseless remarks.

I see that you've met some of our indigenous trolls.

Indigenous trolls live under bridges (usenet newsgroups)
and snack on unwary billy goats gruff (new subscribers).

http://www.surlalunefairytales.com/billygoats/

They try to provoke an emotional response from new subscribers
("get their goat" if you please ;-).
They may say nasty things about you, your intellect, your character
or even your mother that have nothing at all to do
with the topic of the comp.lang.c newsgroup.

The best way to deal with indigenous trolls is to ignore them.
Remember, if you respond, the troll wins. ;-)
 
D

Dik T. Winter

>
> Please stop wasting bandwidth with your senseless remarks.
> If I understand you correctly, I would compare to the microseconds
> counter if I need milliseconds resolution and I would compare
> to the milliseconds counter if I need seconds resolution? But
> ideally, I'd want a single counter to compare against for all
> my timing needs from milliseconds, to seconds, to days. I guess
> I can put these two counters in a struct, but then I'd have
> a 64-bit timing variable. Too wastful..

Yup, that is life. As it is not clear at all what you really want, you
should not expect the people here to give you a clear solution.
 
R

Richard Heathfield

E. Robert Tisdale said:
I see that you've met some of our indigenous trolls.

Oh, don't be so ridiculous. Dan Pop is no troll. This is a case of the pot
calling the rainbow black.
The best way to deal with indigenous trolls is to ignore them.

To the OP: Tisdale's advice here, for once, is correct (insofar as it
suggests that you ignore his own articles). His advice is rarely topical
and rarely correct, so there's no point reading his stuff anyway.

Remember, if you respond, the troll wins. ;-)

No. This is a newsgroup, not a game. Where trolls like Tisdale are
concerned, nobody wins.
 
D

Dan Pop

In said:
Please stop wasting bandwidth with your senseless remarks.

My remarks were far from senseless. They actually provided you with the
best solution for your problem. But if this is how you understand to say
"thank you", I may choose other ways of spending my time.
If I understand you correctly, I would compare to the microseconds
counter if I need milliseconds resolution and I would compare
to the milliseconds counter if I need seconds resolution? But
ideally, I'd want a single counter to compare against for all
my timing needs from milliseconds, to seconds, to days.

For an embedded control problem, the ideal solution is the one that
gets the job done in a minimum of CPU cycles and a minimum of program
memory bytes, not the one that minimizes the number of counters.
If you haven't understood that by now, reread my remark quoted at
the begining of this post.
I guess
I can put these two counters in a struct, but then I'd have
a 64-bit timing variable. Too wastful..

You need a 16-bit counter for microseconds, a 16-bit counter for
milliseconds and a 32-bit counter for seconds. There are only a few bits
wasted in the first two counters (which only use 10 bits out of 16).

Dan
 
A

Andy

(e-mail address removed) (Dan Pop) wrote in message >
You need a 16-bit counter for microseconds, a 16-bit counter for
milliseconds and a 32-bit counter for seconds. There are only a few bits
wasted in the first two counters (which only use 10 bits out of 16).

Dan

After some soul searching, I've come up with this new clock
module (it only works for big-endian machines)


/* 4 millisecond increments */
#define GCLK_INC ((unsigned short)((double)(4.0) *
((double)65536.0/1000.0)) + 0.5)

/* use this type in your code */
typedef unsigned long GCLK_T;

/* Do not use this type in your code. It's only used internally in
gclk.c */
typedef union {
struct {
unsigned long secs;
unsigned short fractSecs; /* 1/65536 second */
} inc;
struct {
unsigned char unused;
GCLK_T ticks; /* upper 3 bytes are seconds. lower
byte 1/256 seconds */
} gclk;
} GCLK_LOW_LEVEL_T;

GCLK_LOW_LEVEL_T gcGClk;

#define GCLKIsr() do { \
gzGClk.inc.fractSecs += GCLK_INC; \
if (gzGClk.inc.fractSecs < GCLK_INC) { \
++gzGClk.inc.secs; \
} \
} while(0)

And everybody compares to gzGClk.gclk.ticks for time
references. that gives 24-bit seconds and 8-bit 1/65536 seconds.
This should work much better now. No? And the time measurement
should be linear up to overflow (in 198 days).

Andy
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,125
Messages
2,570,748
Members
47,302
Latest member
MitziWragg

Latest Threads

Top