delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1997/07/23/12:04:08

From: mauch AT uni-duisburg DOT de (Michael Mauch)
Newsgroups: comp.os.msdos.djgpp
Subject: Re: Uclock & Clock causing SIG error w/O3 and greater
Date: Sat, 19 Jul 1997 17:29:04 +0200
Organization: Home, sweet home (via Gesamthochschule Duisburg)
Lines: 61
Message-ID: <5qqmfa$r5v$1@news-hrz.uni-duisburg.de>
References: <33CFAD70 DOT 1366 AT lausd DOT k12 DOT ca DOT us>
NNTP-Posting-Host: ppp58.uni-duisburg.de
Mime-Version: 1.0
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp

On Fri, 18 Jul 1997 17:53:17 GMT, csantill AT lausd DOT k12 DOT ca DOT us wrote:

> Now that I got some working mode 13h code to hack
> (thanx alot to Sinan!), I decided to test how fast
> it was.  I've been using uclock & clock to do my
> timing procedures but I always seem to get a
> SIGFPE error(division by zero) at line 54:
> 
> fps=7680/((t[2]-t[1])/UCLOCKS_PER_SEC)
>                 or
> fps=7680/((t[2]-t[1])/CLOCKS_PER_SEC)
> 
> This is odd because it does not occur when I compile
> w/O0 or O1.

It seems that (t[2]-t[1])/UCLOCKS_PER_SEC _is_ 0 when you compile with
O2 or O3. You are using integer arithmetics, so if the time between t[1]
and t[2] is less than one second, the difference of t[1] and t[2] is
less than UCLOCKS_PER_SEC and so (t[2]-t[1])/UCLOCKS_PER_SEC _is_ 0. The
same is true if you use clock() and CLOCKS_PER_SEC.

Think about the arithmetically equivalent expression:

  fps=7680*UCLOCKS_PER_SEC/(t[2]-t[1])

This way you won't get a division by zero unless t[2]==t[1], and that's
rather impossible if you use uclock() instead of clock().

But there arises another problem with this expression: signed integers
(and long integers, which are the same on 32 bit systems like DJGPP)
have a range from -2**31 to 2**31-1, where "**" means "to the power of".
(You have 31 bits "for the numbers", the 32th is used for the sign. With
unsigned 32 bit ints, you'd have a range from 0 to 2**32-1).

If you compute "7680*UCLOCKS_PER_SEC", with UCLOCKS_PER_SEC being
1193180 (see time.h), you get more than 2**31-1 and even more than
2**32-1. So you have to use some bits more than 32. With DJGPP, you have
the type "long long int", which is 64 bit wide (ok, 63 bit and the sign
bit). And that's really enough for "7680*UCLOCKS_PER_SEC". 

So you can use "7680LL*UCLOCKS_PER_SEC" or 
"(long long)7680*UCLOCKS_PER_SEC", meaning just the same: a type cast to
64 bit. 

Your complete expression will look like

  fps=7680LL*UCLOCKS_PER_SEC/(t[2]-t[1])

Regards...
		Michael

P.S.: I'm not sure if my English is good enough to tell such things, and
I'm not even sure if my teaching skills are good enough to explain this
in an understandable way. Feel free to ask again if something remained
unclear.

P.P.S.: I don't know where you got the number 7680 from, but probably
you have good reasons for it?
-- 
PGP key (0x013CB889) available at public key servers. PGP mail welcome.
PGP fingerprint: 83 D1 C4 76 0A F5 35 C6  C6 C4 C8 73 1B 45 E9 D5

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019