CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 21
  1. #1
    Join Date
    Dec 2013
    Posts
    11

    Problem using the pow() function from math.h

    I am writing a program that reads a temperature from a wireless sensor and then takes the temperature value read and performs calculations on that temperature. So, for example, The sensor reads a value of 75 degress F and then I plug this value into the equation...

    float e = 2.718281828459;
    long int Thermistor_val;
    int Ctemp=75;

    Thermistor_val=24658*pow(e,(-0.027*Ctemp));

    This works for many passes of the program. I then let this run overnight and when I checked on it in the morning I see that the Thermistor_val variable is at FFFF and stays there. If I restart the program again all is reset and the values look good. My question is, what condition would cause the value of Thermistor_val to go to FFFF and stay there? Is this caused by an overflow condition?

    I need to point out that the Ctemp value, in the actual program, is a calculated value. I suppose Ctemp could be actually a bad value that is causing Thermistor_val to be calculated incorrectly. However when I stopped the program from running the only value that seemed bad was Thermistor_val. Is the way to get around this error to check all values before a calculation is performed to ensure that they are within an acceptable range? Right now my code "works" at least for many of the passes. What I am trying to do is make is more robust to avoid these 'bad data' situations. Any suggestions would be appreciated. Note, I am relatively new to serious error handling in programs.

    Thank you,
    Mike Nycz

  2. #2
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,396

    Re: Problem using the pow() function from math.h

    Quote Originally Posted by mikenycz View Post
    ... I see that the Thermistor_val variable is at FFFF and stays there. If I restart the program again all is reset and the values look good. My question is, what condition would cause the value of Thermistor_val to go to FFFF and stay there? Is this caused by an overflow condition?
    Is it exactly FFFF (0x0000FFFF) or 0xFFFFFFFF?

    Quote Originally Posted by mikenycz View Post
    I need to point out that the Ctemp value, in the actual program, is a calculated value. I suppose Ctemp could be actually a bad value that is causing Thermistor_val to be calculated incorrectly.
    So could it happen that Ctemp was some big negative value?
    And how does your actual code look like?
    Victor Nijegorodov

  3. #3
    Join Date
    Dec 2013
    Posts
    11

    Re: Problem using the pow() function from math.h

    The value was 0xFFFFFFFF.

    Ctemp should be between 60 and 80 right now (I'm measuring temperatures in the room). The value for Ctemp is derived from an IEEE-754 encoded value that is sent by the temperature sensor. One possibility is that the IEEE-754 value received is bad or corrupted and so the calculation of Ctemp gets a bad value. What I was going to try was checking the results of all computations leading up to Ctemp to verify that the result is in an acceptable range. If it is not, throw out the bad data and wait for another value to be sent by the sensor.

    The one question that I have is, if one of the variables does get an overflow value, does that invalidate any future results or can the overflow be reset inside of the program?

    VictorN.. You asked about the code... I have attached the program to this post. The calculation section looks like this...


    if (Bin_Buff[0] == '0') {
    // Calculate exponent value of IEEE 754 number
    Cexp = calc_exp(Bin_Buff);
    //Calculate normalized exponent value of IEEE 754 number
    Aexp = Cexp-127;
    //Add "hidden 1 bit" to Temperature_bin
    Temperature_bin[0]='1';
    //Add bits past decimal point to Temperature_bin
    for (i=9;i<=(8+Aexp);i++) {
    Temperature_bin[i-8]=Bin_Buff[i];
    }
    //Calculate Temperature in Deg F
    Ctemp = calc_temperature(Temperature_bin,Aexp);
    //Plug Temp into equation to get equivalent Thermistor value
    //This equation was derived empirically from one of the FA7226 sensors
    Thermistor_val=24658*pow(e,(-0.027*Ctemp));
    //Convert Thermistor_val to hex values needed for message
    int junk2;
    int junk = Thermistor_val;
    char Thermistor_hexlo = junk;
    for (i=0;i<=7;i++) {
    junk2 = (junk >> 8);
    }
    char Thermistor_hexhi = junk2;

    Here is the calc_exp() routine...

    int calc_exp(unsigned char *input)
    {
    int power2=0;
    int output=0;
    int i;
    for (i=1;i<=8;i++) {
    if (input[i] == '1') {
    switch (8-i) {
    case 0: power2 = power2 +1;
    break;
    case 1: power2 = power2 +2;
    break;
    case 2: power2 = power2 +4;
    break;
    case 3: power2 = power2 +8;
    break;
    case 4: power2 = power2 +16;
    break;
    case 5: power2 = power2 +32;
    break;
    case 6: power2 = power2 +64;
    break;
    case 7: power2 = power2 +128;
    break;
    }
    output=power2;
    }

    }
    return output;
    }

    And here is the calc_temperature() routine.....

    int calc_temperature(unsigned char *input, int length)
    {
    int power2=0;
    int output=0;
    int i;
    for (i=0;i<=(length);i++) {
    if (input[i] == '1') {
    switch (length-i) {
    case 0: power2 = power2 +1;
    break;
    case 1: power2 = power2 +2;
    break;
    case 2: power2 = power2 +4;
    break;
    case 3: power2 = power2 +8;
    break;
    case 4: power2 = power2 +16;
    break;
    case 5: power2 = power2 +32;
    break;
    case 6: power2 = power2 +64;
    break;
    case 7: power2 = power2 +128;
    break;

    }
    output=power2;
    }

    }
    return output;
    }




    Thank you,
    Mike Nycz
    Attached Files Attached Files

  4. #4
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,396

    Re: Problem using the pow() function from math.h

    Code:
    //Find temperature using IEEE 754 format
    
    				if (Bin_Buff[0] == '0') {
    // Calculate exponent value of IEEE 754 number
    					Cexp = calc_exp(Bin_Buff);
    //Calculate normalized exponent value of IEEE 754 number
    					Aexp = Cexp-127;
    You are using Aexp as a size of byte array calling then
    Code:
    //Calculate Temperature in Deg F
    					Ctemp = calc_temperature(Temperature_bin, Aexp);
    But are you sure that calc_exp(Bin_Buff) will always return you the value >= 127?
    Victor Nijegorodov

  5. #5
    Join Date
    Dec 2013
    Posts
    11

    Re: Problem using the pow() function from math.h

    If the IEEE-754 value is good then the answer is yes. The uncertainty is whether the value passed to calc_exp is good. Since this is wireless data being received via an RS232 connected receiver, if the data is corrupted during translation I could possibly get a bad value in Bin_Buff that would generate an erroneous Cexp. I should probably check the value of Cexp prior to using it. Thank you for the pointer. I'll look more closely at all calculated values to ensure they are in the expected range.

    But my question remains... If a variable overflows during program execution, can I recover from the overflow during program execution or do I need to find out the reason for the overflow and prevent it from happening in the first place?

    Thank you,
    Mike Nycz

  6. #6
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,396

    Re: Problem using the pow() function from math.h

    Quote Originally Posted by mikenycz View Post
    ... I should probably check the value of Cexp prior to using it. Thank you for the pointer. I'll look more closely at all calculated values to ensure they are in the expected range.
    Yes, you have to.

    Quote Originally Posted by mikenycz View Post
    ... But my question remains... If a variable overflows during program execution, can I recover from the overflow during program execution or do I need to find out the reason for the overflow and prevent it from happening in the first place?
    Sorry, I don't know. You should read the documentation of your c++ compiler + run-time library.
    Victor Nijegorodov

  7. #7
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Problem using the pow() function from math.h

    Quote Originally Posted by mikenycz View Post
    But my question remains... If a variable overflows during program execution, can I recover from the overflow during program execution or do I need to find out the reason for the overflow and prevent it from happening in the first place?
    Depends on your compiler, runtime, CPU floating point handling and if CPU, certain CPU flags that control what happens when a "bad" FP calculation occurs.

    For example, the Intel processors will mask floating point errors if a certain aspect of the processor is turned on/off. See functions such as _control87 for the Intel processors.

    Regards,

    Paul McKenzie

  8. #8
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,626

    Re: Problem using the pow() function from math.h

    typically speaking... your program must be written in such a way that it properly handles ALL POSSIBLE VALUES (even extremes) that could be given as input. How to handle "exceptional" values is up to you.

    Any time you get an input your program was not designed to handle "anything" may happen.


    This is true for all programs out there, you're "Lucky" in that you can typically establish valid ranges the hardware will produce.
    handling user input where they can type just anout anything and click just about anywhere in any order typically is a lot more complex.


    it's not unusual to find a program has less code devoted to actual work, and more code in input processing/erroneous input handling.

  9. #9
    Join Date
    Dec 2013
    Posts
    11

    Re: Problem using the pow() function from math.h

    Quote Originally Posted by OReubens View Post
    typically speaking... your program must be written in such a way that it properly handles ALL POSSIBLE VALUES (even extremes) that could be given as input. How to handle "exceptional" values is up to you.

    Any time you get an input your program was not designed to handle "anything" may happen.


    This is true for all programs out there, you're "Lucky" in that you can typically establish valid ranges the hardware will produce.
    handling user input where they can type just anout anything and click just about anywhere in any order typically is a lot more complex.


    it's not unusual to find a program has less code devoted to actual work, and more code in input processing/erroneous input handling.
    OK, I've put in checks to verify that all values leading up to using the pow(x,y) function are behaving themselves. The program runs well for a long time.... However, every once in awhile (hours or more) I get a situation where pow() generates a huge value even though the input values (x and y) look reasonable. One thing that is still slightly off is that from the pow() definition it looks like the variables that it expects should be both double variable types. In my case, the one value that I am feeding it is a constant multiplied by an int variable (i.e. -.027*Ctemp where Ctemp is int). Will this inconsistency get me into trouble? It seems to work at least most of the time. Can this inconsistency create problems in the value that gets calculated?

    Thank you,
    Mike Nycz

  10. #10
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Problem using the pow() function from math.h

    Quote Originally Posted by mikenycz View Post
    OK, I've put in checks to verify that all values leading up to using the pow(x,y) function are behaving themselves. The program runs well for a long time.... However, every once in awhile (hours or more) I get a situation where pow() generates a huge value even though the input values (x and y) look reasonable.
    If the program you're running is anything like the program you posted previously, then there are some things that look suspicious.
    Code:
    int calc_temperature(unsigned char *input, int length)
    {
        int power2=0;
        int output=0;
        int i;
        for (i=0;i<=(length);i++) {
        if (input[i] == '1') {
    Whenever I see a <= as an upper bound of a loop, and the loop variable is used as an index into an array, a red flag goes off. Are you overstepping the boundaries of the array here, causing a memory overwrite? You do this in other places also.

    Let's see how you're calling these functions, not just the functions themselves.

    Regards,

    Paul McKenzie

  11. #11
    Join Date
    Dec 2013
    Posts
    11

    Re: Problem using the pow() function from math.h

    Quote Originally Posted by Paul McKenzie View Post
    If the program you're running is anything like the program you posted previously, then there are some things that look suspicious.
    Code:
    int calc_temperature(unsigned char *input, int length)
    {
        int power2=0;
        int output=0;
        int i;
        for (i=0;i<=(length);i++) {
        if (input[i] == '1') {
    Whenever I see a <= as an upper bound of a loop, and the loop variable is used as an index into an array, a red flag goes off. Are you overstepping the boundaries of the array here, causing a memory overwrite? You do this in other places also.

    Let's see how you're calling these functions, not just the functions themselves.

    Regards,

    Paul McKenzie
    The code where these functions are called is shown in a previous part of this thread. However, I have made some additional changes that check the inputs into the functions. I will post them below....


    if (Input_Buff1[1] == 0x1a){

    for (bytenum=0;bytenum<=3;bytenum++){
    single_byte = Input_Buff1[14+bytenum];
    charbytetostring(single_byte,temp_bin_buff);
    for (j=0;j<=7;j++) {
    Bin_Buff[j+8*bytenum] = temp_bin_buff[j];
    }
    }
    //Find temperature using IEEE 754 format

    if (Bin_Buff[0] == '0') {
    // Calculate exponent value of IEEE 754 number
    Cexp = calc_exp(Bin_Buff);
    //Calculate normalized exponent value of IEEE 754 number
    Aexp = Cexp-127;
    // Check Aexp value
    if (Aexp <0 || Aexp >=8) {
    clear_buffers();
    Aexp=0;
    break;
    }
    //Add "hidden 1 bit" to Temperature_bin
    Temperature_bin[0]='1';
    //Add bits past decimal point to Temperature_bin
    for (i=9;i<=(8+Aexp);i++) {
    Temperature_bin[i-8]=Bin_Buff[i];
    }
    //Calculate Temperature in Deg F
    Ctemp = calc_temperature(Temperature_bin,Aexp);
    //Check calculated temperature
    if (Ctemp < -30 || Ctemp >120) {
    clear_buffers();
    Ctemp=0;
    break;
    }
    //Plug Temp into equation to get equivalent Thermistor value
    //This equation was derived empirically from one of the FA7226 sensors
    expon = powl(e,(-.027*Ctemp));
    Thermistor_val=24658*expon;

    }


    Prior to expon getting very large, the values of Aexp and Ctemp are what I expect them to be (i.e. Aexp = 6 and Ctemp = 71).

    One thing that may be pertinent, The Ctemp variable is declared as int while expon and the powl() function use double. The question is, can the mixing of types in a calculation like this cause problems? Should I convert the Ctemp value to double before using it in the powl() function?

    Thanks,
    Mike Nycz

  12. #12
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Problem using the pow() function from math.h

    Quote Originally Posted by mikenycz View Post
    The code where these functions are called is shown in a previous part of this thread. However, I have made some additional changes that check the inputs into the functions. I will post them below....
    Please format your code to use code tags, as the code you posted is practically unreadable:

    [code]
    Your code goes here...
    [/code]

    Regards,

    Paul McKenzie

  13. #13
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,824

    Re: Problem using the pow() function from math.h

    When posting code, please format it properly first and use code tags. Go advanced, select the code and click '#'.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  14. #14
    Join Date
    Dec 2013
    Posts
    11

    Re: Problem using the pow() function from math.h

    Quote Originally Posted by 2kaud View Post
    When posting code, please format it properly first and use code tags. Go advanced, select the code and click '#'.
    Code:
    	if (Input_Buff1[1] == 0x1a){
    				
    				for (bytenum=0;bytenum<=3;bytenum++){
    					single_byte = Input_Buff1[14+bytenum];
    				charbytetostring(single_byte,temp_bin_buff);
    					for (j=0;j<=7;j++) {
    						Bin_Buff[j+8*bytenum] = temp_bin_buff[j];
    					}
    				}
    //Find temperature using IEEE 754 format
    
    				if (Bin_Buff[0] == '0') {
    // Calculate exponent value of IEEE 754 number
    					Cexp = calc_exp(Bin_Buff);
    //Calculate normalized exponent value of IEEE 754 number
    					Aexp = Cexp-127;
    // Check Aexp value
    					if (Aexp <0 || Aexp >=8) {
    					    clear_buffers();
    						Aexp=0;
    						break;
    					}
    //Add "hidden 1 bit" to Temperature_bin
    					Temperature_bin[0]='1';
    //Add bits past decimal point to Temperature_bin
    					for (i=9;i<=(8+Aexp);i++) {
    						Temperature_bin[i-8]=Bin_Buff[i];
    					}	
    //Calculate Temperature in Deg F
    					Ctemp = calc_temperature(Temperature_bin,Aexp);
    //Check calculated temperature
    					if (Ctemp < -30 || Ctemp >120) {
    					   	clear_buffers();
    						Ctemp=0;
    						break;
    					}
    //Plug Temp into equation to get equivalent Thermistor value
    //This equation was derived empirically from one of the FA7226 sensors	
    //					expon = powl(e,(-.027*Ctemp));
    					expon = exp(-.027*Ctemp);
    					Thermistor_val=24658*expon;
    //					Thermistor_val=24658*pow(e,(-0.027*Ctemp));
    //Convert Thermistor_val to hex values needed for message					
    					int junk2;
    					int junk = Thermistor_val;
    					char Thermistor_hexlo = junk;
    					for (i=0;i<=7;i++) {
    						junk2 = (junk >> 8);
    						}	
    					char Thermistor_hexhi = junk2;
    //Check Thermistor hex values
    					char bad_data = 0xff;
    					if (Thermistor_hexhi == bad_data && Thermistor_hexlo == bad_data) {
    						clear_buffers();
    						Thermistor_val=0;
    						Thermistor_hexhi = 0x00;
    						Thermistor_hexlo = 0x00;
    						expon = 0;
    						while(1){}
    						break;
    					}
    Here it is...

  15. #15
    GCDEF is offline Elite Member Power Poster
    Join Date
    Nov 2003
    Location
    Florida
    Posts
    12,635

    Re: Problem using the pow() function from math.h

    Formatting should make sense.

    Your calls to pow are commented out, so it's unlikely that is your current code.

    What's the point of while(1){}?

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured