View previous topic :: View next topic |
Author |
Message |
alan
Joined: 12 Nov 2012 Posts: 357 Location: South Africa
|
#define evaluation |
Posted: Thu Jul 18, 2013 4:33 am |
|
|
Why does the following expression evaluate to 99 instead of 100
Tested with V1.141 and V5.009
Code: |
#define Tcy (unsigned int64)(2e9)/((unsigned int64)(20000000))
|
Thanks |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19509
|
|
Posted: Thu Jul 18, 2013 6:31 am |
|
|
Because rounding from a float to an integer, clips downwards. So it becomes 1999999999/20000000, which in integer arithmetic is 99.
'2E9', is always a float value.
You don't need the casts.
Just use 2000000000/20000000.
Best Wishes |
|
|
alan
Joined: 12 Nov 2012 Posts: 357 Location: South Africa
|
|
Posted: Thu Jul 18, 2013 9:11 am |
|
|
Thanks
Just needed to add an L.
2000000000L/20000000L
Regards
Alan |
|
|
alan
Joined: 12 Nov 2012 Posts: 357 Location: South Africa
|
|
Posted: Sat Jul 27, 2013 2:59 am |
|
|
Still battling with #define
I have the following
Code: |
#define CAPACITY 40
#define IFLOAT CAPACITY * 1.57
if(IOut < IFLOAT )
itoa(IFLOAT,10,ID0str);
|
This produce the following asm
Code: |
.................... itoa(IFLOAT,10,ID0str);
MOV #A,W4 : W4 = A
MOV W4,10AA : [10AA] = W4
MOV #3E,W4 : W4 = 3E <---- This is the correct value, thus evaluate OK
MOV W4,10A6 : [10A6] = W4
CLR 10A8 : [10A8] = 0
MOV #105C,W4 : W4 = 105C
MOV W4,10AC : [10AC] = W4
CALL 1384 :
|
and IOut is declared as uint16_t
Code: |
.................... if(IOut < IFLOAT ) {
MOV 1008,W0 : W0 = [1008]
MOV #0,W1 : W1 = 0
MOV #0,W2 : W2 = 0
MOV #0,W3 : W3 = 0
CALL 1744 :
MOV #6667,W4 : W4 = 6667
MOV #6666,W5 : W5 = 6666
MOV #6666,W6 : W6 = 6666
MOV #404F,W7 : W7 = 404F
CALL 17A8 :
BRA NC,18BA : Branch if not carry (or Borrow)
|
If I replace IFLOAT with 63 it works fine.
How can I get the compiler to do the comparison right.
Tested with V5.010 and V4.141. Listings above are for the V1.141
Regards
Alan |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Jul 27, 2013 10:29 am |
|
|
Post a test program that we can run in MPLAB simulator.
It must be compilable and very short. Something like this:
Code: | #include <16F887.h>
#fuses INTRC_IO, NOWDT
#use delay(internal=4M)
#use rs232(baud=9600, UART1, ERRORS)
//==========================================
void main()
{
float IOut = 10.0;
#define CAPACITY 40
#define IFLOAT CAPACITY * 1.57
if(IOut < IFLOAT )
printf("IOut < IFLOAT\r");
else
printf("IOut is not < IFLOAT\r");
while(1);
} |
Aside from that, the standard, safe way to define math expressions
other than individual constants is to enclose them in parentheses like this:
Code: | #define IFLOAT (CAPACITY * 1.57) |
|
|
|
alan
Joined: 12 Nov 2012 Posts: 357 Location: South Africa
|
|
Posted: Sat Jul 27, 2013 11:16 am |
|
|
Thanks PCM
Didn't know MPLAB had an UART monitor. Yes the code above does give the expected result, was a fault somewhere else. I stopped at this funny comparison and thought that may be the problem.
The parentheses also did the job together with the following cast of the constant. The asm are now what I expected in the 1st place.
Code: | if(IOut < ((uint16_t) IFLOAT) |
Thanks again for taking the time.
Regards
Alan |
|
|
|