|
|
View previous topic :: View next topic |
Author |
Message |
Piccolo
Joined: 19 May 2006 Posts: 23 Location: Connecticut
|
math function: pow(X,Y) error |
Posted: Tue Aug 30, 2011 12:37 pm |
|
|
Hello Forum,
I am using a PIC16F866 with CCS compiler version 4.124.
It seems the math.h function pow(X,Y) does not behave, or I'm missing something (quite possible).
Here's my code snippet:
Code: |
void CalcDewPoint(void)
{
float32 e, es;//vapor pressure when given temperature (in millibars).
float32 logs;
// e is vapor pressure when given dewpoint (in millibars).
//vapor pressure when given temperature (in millibars).
// DryBulbTemp is in °C.
// RelHum is %Relative Humidity.
//! e = DryBulbTemp * 7.5;
//! es = DryBulbTemp + 237.7;
e = 163.3;
es = 259.5;
e = e/es;
es = pow(10.0,e);
es *= 6.112;
e = (es*RelHum);
e /= 100.0;
es = -430.22;
logs = 237.7*log(e);
es += logs;
logs = log(e);
logs *= -1.0;
logs += 19.08;
DewPtTemp = es/logs;
}
|
|
|
|
Piccolo
Joined: 19 May 2006 Posts: 23 Location: Connecticut
|
|
Posted: Tue Aug 30, 2011 12:43 pm |
|
|
Sorry, I must have hit a wrong button, as I was not finished with my query.
I tried this code with a PIC24 part, and when I used float64 the code ran properly.
I cannot use float64 with PIC16 part.
does anyone know if the pow(X,Y) function for float32 is buggy? I did scan the forum, but found only some older posts regarding this.
I did run this code with version 3 compiler, but then I had a different PIC, and I don't have a device file for PIC16F886 for version 3.
Any suggestions greatly appreciated.
Best regards,
piccolo |
|
|
foxabilo
Joined: 26 Aug 2011 Posts: 3 Location: United Kingdom
|
|
Posted: Tue Aug 30, 2011 1:08 pm |
|
|
Not sure if the pow function has any bugs but one thing I always do regardless of the value is typecast any numbers in my code, one thing I notice is the use of 1.0, I'm not sure if the compiler will see this as actualy 1 and thus make it an INT.
Try preceeding all fixed values with the typecast e.g
that should in theory not be needed for values with decimals but something I always do to avoid problems.
What is the actual numerical error you get, can you post a simplified bit of code with example output that shows the error?
Fox |
|
|
Piccolo
Joined: 19 May 2006 Posts: 23 Location: Connecticut
|
|
Posted: Tue Aug 30, 2011 2:30 pm |
|
|
Here's some more information:
with this code,
Code: |
#include "math.h"
float Value;
void CalcPOW(void)
{
Value = pow(10,0); //should be 1 but actual result is 127.00000
Value = pow(10,1); //should be 10 but actual result is -0.03711
Value = pow(10,2); //should be 100 but actual result is 0.00000
Value = pow(10,3); //should be 1000 but actual result is 0.00000
Value - pow(2,0); //should be 1 but actual result is 127.00000
} |
I output the Value to serial port using
Code: | printf("%3.5f", Value); |
It does not matter if I use 10 or 10.0, and it makes no difference if I typecast the values.
Also, I am using this in the header file above the FUSES:
#device *=16
Any suggestions greatly appreciated.
piccolo |
|
|
Piccolo
Joined: 19 May 2006 Posts: 23 Location: Connecticut
|
|
Posted: Tue Aug 30, 2011 2:34 pm |
|
|
Here's the ASM output:
Code: | .................... Value = pow(10,0);
0F84: CLRF 58
0F85: CLRF 57
0F86: MOVLW 20
0F87: MOVWF 56
0F88: MOVLW 82
0F89: MOVWF 55
0F8A: CLRF 5C
0F8B: CLRF 5B
0F8C: CLRF 5A
0F8D: CLRF 59
0F8E: GOTO 5DF
0F8F: MOVF 7A,W
0F90: MOVWF 54
0F91: MOVF 79,W
0F92: MOVWF 53
0F93: MOVF 78,W
0F94: MOVWF 52
0F95: MOVF 77,W
0F96: MOVWF 51
.................... DewPtTemp = Value;
0F97: MOVF 54,W
0F98: MOVWF 33
0F99: MOVF 53,W
0F9A: MOVWF 32
0F9B: MOVF 52,W
0F9C: MOVWF 31
0F9D: MOVF 51,W
0F9E: MOVWF 30 |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Aug 30, 2011 2:35 pm |
|
|
Quote: | I am using a PIC16F866 with CCS compiler version 4.124. |
This PIC doesn't exist. |
|
|
Piccolo
Joined: 19 May 2006 Posts: 23 Location: Connecticut
|
|
Posted: Tue Aug 30, 2011 2:37 pm |
|
|
Sorry, I am using the PIC16F886 |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19504
|
|
Posted: Tue Aug 30, 2011 2:54 pm |
|
|
Are you _sure_ you are loading the math.h, that corresponds to the compiler?. I have seen this, when a V4 compiler was used to compile code that had previously been compiled with a V3 compiler, and was still loading the math.h library from the V3 compiler. V4 changes the way that pointer arithmetic is done to the correct C behaviour, but parts of the old V3 library use pointer arithmetic assuming the 'old' behaviour, and give screwy results if compiled with V4.
You mention having previously used a V3 compiler, so check this.
Best Wishes |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Aug 30, 2011 3:06 pm |
|
|
I took your last program and made it into a test program and ran it in
MPLAB Simulator (MPLAB vs. 8.73a) and I got the following output:
Quote: |
1.00000
10.00000
99.99999
999.99992
1.00000
1.000
10.000
99.999
999.999
1.000
1.000
10.000
100.000
1000.000
1.000
|
Top of .LST file:
Quote: |
CCS PCM C Compiler, Version 4.124, xxxxx 30-Aug-11 14:02
Filename: C:\Program Files\PICC\Projects\PCM_Test\pcm_test.lst
ROM used: 3996 words (49%)
Largest free fragment is 2048
RAM used: 10 (3%) at main() level
74 (20%) worst case
Stack: 5 locations
|
Build results:
Quote: |
Memory usage: ROM=49% RAM=3% - 20%
0 Errors, 2 Warnings.
Loaded C:\Program Files\PICC\Projects\PCM_Test\pcm_test.cof.
BUILD SUCCEEDED: Tue Aug 30 14:02:06 2011
|
Test program:
Code: |
#include <16F886.H>
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=4M)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#include "math.h"
float Value;
void CalcPOW(void)
{
Value = pow(10,0); //should be 1 but actual result is 127.00000
printf("%3.5f \r", Value);
Value = pow(10,1); //should be 10 but actual result is -0.03711
printf("%3.5f \r", Value);
Value = pow(10,2); //should be 100 but actual result is 0.00000
printf("%3.5f \r", Value);
Value = pow(10,3); //should be 1000 but actual result is 0.00000
printf("%3.5f \r", Value);
Value = pow(2,0); //should be 1 but actual result is 127.00000
printf("%3.5f \r", Value);
printf("\r");
// Change width and precision fields so 1st one is higher than the last one:
Value = pow(10,0); //should be 1 but actual result is 127.00000
printf("%5.3f \r", Value);
Value = pow(10,1); //should be 10 but actual result is -0.03711
printf("%5.3f \r", Value);
Value = pow(10,2); //should be 100 but actual result is 0.00000
printf("%5.3f \r", Value);
Value = pow(10,3); //should be 1000 but actual result is 0.00000
printf("%5.3f \r", Value);
Value = pow(2,0); //should be 1 but actual result is 127.00000
printf("%5.3f \r", Value);
printf("\r");
Value = pow(10,0); //should be 1 but actual result is 127.00000
printf("%5.3g \r", Value);
Value = pow(10,1); //should be 10 but actual result is -0.03711
printf("%5.3g \r", Value);
Value = pow(10,2); //should be 100 but actual result is 0.00000
printf("%5.3g \r", Value);
Value = pow(10,3); //should be 1000 but actual result is 0.00000
printf("%5.3g \r", Value);
Value = pow(2,0); //should be 1 but actual result is 127.00000
printf("%5.3g \r", Value);
printf("\r");
}
//==========================================
void main()
{
CalcPOW();
while(1);
} |
|
|
|
Piccolo
Joined: 19 May 2006 Posts: 23 Location: Connecticut
|
|
Posted: Tue Aug 30, 2011 3:09 pm |
|
|
That was the problem! My project Options->Include Files was pointing to the version 3 compiler Drivers folder. the code is working as expected now, but I've got to do some trimming somewhere as the version 4 compiler gives me an out of ROM error, but at least the POW(X,Y) function issue appears resolved. Thank you for your assistance and great suggestions.
Best regards,
piccolo |
|
|
|
|
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
|