[Courses] [C] Debugging (Re: help me find my C bug? (long))

Conor Daly conor.daly at met.ie
Wed Jul 10 12:56:03 EST 2002


On Wed, Jul 10, 2002 at 05:36:24PM +1000 or thereabouts, Mary wrote:
> On Tue, Jul 09, 2002 at 10:28:50PM -0700, Suzi Anvin wrote:
> > Hold on... pointers are chapters away yet!  :)  this is like my 3rd or
> > 4th day at this!  So far, all the programs I've been playing with are
> > one-function programs and I've yet to have explained to me (by the
> > book) the difference between global and local variables...  doing it
> > the book's way for now, sand I'm really hoping they eventually explain
> > WHY all the examples declare all the variables globally so far.  :)
> 
> That sounds... odd. Local variables in C aren't hard, you can declare
> them at the start of any block (blocks are bracketed by {} braces), and
> their scope is until the end of the block.

Heh, I got bitten by scope on one accasion recently.  I'd just installed
vim6.0 to take advantage of "folding" (It's brilliant, 80 line functions
hidden behind one line!).  I wanted to make loops, if else ladders, variable
declarations all disappear and, given that {} is the usual delimeter for the
folding function in vim, I placed all of my variable declarations inside {}
pairs.  Then I wondered why my code wouldn't compile.  My variables had all
become limited in their scope to just the {} blocks where they were
_declared_!

On the matter of floating point imprecision, we run a database of weather
records here and record quite a bit of stuff to one place of decimals.
However, at times, a search for "rain=3.3" returns no data while "rain >3.29
and rain <3.31" will return hundreds of lines!

Using 

total=(amount * 100) + 0.5;

works, but to cope with negative numbers you need just a little more.  You
can use two (probably more) different approaches;

1. if else

if ( amount < 0 ) {
  total=(int) (amount * 100) - 0.5);
} else {
  total=(int) (amount * 100) + 0.5);
}

2. use the sign

sign = sqrt (amount * amount);
total=(int) (amount * 100) + (sign * 0.5);

note that either of these methods give rise to an inconsistency where -0.5
rounds to 0 while -1.5 rounds to -2 and -1 gets missed along the way.  The
solution to this (IMO!) is to use just a *little* extra for the rounding
figure.  ie.

1. if else

if ( amount < 0 ) {
  total=(int) (amount * 100) - 0.50001);
} else {
  total=(int) (amount * 100) + 0.5);
}

2. use the sign

sign = sqrt (amount * amount);
total=(int) (amount * 100) + (sign * 0.50001);

This will produce expected behaviour but ONLY so long as the "little bit
extra" is well below the precision of the numbers you are rounding.

Conor (rambling...)
-- 
Conor Daly 
Met Eireann, Glasnevin Hill, Dublin 9, Ireland
Ph +353 1 8064276 Fax +353 1 8064247
------------------------------------
bofh.irmet.ie running RedHat Linux  9:33am  up 2 days, 23 min,  7 users,  load average: 0.19, 0.29, 0.26


**********************************************************************
This email and any files transmitted with it are confidential and
intended solely for the use of the individual or entity to whom they
are addressed. If you have received this email in error please notify
the system manager.

This footnote also confirms that this email message has been swept 
for the presence of computer viruses.


**********************************************************************




More information about the Courses mailing list