• AVR Freaks

AnsweredHot!Math operation

Author
Brum
New Member
  • Total Posts : 7
  • Reward points : 0
  • Joined: 2006/09/21 00:41:23
  • Location: 0
  • Status: offline
2019/04/25 07:26:23 (permalink)
0

Math operation

Hi there,


I have a piece of code for a linear interpolation:


uint32_t resTMR1=0;

int32_t temp_ACQ=0;


temp_ACQ1= (  ( ( (resTMR1-POLS_TEMP_MINUS30)*100) / (POLS_TEMP_MINUS20-POLS_TEMP_MINUS30 ) )* (TEMP_MINUS20-TEMP_MINUS30) ) + (TEMP_MINUS30*100) ;


resTMR1 contains the pulses generated by an external sensor, I decided to replace the external sensor with a vector with code testing purposes.


uint16_t VECTOR_TEMP_DEBUG[LIMIT_DEBUG]={26,186,338,494,651,808,1125,1284,1923};

                                            expected result:    -50,-39,-30 -20, -10,    0,    20,   30,    71


When I check if the results are the expected ones I realize they are not.
So I decide to split the operations in order to check what is going on:


uint32_t resTMR1=0;

int32_t temp_ACQ=0;
int32_t temp_ACQ1=0;

int32_t a;
int16_t d;
uint8_t b,c;   


a=((resTMR1-POLS_TEMP_MINUS30 )*100);

b=(POLS_TEMP_MINUS20-POLS_TEMP_MINUS30 );
c=(TEMP_MINUS20-TEMP_MINUS30);

d=(TEMP_MINUS30*100);
            
temp_ACQ= (  ( a / b )* c ) + d ;   (eq.1)


and compare with
temp_ACQ1= (  ( ( (resTMR1-POLS_TEMP_MINUS30)*100) / (POLS_TEMP_MINUS20-POLS_TEMP_MINUS30 ) )* (TEMP_MINUS20-TEMP_MINUS30) ) + (TEMP_MINUS30*100) ;  (eq.2)


with (eq.1) results are as expected but with (eq.2) results are always wrong.
I modified the size for temp_ACQ1 from int32_t to int64_t and the results still wrong.

I checked the brackets and seems to be on place, is there any kind of limitation with intermediate results?

what I am doing wrong?


PIC: 16F18324 + pickit 4 + MPLAB IDE X 5.10
 
Thanks in advance,
 
Marc
 
 
#1
Jim Nickerson
User 452
  • Total Posts : 5892
  • Reward points : 0
  • Joined: 2003/11/07 12:35:10
  • Location: San Diego, CA
  • Status: offline
Re: Math operation 2019/04/25 07:44:16 (permalink) ☄ Helpfulby Brum 2019/04/25 07:56:57
+1 (1)
I have seen similar results.
I have since split the calculations as you have.
I have been pleased the split calculations work.
I no longer combine numerous calculations on one line.
#2
Brum
New Member
  • Total Posts : 7
  • Reward points : 0
  • Joined: 2006/09/21 00:41:23
  • Location: 0
  • Status: offline
Re: Math operation 2019/04/25 07:46:06 (permalink)
0
More tests
Eq.2 seems to have a problem with the negative part for the first subtraction ( (resTMR1-POLS_TEMP_MINUS30)*100)
while  resTMR1 < POLS_TEMP_MINUS30 results are wrong, and when resTMR1 >= POLS_TEMP_MINUS30, results start to be inline,. Values from MPLAB are the same but the decimal representation is wrong. any clue?
 
I made some screenshoots, but I cannot attach it, sorry :(
post edited by Brum - 2019/04/25 07:50:48
#3
Brum
New Member
  • Total Posts : 7
  • Reward points : 0
  • Joined: 2006/09/21 00:41:23
  • Location: 0
  • Status: offline
Re: Math operation 2019/04/25 07:54:09 (permalink)
0
more tests.
 
Eq.2 starts to work when result is >0 so I assume that intermediate operations are unsigned.
#4
1and0
Access is Denied
  • Total Posts : 9040
  • Reward points : 0
  • Joined: 2007/05/06 12:03:20
  • Location: Harry's Gray Matter
  • Status: offline
Re: Math operation 2019/04/25 08:01:12 (permalink)
0
What are the values of those constants?  And how are they defined?
 
#5
Brum
New Member
  • Total Posts : 7
  • Reward points : 0
  • Joined: 2006/09/21 00:41:23
  • Location: 0
  • Status: offline
Re: Math operation 2019/04/25 08:22:00 (permalink)
0
 
#define POLS_TEMP_MINUS30         338    
#define POLS_TEMP_MINUS20         494  
#define TEMP_MINUS30              -30
#define TEMP_MINUS20              -20
#6
1and0
Access is Denied
  • Total Posts : 9040
  • Reward points : 0
  • Joined: 2007/05/06 12:03:20
  • Location: Harry's Gray Matter
  • Status: offline
Re: Math operation 2019/04/25 09:07:09 (permalink) ☼ Best Answerby Brum 2019/04/25 22:16:33
+1 (1)
Brum
uint32_t resTMR1=0;

Change the type of resTMR1 to int32_t.
 
Edit: ... or cast it

temp_ACQ1= (  ( ( ((int32_t)resTMR1-POLS_TEMP_MINUS30)*100) / (POLS_TEMP_MINUS20-POLS_TEMP_MINUS30 ) )* (TEMP_MINUS20-TEMP_MINUS30) ) + (TEMP_MINUS30*100) ;

post edited by 1and0 - 2019/04/25 09:12:06
#7
Brum
New Member
  • Total Posts : 7
  • Reward points : 0
  • Joined: 2006/09/21 00:41:23
  • Location: 0
  • Status: offline
Re: Math operation 2019/04/25 22:17:03 (permalink)
0
you are right 1and0, with the cast is enough.
 
thanks you!
#8
1and0
Access is Denied
  • Total Posts : 9040
  • Reward points : 0
  • Joined: 2007/05/06 12:03:20
  • Location: Harry's Gray Matter
  • Status: offline
Re: Math operation 2019/04/26 03:25:55 (permalink)
+1 (1)
I hope you understand the reason. With resTMR1 as an unsigned long, this
 
    (resTMR1 - POLS_TEMP_MINUS30)
 
performs an unsigned long subtraction with an unsigned long result, and there is NO negative numbers in unsigned. ;)
#9
Brum
New Member
  • Total Posts : 7
  • Reward points : 0
  • Joined: 2006/09/21 00:41:23
  • Location: 0
  • Status: offline
Re: Math operation 2019/04/26 03:44:50 (permalink)
0
as soon as you post your reply I realize that resTMR1 is an unsigned variabl. Thanks!!!
#10
Jump to:
© 2019 APG vNext Commercial Version 4.5