no DIVIDE BY ZERO error?

Having forgotten some of the basic rules of C data types tonight while working on a simple math calculation, I was doing some investigation into division operations.

After a lot of debugging, I gave myself a good cranial dent with the heel of my hand and my memory was refreshed on the rules of int/long sizes and math operations.

The sample program below illustrates what is clearly stated here: http://arduino.cc/en/Reference/Arithmetic. Output is also below.

The moral of the story is that type casting is just another math operation, and it follows the normal associative laws for evaluation.

But, back in the last century when I learned math and computer science, I think we were taught that division by zero should result in a program error, regardless of data type. Did they change that rule somewhere along the way and I miss the memo?

So, my question is, why does the first iteration of the loop give either +/- 1 for a result instead of an error?

/* IntMath
 
 Andy Davidson
 
 This program is intended to evaluate the function
 y = 60000 / x
 over the range of x = 0 to 6000 in increments of 100.
 
 Only c2 and c4 produce the right result, demonstrating that
 the default type for integer constants is int, and that
 type casting is just another math operation, which
 follows the normal associative laws for evaluation.
 
 */

const long c1 = 60 * 1000;
const long c2 = 60 * long (1000);
const long c3 = long (60 * 1000);
const long c4 = 60000;

void setup () {

  Serial.begin (9600);

  for (int i=0; i<60; i++) {

    int  x  = i * 100;

    long y1 = c1 / x;
    long y2 = c2 / x;
    long y3 = c3 / x;
    int  y4 = c4 / x;

    Serial.print ("i: ");
    Serial.print (i);
    Serial.print ("\tx: ");
    Serial.print (x);
    Serial.print ("\ty1: ");
    Serial.print (y1);
    Serial.print ("\ty2: ");
    Serial.print (y2);
    Serial.print ("\ty3: ");
    Serial.print (y3);
    Serial.print ("\ty4: ");
    Serial.print (y4);
    Serial.println ();    
  }

}

void loop () {
}

Results:

i: 0      x: 0      y1: 1      y2: -1      y3: 1      y4: -1
i: 1      x: 100      y1: -55      y2: 600      y3: -55      y4: 600
i: 2      x: 200      y1: -27      y2: 300      y3: -27      y4: 300
i: 3      x: 300      y1: -18      y2: 200      y3: -18      y4: 200
i: 4      x: 400      y1: -13      y2: 150      y3: -13      y4: 150
i: 5      x: 500      y1: -11      y2: 120      y3: -11      y4: 120
i: 6      x: 600      y1: -9      y2: 100      y3: -9      y4: 100
i: 7      x: 700      y1: -7      y2: 85      y3: -7      y4: 85
i: 8      x: 800      y1: -6      y2: 75      y3: -6      y4: 75
i: 9      x: 900      y1: -6      y2: 66      y3: -6      y4: 66
i: 10      x: 1000      y1: -5      y2: 60      y3: -5      y4: 60
i: 11      x: 1100      y1: -5      y2: 54      y3: -5      y4: 54
i: 12      x: 1200      y1: -4      y2: 50      y3: -4      y4: 50
i: 13      x: 1300      y1: -4      y2: 46      y3: -4      y4: 46
i: 14      x: 1400      y1: -3      y2: 42      y3: -3      y4: 42
i: 15      x: 1500      y1: -3      y2: 40      y3: -3      y4: 40
i: 16      x: 1600      y1: -3      y2: 37      y3: -3      y4: 37
i: 17      x: 1700      y1: -3      y2: 35      y3: -3      y4: 35
i: 18      x: 1800      y1: -3      y2: 33      y3: -3      y4: 33
i: 19      x: 1900      y1: -2      y2: 31      y3: -2      y4: 31
i: 20      x: 2000      y1: -2      y2: 30      y3: -2      y4: 30
i: 21      x: 2100      y1: -2      y2: 28      y3: -2      y4: 28
i: 22      x: 2200      y1: -2      y2: 27      y3: -2      y4: 27
i: 23      x: 2300      y1: -2      y2: 26      y3: -2      y4: 26
i: 24      x: 2400      y1: -2      y2: 25      y3: -2      y4: 25
i: 25      x: 2500      y1: -2      y2: 24      y3: -2      y4: 24
i: 26      x: 2600      y1: -2      y2: 23      y3: -2      y4: 23
i: 27      x: 2700      y1: -2      y2: 22      y3: -2      y4: 22
i: 28      x: 2800      y1: -1      y2: 21      y3: -1      y4: 21
i: 29      x: 2900      y1: -1      y2: 20      y3: -1      y4: 20
i: 30      x: 3000      y1: -1      y2: 20      y3: -1      y4: 20
i: 31      x: 3100      y1: -1      y2: 19      y3: -1      y4: 19
i: 32      x: 3200      y1: -1      y2: 18      y3: -1      y4: 18
i: 33      x: 3300      y1: -1      y2: 18      y3: -1      y4: 18
i: 34      x: 3400      y1: -1      y2: 17      y3: -1      y4: 17
i: 35      x: 3500      y1: -1      y2: 17      y3: -1      y4: 17
i: 36      x: 3600      y1: -1      y2: 16      y3: -1      y4: 16
i: 37      x: 3700      y1: -1      y2: 16      y3: -1      y4: 16
i: 38      x: 3800      y1: -1      y2: 15      y3: -1      y4: 15
i: 39      x: 3900      y1: -1      y2: 15      y3: -1      y4: 15
i: 40      x: 4000      y1: -1      y2: 15      y3: -1      y4: 15
i: 41      x: 4100      y1: -1      y2: 14      y3: -1      y4: 14
i: 42      x: 4200      y1: -1      y2: 14      y3: -1      y4: 14
i: 43      x: 4300      y1: -1      y2: 13      y3: -1      y4: 13
i: 44      x: 4400      y1: -1      y2: 13      y3: -1      y4: 13
i: 45      x: 4500      y1: -1      y2: 13      y3: -1      y4: 13
i: 46      x: 4600      y1: -1      y2: 13      y3: -1      y4: 13
i: 47      x: 4700      y1: -1      y2: 12      y3: -1      y4: 12
i: 48      x: 4800      y1: -1      y2: 12      y3: -1      y4: 12
i: 49      x: 4900      y1: -1      y2: 12      y3: -1      y4: 12
i: 50      x: 5000      y1: -1      y2: 12      y3: -1      y4: 12
i: 51      x: 5100      y1: -1      y2: 11      y3: -1      y4: 11
i: 52      x: 5200      y1: -1      y2: 11      y3: -1      y4: 11
i: 53      x: 5300      y1: -1      y2: 11      y3: -1      y4: 11
i: 54      x: 5400      y1: -1      y2: 11      y3: -1      y4: 11
i: 55      x: 5500      y1: -1      y2: 10      y3: -1      y4: 10
i: 56      x: 5600      y1: 0      y2: 10      y3: 0      y4: 10
i: 57      x: 5700      y1: 0      y2: 10      y3: 0      y4: 10
i: 58      x: 5800      y1: 0      y2: 10      y3: 0      y4: 10
i: 59      x: 5900      y1: 0      y2: 10      y3: 0      y4: 10

But, back in the last century when I learned math and computer science, I think we were taught that division by zero should result in a program error, regardless of data type. Did they change that rule somewhere along the way and I miss the memo?

Some languages still do you run time error trapping, however C is not one of them. C was designed to be low level, low overhead with no run time code that I know of. It's a good language match for microcontroller because of their limited resources and complex I/O components.

Lefty

So the results on these processors are just undefined? Return -1?

Well I'm more a hardware guy then a software guy, so I'm not the one to ask such details :wink:

A quick google checked implied that some C++ implementations may have some math error reporting, most likely as part of their math library routines, maybe straight C could have the same, but I am pretty sure that it's not a part of C's core language, not sure about C++.

Lets let some of the software wizards that hang here comment further.

Lefty

// think we were taught that division by zero should result in a program error//
I think the keyword there is "should".
It should result in a program error, and who wrote the program?
You did! :wink:
If you want a system error, well, you're talking to the wrong processor, because the AVR doesn't have a divide instruction, so can't itself know that a divide-by-zero has occurred.
Don't forget the AVR is a tiny microcontroller, not a full-blown desktop or laptop-class microprocessor.

Well, of course as a good programmer I will code for the boundary cases!

I don't need the hardware fault to be generated, I was just curious, being new to micro-controllers.

So is the compiler then generating code to "fake" the division with shifts? And floating point; how does that work?

So is the compiler then generating code to "fake" the division with shifts?

Correct.

And floating point; how does that work?

Sloooowly ;D