CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

divide by zero

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
FFT



Joined: 07 Jul 2010
Posts: 92

View user's profile Send private message

divide by zero
PostPosted: Wed Nov 24, 2010 12:20 pm     Reply with quote

Hi All,

I get "Divide by zero" error on this code:
Code:
#define CPUCLK                  48000000 // [Hz]
#define TMRDIV                  8
#define TIMEOUT                 (1/((1/(CPUCLK/4))*TMRDIV*65536)) //interrupt counts of timer for 1 sec

void main()
{
   volatile int8 Timer;

   Timer=TIMEOUT; // on this row occurs 'divide by zero' error

   while(1);
}

But the result of TIMEOUT is 22.88 for calculator.
FFT



Joined: 07 Jul 2010
Posts: 92

View user's profile Send private message

PostPosted: Wed Nov 24, 2010 12:25 pm     Reply with quote

I added .0 at the end of all numbers and now can compile, but why it calculates everything as int8?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Nov 24, 2010 1:13 pm     Reply with quote

MSVC++ 6.0 does the same thing. Here is the error message:
Quote:

error C2124: divide or mod by zero

Test program for MSVC6:
Code:

#include <stdio.h>

#define CPUCLK    48000000 // [Hz]
#define TMRDIV    8
#define TIMEOUT   (1/((1/(CPUCLK/4))*TMRDIV*65536)) //interrupt counts of timer for 1 sec
//============================
void main(void)
{
unsigned char Timer;

Timer = TIMEOUT;

printf("%x \n", Timer);

}
temtronic



Joined: 01 Jul 2010
Posts: 9221
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Nov 24, 2010 2:12 pm     Reply with quote

I'd breakdown the definition of TIMEOUT, printing out the subcomputed values to see why it isn't the value(23) that you think it should be.
It's easy to think the compiler is do something wrong, but stacked(multilevel) parenthesis can get even the best programmer !
FFT



Joined: 07 Jul 2010
Posts: 92

View user's profile Send private message

PostPosted: Wed Nov 24, 2010 3:46 pm     Reply with quote

I declared all the numbers like float (8.0 etc..) as solution.

BTW, Keil for ARM does not the same thing.
andrewg



Joined: 17 Aug 2005
Posts: 316
Location: Perth, Western Australia

View user's profile Send private message Visit poster's website

PostPosted: Wed Nov 24, 2010 10:04 pm     Reply with quote

This is how I would have done it:
Code:
#define TIMEOUT (getenv("CLOCK")/4/TMRDIV/65536)
Or, if you wanted rounding to the nearest integer:
Code:
#define TIMEOUT ((getenv("CLOCK")/4/TMRDIV+32768)/65536)

_________________
Andrew
Wayne_



Joined: 10 Oct 2007
Posts: 681

View user's profile Send private message

PostPosted: Thu Nov 25, 2010 2:58 am     Reply with quote

This is most likely your problem

(1/(CPUCLK/4))

1/(CPUCLK/4) will be less than 1. The int part of the result will be 0.
from then on it is all down hill.
0 * val = 0
FFT



Joined: 07 Jul 2010
Posts: 92

View user's profile Send private message

PostPosted: Thu Nov 25, 2010 5:43 am     Reply with quote

@andrewg, Thanks for the equation.

Wayne_ wrote:
1/(CPUCLK/4) will be less than 1. The int part of the result will be 0. from then on it is all down hill. 0 * val = 0

I already understood that, but my question was other. "why it calculates everything as int8?"

Thanks all for the valued opinions, the problem temporarily has solved by the andrewg's equation, the other way is to make all the numbers float.
andrewg



Joined: 17 Aug 2005
Posts: 316
Location: Perth, Western Australia

View user's profile Send private message Visit poster's website

PostPosted: Thu Nov 25, 2010 6:44 am     Reply with quote

FFT wrote:
"why it calculates everything as int8?"


The compiler always treats things as the most simple type possible. It will try to fit things into an 8-bit integer first, then 16-bit, then 32-bit. I'm pretty sure it will only use floating point if you force it to, as you've done using ".0".

In your case it's not using int8, but int32. The 8 vs 32 isn't important, the fact it's an integer is. As you've found, the intermediate value of (1/12000000) is rounded down to zero due to the integer math.

When dealing with integer math, you need to consider the order of calculation to maintain accuracy and precision.
_________________
Andrew
Ttelmah



Joined: 11 Mar 2010
Posts: 19500

View user's profile Send private message

PostPosted: Thu Nov 25, 2010 8:17 am     Reply with quote

Simple answer. It doesn't use int8....

In C, the standard rule is, that for every arithmetic operation, you look at the types of the two operands, and then promote the 'lowest' types number to the higher type, and perform the arithmetic using this type.

Look at the numbers in the original sum. The _highest_ type used here, is an int32. Since this is used in the very first sum, this will be the type for the entire operation. When you perform the first division, you have 1/(a value>1), so the result in integer maths, is zero. The second division, then errors.

Now, most C's follow this rule. (as PCM programmer has pointed out VC does as well). There are 'slight' exceptions as you move into computers with more processing power (on the PC for example, if you perform 'int8' multiplications, the result is always an int16). This is because there is a hardware multiplier, that gives a 16bit result. Similarly, when you use the FPU, there is a tendency to accept a higher type result 'automatically'. This however is _not_ standard C.

Now, in the problem code, simply forcing the very first multiplier to be a float, will automatically force float to be used for every subsequent operation. So (CPUCLK/4.0), is all that is needed.

Best Wishes
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group