View previous topic :: View next topic |
Author |
Message |
apakSeO
Joined: 07 Dec 2016 Posts: 60 Location: Northeast USA
|
Rounding function does not return any value |
Posted: Thu Aug 16, 2018 1:00 pm |
|
|
CCS compiler v5.074
PIC18F24K40
I found Ttelmah's post from 09/14/2006 on implementing a rounding function for floating point numbers. I tried to implement this code:
Code: |
#include <18F24K40.h>
#device PIC18F24K40
#device ADC=10
#use delay(INTERNAL=2MHZ)
#fuses NOWDT
#fuses NOPROTECT
#fuses NOBROWNOUT
#fuses NOPUT
#include "math.h"
#define round(x,n) (floor(x*(10.0^n)+0.49)/(10.0^n))
float32 num1 = 65.12345;
float32 num1round;
void main(void)
{
num1round = round(65.12345, 3); // Does not matter if var 'num1' used here or explicit float used here
while(1)
{
}
}
|
Code successfully compiles. I run a debug session, and pause the execution. num1round is always zero in the variable Watches tab ( I'm using MPLAB as the IDE, btw)
Any idea as to why this rounding routine is not working in my case?
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19487
|
|
Posted: Thu Aug 16, 2018 1:18 pm |
|
|
Where are you putting the breakpoint to stop and view the variable?.
Remember if you put it on this line, it has not executed yet. |
|
|
apakSeO
Joined: 07 Dec 2016 Posts: 60 Location: Northeast USA
|
|
Posted: Thu Aug 16, 2018 2:59 pm |
|
|
Ttelmah wrote: | Where are you putting the breakpoint to stop and view the variable?.
Remember if you put it on this line, it has not executed yet. |
Not actually using a breakpoint. I start program execution in the debugger. Lines above the while(1) get executed, then I hang around forever in the while(1) loop. So at some point I hit pause in the debugger, and view the values displayed as in the graphic. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9220 Location: Greensville,Ontario
|
|
Posted: Thu Aug 16, 2018 3:14 pm |
|
|
gee I have to ask, why not just send the result to a PC terminal program ?
I've always treated debuggers like simulators...prefer to see real results in the real World.
As an 'aside', are you really running that PIC at TWO MHZ ?Have to wonder how long that code takes to execute !! |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Aug 16, 2018 4:00 pm |
|
|
Try it with the macro for round() as shown below, with the pow() function.
I got the following result:
Test program:
Code: |
#include <18F46K22.h>
#fuses INTRC_IO, NOWDT, BROWNOUT, PUT, NOPBADEN
#use delay(clock=4M)
#use rs232(baud=9600, UART1, ERRORS)
#include "math.h"
#define round(x,n) (floor(x*(pow(10.0,n))+0.49)/(pow(10.0,n)))
float num1round;
//=================================
void main(void)
{
num1round = round(65.12345, 3);
printf("%7.3f\r", num1round);
while(TRUE);
} |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19487
|
|
Posted: Fri Aug 17, 2018 1:38 am |
|
|
Dead right. ^ is XOR in C.
Classic problem of using too many languages... |
|
|
apakSeO
Joined: 07 Dec 2016 Posts: 60 Location: Northeast USA
|
|
Posted: Fri Aug 17, 2018 9:21 am |
|
|
temtronic wrote: | gee I have to ask, why not just send the result to a PC terminal program ?
I've always treated debuggers like simulators...prefer to see real results in the real World.
As an 'aside', are you really running that PIC at TWO MHZ ?Have to wonder how long that code takes to execute !! |
Hahah, I know! 2Mhz actually gives me a fair compromise between power consumption and speed. This is not a time-sensitive application.
For posterity, I timed the pulse output from the following lines. This takes approx. 35ms to execute when the PIC is set to 2MHz:
Code: |
output_high(PIN_C6);
num1round = round(num1, 3);
output_low(PIN_C6);
|
given that num1 is a float32 and num1 = 65.12345 and round() is defined as above in the correction.
Given the modification to using pow() instead of ^ the code now does what it should. Thanks again guys. You da real MVP. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19487
|
|
Posted: Fri Aug 17, 2018 12:07 pm |
|
|
Seriously all the normal complaints about using float do apply. If you only want fixed rounding at three digits, consider instead using an integer:
Code: |
#include <18F46K22.h>
#fuses INTRC_IO, NOWDT, BROWNOUT, PUT, NOPBADEN
#use delay(clock=4M)
#use rs232(baud=9600, UART1, ERRORS)
#include "math.h"
int32 num1round;
//=================================
void main(void)
{
num1round = (65.12345+0.00049)*1000;
printf("%7.3lw\r", num1round);
while(TRUE)
;
}
|
This will take a lot less time and give the same result. |
|
|
|