|
|
|
![]() |
|
|||||||
|
||||||||
![]() |
| Thread Tools | Rate Thread | Display Modes |
|
#1
|
|||
|
|||
|
Math Gone Wrong
We have a integer type value called joystick
Code:
joystick = (2)*(p1_x)+256;
printf("joystick: %d p1_x: %d \n", joystick, p1_x);
p1_x joystick 0 256 works like it should (2)*(0)+256 50 356 works fine: 2*50+256=100+256=356 127 510 works fine: 2*127+256=254+256=510 128 256 ***DOESN"T WORK**** 200 400 ***DOESN'T WORK**** 250 500 ***DOESN't WORK**** for some reason the code only works for p1_x is less than 128, otherwise after it is greater than or equal to 128 it just doubles it. Can anyone explain why, and what a solution might be, thanks. |
|
#2
|
|||||
|
|||||
|
Re: Math Gone Wrong
I can't remember correctly right at the moment, but I think integers are limited to 128 as the highest (really 127 because of zero). If I'm correct, that would explain the problem. Try using a different type variable, like a long or something, and see if that works.
|
|
#3
|
|||||
|
|||||
|
Re: Math Gone Wrong
Quote:
Therefore it cannot hold 256, 400, or 500 in the above example. |
|
#4
|
|||
|
|||
|
Re: Math Gone Wrong
Quote:
I tried longs yesterday as well, and got the same results, and i think integers can go from -32768 to 32768, so i don't think that is the problem, but i'll check again, next time we work on the robot, and unfortunately snow has closed school today, so we can't work, any other ideas, thanks-again Last edited by psquared : 22-01-2005 at 09:41. |
|
#5
|
|||
|
|||
|
Re: Math Gone Wrong
Quote:
value = (2)*(p1_x)+256; I would think that is ok, but if not, how could we correct it to get the same result. thanks. |
|
#6
|
|||||
|
|||||
|
Re: Math Gone Wrong
Quote:
try typecasting value = 2*(int) p1_x + 256; [edit] What's happening is the operation on the right will use the size of the largest type in the equation to store the result temporarily. In this case an unsigned char (p1_x). The 2* calculation overflows the unsigned char temporary storage. Adding the (int) forces the compiler to use the larger integer type to temporarily store the result. Last edited by Mark McLeod : 22-01-2005 at 09:56. |
|
#7
|
|||
|
|||
|
Re: Math Gone Wrong
To clear up the confusion here, the standard C types have the following ranges:
char: 2^8 (256) int: 2^16 (65536) long: 2^32 (4294967296) The unsigned variety go 0 to (range-1) The signed go from (-(range/2)) to ((range/2)-1) Just a FYI |
|
#8
|
|||
|
|||
|
Re: Math Gone Wrong
Just to clarify further (and we had this problem too):
The C standards says that integer arithmetic will be automatically promoted to integer size, that is 16 bits. So for signed integers the range is -32768 to 32767 and for unsigned the range is 0 to 65536. The Microchip compiler has a "feature" that will try to optimize the size and speed of the program by keeping expressions at the smallest size possible. What you're seeing is a result of this quirk in the compiler. If you multiply two values together (even constants!) where the values can be represented as characters, then the math is done with byte arithmetic. So writing this expression: 8* 25 Gives you an answer of -56 because both 8 and 25 can fit in chars and so the math is done with chars (instead of the usual standard promotion to ints), the answer overflows the char range, and you get -56. In your case you were multiplying 2*p1_x. 2 can fit in a char, p1_x is a char, so the math is carried out as bytes. Any time 2*p1_x was greater than a byte you had overflow and the wrong answer. |
|
#9
|
||||
|
||||
|
Re: Math Gone Wrong
Psquared,
Please show us your declaration for the variable "joystick". |
|
#10
|
|||
|
|||
|
Re: Math Gone Wrong
Thanks Brad, that makes a lot of sense, and will help us evade any future problems like that. Also I will try the casting when we are able to meet again for robotics. It is snowing here, and we haven't been able to meet since friday, and if school is out tomorrow, we can't work tomorrow either. But, when we do go back, I'll be sure to try everything out, and if it works I'll let you know. Thanks for all of the help from everyone who offered solutions.
|
|
#11
|
|||||
|
|||||
|
Re: Math Gone Wrong
One other solution is to use the option in MPLAB to force the default use of the integer type (at least) in any calculations. You still need to be aware of the potential for overflow, e.g., any calculation with an intermediate result > 32767 for instance.
Project -> Build Options… -> Project MPLAB C18 tab Check “Enable integer promotions” |
![]() |
| Thread Tools | |
| Display Modes | Rate This Thread |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| New math functions? | KVermilion | Programming | 8 | 17-01-2005 10:38 |
| I-cylinder body wrong? | Daniel Brim | Inventor | 0 | 05-03-2004 20:18 |
| Wrong Math in the site info section.. | Matt Attallah | CD Forum Support | 9 | 10-06-2003 16:43 |
| direct Drill motor drive wrong or right | rcubes85 | General Forum | 6 | 11-02-2003 18:11 |
| Whats wrong with this code? | Morgoth | Programming | 4 | 19-01-2003 11:45 |