|
|
View previous topic :: View next topic |
Author |
Message |
SherpaDoug
Joined: 07 Sep 2003 Posts: 1640 Location: Cape Cod Mass USA
|
C math question |
Posted: Fri Jul 16, 2004 1:26 pm |
|
|
Given this code
Code: | Signed int T,dT,Num;
Num = -123;
T = Num/10;
dT = Num%10;
|
Will this properly give integer and decimal parts of Num/10 for both positive and negative numbers? I have done this many times, but never had to worry about negatives. K&R says the result of % on negatives is machine dependent. How do people usually code this? _________________ The search for better is endless. Instead simply find very good and get the job done. |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1908
|
signed math |
Posted: Fri Jul 16, 2004 2:28 pm |
|
|
Ooh, is your question ever timely!
I just finished doing something similar, and I had some unexpected results until I figured out how the compiler was evaluating things.
I had to figure out the travel of a mechanical part, given a 10 bit adc reading from an electronic height sensor. The sensor's output is in the range 0 - 5V, and I had to take into account two possibilities: that 0V (0x0000) = 0 travel, and 5V (0x03ff) = full travel, and vice-versa: 0V (0x0000) = full travel, and 5V (0x03ff) = 0 travel. This was to take into account the height sensor being installed backwards, which is a possibility. Also, in the real world, the sensor's output not be the full 5V, which is why I coded things the way I did.
How I ended up doing it is as follows:
Code: | signed int16 min; // 0 travel value
signed int16 diff; // full travel value - 0 travel value
signed int16 step;
signed int16 temp; // used for math later
int16 adc_reading; // no explanation necessary
int full_travel; // full travel of the part (inches)
int travel; // actual position of part - range 0 - full_travel
int1 ascending = FALSE;
if (diff < 0) { // if diff is negative, then 5V = 0 travel, 0V = full travel
ascending = FALSE;
}
else {
ascending = TRUE;
}
step = diff/full_travel; // this is the value corresponding to 1 inch of travel (one step)
temp = adc_reading - min;
travel = temp/step; // this ends up being a pretty good approximation of the part's position in inches, truncated to the nearest inch
// now to take care of rounding - if the remainder > step/2, round up travel
if (ascending && ((temp % step) > (step / 2))) { // remainder positive
travel++;
}
else if (!ascending && ((temp % step) < (step / 2))) { // remainder negative
travel++;
} |
Originally I simply checked to see if (temp % step) > (step/2), without the ascending flag. It turns out that if things are backwards (5V = 0 travel, 0V = full travel), then the remainder of temp % step and step are both negative. However, if the remainder is, say -1, that's 0xffff, and if step is -2, that's what, 0xfffe? Since 0xffff > 0xfffe, the if evaluates to true, and travel would be incremented, even though I (that's the important part) didn't think that it should be.
Hope this helps. |
|
|
Guest
|
|
Posted: Sat Jul 17, 2004 1:21 am |
|
|
To be sure about the modulo's result I use something like this:
signed int unsig;
unsig = Num;
if (unsig < 0) unsig = -unsig;
dT = unsig % 10;
This gives in you example (-123) -12 for T and 3 for dT. |
|
|
Sherpa Doug Guest
|
|
Posted: Sat Jul 17, 2004 1:43 pm |
|
|
Anonymous wrote: | To be sure about the modulo's result I use something like this:
signed int unsig;
unsig = Num;
if (unsig < 0) unsig = -unsig;
dT = unsig % 10;
This gives in you example (-123) -12 for T and 3 for dT. |
That is the simple answer I was hoping for. Rathter obvious in retrospect, as many good answers are. Hopefully I can try it Monday if my boss has no new crises for me. |
|
|
|
|
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
|