View previous topic :: View next topic |
Author |
Message |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Jun 21, 2010 11:58 pm |
|
|
If you are certain that the characters will always be from '0' to '9', then
this simple ToInt() macro will work:
Code: |
#define ToInt(c) (c - '0')
|
Give it an ASCII character from '0' to '9', and it will return an integer
value from 0 to 9.
Example:
Code: |
int8 result;
int8 value;
value = '9'; // ASCII 9
result = ToInt(value); // Convert ASCII digit to integer
|
|
|
|
hayee
Joined: 05 Sep 2007 Posts: 252
|
|
Posted: Tue Jun 22, 2010 1:32 am |
|
|
What i have done is that store a value in a buffer and then subtract 48 from that value and it is showing correct value.
like
Code: |
int buffer[7];
int thousand,hundred,tens,ones,tenth,hundredth;
float value=9985.23
sprintf(buffer, " %6.2f ",value);
thousand=buffer[0]-48;
hundred=buffer[1]-48;
tens=buffer[2]-48;
ones=buffer[3]-48;
tenth=buffer[5]-48;
hundredth=buffer[6]-48;
|
Is this right? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Jun 22, 2010 1:40 am |
|
|
I can see a minimum of 3 problems in your code. Try to determine
what they are. I'm going to leave the thread. |
|
|
hayee
Joined: 05 Sep 2007 Posts: 252
|
|
Posted: Tue Jun 22, 2010 6:29 am |
|
|
According to your comments ''I can see a minimum of 3 problems in your code" I have reached on the conclusion that
1) It will not work properly when the value is less than 1000
2) because of subtracting the 48 from the buffer may be generate the error.
I want some expalination about " %6.2f " used in the sprintf statement.
Why code is working fine by using 6.2?
When i change this to some other value (like %5.2f) it not works well. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19553
|
|
Posted: Tue Jun 22, 2010 7:00 am |
|
|
How many digits are there in 9999.99?
How many after the decimal point?.
Read the manual on what the values used in the % formats mean.
Ask yourself what the effect of adding a leading '0' in the format would be.
Best Wishes |
|
|
hayee
Joined: 05 Sep 2007 Posts: 252
|
|
Posted: Fri Jun 25, 2010 2:18 am |
|
|
I am unable to understand the function of "%6.2f" in the sprintf statement.
I have write a code and when i change the value after % no change occurs (like %5.2,%4.2 etc)
Code: |
#include <18F252.H>
#include <stdlib.h>
#fuses HS, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#define ToInt(c) (c- '0')
//==========================================
void main()
{
int8 buffer[7];
float value;
int x,y,a,b,c,d,e,f,g,h;
value = 2468.13;
sprintf(buffer,"%6.2f", value);
puts(buffer);
a=ToInt(buffer[0]);
b=ToInt(buffer[1]);
c=ToInt(buffer[2]);
d=ToInt(buffer[3]);
e=ToInt(buffer[4]);
f=ToInt(buffer[5]);
g=ToInt(buffer[6]);
printf("%d",a);
printf("%d",b);
printf("%d",c);
printf("%d",d);
printf("%d",e);
printf("%d",f);
printf("%d",g);
y=a*b;
printf(" %d ", y);
while(1);
} |
when i compiled the program with %6.2f hyperterminal showed me the following values
Quote: |
2468.12
2468-212 8
|
when i compiled the program with %5.2f hyperterminal showed me same values.
Quote: |
2468.12
2468-212 8
|
when i compiled the program with %4.2f hyperterminal showed me same values.
Quote: |
2468.12
2468-212 8
|
As i understand by changing the values after % will also change the values stored in the buffer.Is it?
But when i change this (% values) in my original code it effects the whole code.I am not understanding the behaviour of the function. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19553
|
|
Posted: Fri Jun 25, 2010 3:51 am |
|
|
Try a smaller number.
The point about the first value in the %x.y' format, is it specifies a minimum field width.
If you send a number that it _bigger_ than the field width, the code will automatically make the field bigger (which you are doing with the values you try).
However try (for example), 12.34, with %6.2, then then with %06.2. Then remember that the code you are working with, needs to know _where_ the digits are, and in some of the versions you are working with, won't handle 'non numeric' values.
Best Wishes |
|
|
hayee
Joined: 05 Sep 2007 Posts: 252
|
|
Posted: Tue Oct 12, 2010 5:28 am |
|
|
Can I break a floating number 999999.99 into separate integer using sprintf command or not. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19553
|
|
Posted: Tue Oct 12, 2010 9:02 am |
|
|
If you are using a 'normal' PIC (PIC16/18 etc.), you can't store 999999.99 at all. Maximum precision of a FP number, is about 6.5 digits. With a number this large, the values after the DP, will effectively be garbage....
Best Wishes |
|
|
hayee
Joined: 05 Sep 2007 Posts: 252
|
|
Posted: Tue Oct 12, 2010 10:35 pm |
|
|
I am using pic18f252,
what I understand from 6.5 is that 6 digits before decimal and 5 digits after decimal. Is it right? If yes than my number is in the range 999999.99
What are other options for my required operation? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19553
|
|
Posted: Wed Oct 13, 2010 2:04 am |
|
|
No.
Total number of digits in the number.
So a FP number of 999999.9, is seven digits of accuracy, while 99999.9 is 6. The number are _not_ held in decimal, but binary, and the total accuracy, is about 6 1/2 digits of decimal accuracy.
Best Wishes |
|
|
hayee
Joined: 05 Sep 2007 Posts: 252
|
|
Posted: Wed Oct 13, 2010 2:28 am |
|
|
Thanks Ttelmah.
Would you please give me some good links for understanding floating point numbers.
So what should i do to solve my problem? |
|
|
hayee
Joined: 05 Sep 2007 Posts: 252
|
|
Posted: Tue Feb 08, 2011 4:39 am |
|
|
Quote: | I can see a minimum of 3 problems in your code. Try to determine
what they are. I'm going to leave the thread. |
can anyone tell me what are these problems? |
|
|
hayee
Joined: 05 Sep 2007 Posts: 252
|
|
Posted: Tue Mar 22, 2011 7:01 am |
|
|
I am using sprintf function to break the floating number into seperate numbers.
I have a crystal value of 4Mhz and the sprintf function is taking 20ms, which is too much,my code is like that
Code: |
sprintf(buffer,"%0.2f",total_volume);
if(total_volume<1)
{
data_lcd[8]=0x8A;data_lcd[9]=0x9A;
data_lcd[4]=ad4*16 + ToInt(buffer[3])*1; //show values on particular
data_lcd[3]=ad3*16 + ToInt(buffer[2])*1; // segment
data_lcd[1]=0x10;
}
else if(total_volume>=1 && total_volume<10)//if total volume is <10 values pattern
{
data_lcd[8]=0x8A;data_lcd[9]=0x9A;
data_lcd[4]=ad4*16 + ToInt(buffer[3])*1;//show values on particular
data_lcd[3]=ad3*16 + ToInt(buffer[2])*1;//segment
data_lcd[1]=ad1*16 + ToInt(buffer[0])*1;//
}
else if(total_volume>=10 && total_volume<100)//if total volume is >10 & <100
{ //values pattern
data_lcd[9]=0x9A;
data_lcd[4]=ad4*16 + ToInt(buffer[4])*1;//
data_lcd[3]=ad3*16 + ToInt(buffer[3])*1;//
data_lcd[1]=ad1*16 + ToInt(buffer[1])*1;//
data_lcd[8]=ad8*16 + ToInt(buffer[0])*1;//
}
else if(total_volume>=100 && total_volume<1000)//if total volume is >100 &
{ //<1000 values pattern
data_lcd[4]=ad4*16 + ToInt(buffer[5])*1;//
data_lcd[3]=ad3*16 + ToInt(buffer[4])*1;//show values
data_lcd[1]=ad1*16 + ToInt(buffer[2])*1;//on particular
data_lcd[8]=ad8*16 + ToInt(buffer[1])*1;//segment.
data_lcd[9]=ad9*16 + ToInt(buffer[0])*1;//
}
|
Can someone tell me some other way( memory and delay efficient method ) to solve this issue.i have floating range of 0 to 999.99
I have checked with oscilloscope the timings, only sprintf statement is using 20ms. |
|
|
|