Hi Guys,
I want to test an unsigned long with the mod operator (%), if the result is positive then the result is used, if not then the long value is used.
I can't find the spec for C51 which describes what happens if the result of the mod is negative. Does it return '0' or a negative value.
This is definitely the tidiest way to do the job. I can do it differently and will do so for now, and will also set up some testing to check behaviour of the mod operator.
It would be very useful and might save me some valuable time if I could check behaviour with the C51 spec but can't find it anywhere. K & C ANSI doesn't help much, just says that the result is compiler dependant.
Thanks
The % operator is a division. Division on an unsigned long is quite expensive for a 8-bit processor.
When do you expect & to be negative? When one of the input numbers are negative? The cost of checking if an integer is negative is way less than performing a modulo calculation and then look at the sign of the result.
Oops. Managed to press a & instead of a % in the second paragraph.
Hi Per, I have been reading the "C51 Primer" and it is pretty clear that division with integers and longs is an expensive option. I realised that this must include the MOD operator. I have opted for a slightly lengthier but doubtless quicker subtraction algorithm instead. I am still interested in what happens when you try to find the modulus of a number which is smaller than the modulo value. Thanks for your interest.
Rob G
Own subtract algorithms will not beat the internal modulo function used by the compiler, unless possibly for very special numbers.
Note that the modulo operator - depending on version of standard and individual compiler implementation - has had different behaviour when one or two of the numbers are negative. If both numbers are positive, then it doesn't matter what compiler you have. You will always get a non-negative result.
0%3 => 0 1%3 => 1 2%3 => 2 3%3 => 0 4%3 => 1 5%3 => 2
Interesting things can start to happen for negative numbers. Alas, I can't test C51, but this is the "normal" behaviour - the C99 standard requires / to round towards zero and that if a/b is representable, then (a/b)*b + a%b shall equal a. -1%3 => -1 -2%3 => -2 -3%3 => 0 1%-3 => 1 2%-3 => 2 3%-3 => 0 -1%-3 => -1 -2%-3 => -2 -3%-3 => 0
So to get a negative reminder, the first number most be negative and not be divided evenly with the second number.
I will try and make time to compare approaches. The Keil docs are quite gloomy about timing for anything other than byte division. In this particular case the subtract method may work just as well. It will be interesting to see the results, and the info you have supplied will be very useful.
I should add that the case in point is for a number which lies in a certain range and must be subdivided into equal blocks by stages. The number is the total number of pulses to be issued to a stepper motor.
Each stage is a period during which the motor is run and which may mark periods of different frequencies (i.e. motor speeds). After each block some tests are made which modify the speed during the next block. Any remainder is run as a separate, shorter block.
A point to consider is the case where the initial number is smaller than the set block size (i.e. the modulus). This will be legal and the routine will execute OK. So long as the result is 0 then using MOD to find the remainder will work fine.