CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

math function: pow(X,Y) error

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Piccolo



Joined: 19 May 2006
Posts: 23
Location: Connecticut

View user's profile Send private message

math function: pow(X,Y) error
PostPosted: Tue Aug 30, 2011 12:37 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Aug 30, 2011 12:43 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Aug 30, 2011 1:08 pm     Reply with quote

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
Code:
e=e+(float32)1.0

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

View user's profile Send private message

PostPosted: Tue Aug 30, 2011 2:30 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Aug 30, 2011 2:34 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Aug 30, 2011 2:35 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Aug 30, 2011 2:37 pm     Reply with quote

Sorry, I am using the PIC16F886
Ttelmah



Joined: 11 Mar 2010
Posts: 19352

View user's profile Send private message

PostPosted: Tue Aug 30, 2011 2:54 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Aug 30, 2011 3:06 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Aug 30, 2011 3:09 pm     Reply with quote

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
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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