CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

break float number to get separate numbers.
Goto page Previous  1, 2
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Jun 21, 2010 11:58 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Jun 22, 2010 1:32 am     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Jun 22, 2010 1:40 am     Reply with 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.
hayee



Joined: 05 Sep 2007
Posts: 252

View user's profile Send private message

PostPosted: Tue Jun 22, 2010 6:29 am     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Jun 22, 2010 7:00 am     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Jun 25, 2010 2:18 am     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Jun 25, 2010 3:51 am     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Oct 12, 2010 5:28 am     Reply with quote

Can I break a floating number 999999.99 into separate integer using sprintf command or not.
Ttelmah



Joined: 11 Mar 2010
Posts: 19553

View user's profile Send private message

PostPosted: Tue Oct 12, 2010 9:02 am     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Oct 12, 2010 10:35 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Oct 13, 2010 2:04 am     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Oct 13, 2010 2:28 am     Reply with quote

Thanks Ttelmah.
Would you please give me some good links for understanding floating point numbers. Smile

So what should i do to solve my problem?
hayee



Joined: 05 Sep 2007
Posts: 252

View user's profile Send private message

PostPosted: Tue Feb 08, 2011 4:39 am     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Mar 22, 2011 7:01 am     Reply with quote

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.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page Previous  1, 2
Page 2 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group