View previous topic :: View next topic |
Author |
Message |
skoberlink
Joined: 27 May 2010 Posts: 52
|
Int -> float incorrect cast |
Posted: Fri Jan 14, 2011 12:41 pm |
|
|
Alright so I have no idea what's happening here so hopefully someone can tell me what's going on.
I am using MPLab IDE 8.63 with CCS 4.114 on a PIC18F2620.
I am using two int32 type variables to find a percent and store it in a float. I have tried many variations of casting and dividing including these:
Code: |
pct = ((float)num);
pct /= ((float)max);
pct = ((float)num) / ((float) max));
pct = ((float)num) / max;
pct = num / ((float)max);
|
num and max are both unsigned int32, pct is a float. num <= max at all times.
If I'm not mistaken, any one of those should work.
In fact I was using this one in another project to perform the same function (the old one used a PIC16F88 instead):
Code: |
pct = num;
pct /= max;
|
Looking back (it's been sometime since I wrote that), it doesn't seem like that should have worked but it did. I tried it here and it does not.
I realize this is really newbie stuff but something is just going weird.
Sometimes I'll get a negative percent, it's always greater than 1 (or less than -1 if it's negative). Basically the math is just not happening the way it should and this should be pretty easy stuff.
Any ideas what's going on? Maybe I made a stupid mistake somewhere or maybe there's a known bug in that compiler version. I'd appreciate anything at this point.
Last edited by skoberlink on Fri Jan 14, 2011 12:54 pm; edited 1 time in total |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Jan 14, 2011 12:50 pm |
|
|
Quote: | Sometimes I'll get a negative percent.
|
Make a test program that shows this specific failure. See the program
shown below for an example of a test program.
Here's the output of the program below:
Code: |
#include <18F2620.h>
#fuses INTRC_IO,NOWDT,PUT,BROWNOUT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
//======================================
void main(void)
{
float pct;
int32 num;
int32 max;
num = 5;
max = 100;
pct = ((float)num);
pct /= ((float)max);
printf("pct = %7.3f \n\r", pct);
while(1);
}
|
You can run this test in the MPLAB simulator very quickly.
This post explains how to use the simulator with "UART1" so you can
display printf statements in the Output Window in MPLAB:
http://www.ccsinfo.com/forum/viewtopic.php?t=23408&start=1 |
|
|
skoberlink
Joined: 27 May 2010 Posts: 52
|
|
Posted: Fri Jan 14, 2011 1:14 pm |
|
|
I can't get it to go negative now for some reason.
I also noticed I forgot to initialize the float so I did that and now I can get numbers below 1 but they're still significantly different from the correct values.
Just for an example I gave the input
num = 577, max = 1074
to my own function and using
Code: |
pct = 0; //after this pct = 0
pct = ((float)num); //after this pct = 8847937 (wtf?)
pct /= ((float)max); //after this pct = 0.233977437
|
This of course was only one example. I ran it again after this and instead of 8847937 I got 2.08922266e+009 and instead of 0.233... I got 55.057...
If you think it's relevant, in the second case num=579 and max=1079
I tried running your test program and it gave me the correct output.
I also tried substituting my own code into the test program (which was virtually identical) and again it worked exactly as expected. Same thing happened when I put in my real values for num and max. So it must be something about my project specifically...
In case it's useful here's my exact function.
Code: | //pos_calc
//no param, no return
//*PURPOSE calculate the current position based on curr_step
void pos_calc(){
extern unsigned char pos_out;
extern unsigned int32 max_steps, curr_step;
extern float pos_pct;
pos_pct = 0;
pos_pct = ((float)curr_step);
pos_pct /= ((float)max_steps);
pos_pct *= 255;
pos_out = pos_pct;
} |
So the purpose of the project is to move a stepper motor. The program keeps track of the current step and max steps in global variables (extern because I am using multiple compilation units).
This function is used to calculate the current position as a percent and then convert it to a percentage of 255 to be output as a single byte to a DAC.
pos_out is also used in another compilation unit. The reason I just don't output here is a little complicated and I don't think it's relevant since the problem occurs before that code is run.
So what here could cause a problem?
EDIT: I forgot to mention, pos_pct is extern because I still haven't figured out how to view local variables on this project. I made a separate post about this issue recently and didn't receive much help. I can view locals in other projects but not this one for some reason. Anyway, that's why pos_pct is temporarily extern so that I can see it. I suppose I could remove the extern and just make it global within this compilation unit.... Either way I still see symptoms of the problem when it's not extern so I don't think that's the issue. At least it's not the only issue... |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Jan 14, 2011 1:30 pm |
|
|
I installed vs. 4.114 and plugged in your first set of numbers, and I get
this, and it's correct:
I suggest that you re-install your compiler.
Test program:
Code: |
#include <18F2620.h>
#fuses INTRC_IO,NOWDT,PUT,BROWNOUT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
//======================================
void main(void)
{
float pct;
int32 num;
int32 max;
num = 577;
max = 1074;
pct = ((float)num);
pct /= ((float)max);
printf("pct = %7.3f \n\r", pct);
while(1);
} |
|
|
|
skoberlink
Joined: 27 May 2010 Posts: 52
|
|
Posted: Fri Jan 14, 2011 1:32 pm |
|
|
So I tried something else.
I made two unsigned int32's max and num that are not external and assigned max_steps and curr_step to those respectively. Max and num ended up with incorrect values even though they are the same type.
This tells me that there is something wrong with using externals. I have heard that they can cause odd issues like this. Is there some way around that? Or will I just need to use a single compilation unit? I was trying to avoid that so that my code could stay organized... |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Jan 14, 2011 1:38 pm |
|
|
I can't help you with Multiple Compilation Units. That only works with
the full CCS IDE compiler (PCW, PCWH, PCHWHD). I use the command
line compilers (PCM and PCH) with MPLAB. |
|
|
skoberlink
Joined: 27 May 2010 Posts: 52
|
|
Posted: Fri Jan 14, 2011 1:59 pm |
|
|
Ok well I really appreciate your help. I'm trying to switch it over to a single compilation unit. This isn't the first time I've run into problems with extern. I've just always figured it out before. I might as well just get rid of them.
So I took them all out and it seems to compile up until the linker where I get this error:
*** Error 29 "motor_18f2620.c" Line 1(0,1): Function definition different from previous definition y != float
I can pretty much guess what that error means if it were a function declaration. The y != float has me confused though. Any ideas?
EDIT: also I don't have a file called motor_18f2620.c but motor_18f2620 is the project name so I'm not sure what that means. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Jan 14, 2011 2:19 pm |
|
|
1. Look at the area above that line. Maybe the problem is a few lines
before that line.
2. Make sure your function prototype statements (if any) match the actual
function declaration.
3. Make sure you're calling it correctly.
If that doesn't help, then cut down the program to 10 lines by trial and
error to get a minimal test program that shows the problem. Then post it. |
|
|
skoberlink
Joined: 27 May 2010 Posts: 52
|
|
Posted: Fri Jan 14, 2011 2:33 pm |
|
|
The y != float is the only error or warning and it isn't a function so I don't know what's causing the problem.
I am using math.h if that could cause any issues. I mention this because it's full of float stuff. All my function declarations, definitions, and calls work the way they should. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Jan 14, 2011 3:24 pm |
|
|
I can't really do anything more without a minimal test program that
shows the problem. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19568
|
|
Posted: Sat Jan 15, 2011 2:58 am |
|
|
As a comment. Force all the stuff containing the external definitions to recompile.
I have seen a similar behaviour some time ago, when I upgraded the compiler, and tried to use some external code, that had been compiled with the previous compiler. Needed to 'touch' all the external sections, and recompile them with the new compiler (obviously should not be needed normally), and it then worked. Appeared that CCS had changed something in the way that external definitions were linked between the versions (undocumented of course....).
Best Wishes |
|
|
|