View unanswered posts | View active topics It is currently Wed Nov 26, 2014 10:53 pm






Reply to topic  [ 8 posts ] 
truncate float numbers and converte to a string 
Author Message
Guru
User avatar

Joined: Sat Mar 01, 2008 12:52 pm
Posts: 1030
Post truncate float numbers and converte to a string
hello to all,

how can I truncate a float to just 2 decimals before converting it to a string?

e.g. , I have float variables
Code:
f=8.1234567
g=12.345567


if I convert these new values "f, g" into strings, e.g.
Code:
fstring=(string)f;

this surely works, but of course I always get all of the decimals - but I only need just 2 decimals for the string operations.

How can I do this float decimal truncation?

_________________
regards,
HaWe aka Ford
#define S sqrt(t+2*i*i)<2
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;task main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PutPixel(x,y);}}}while(1)}


Sat Aug 02, 2008 4:41 am
Profile
Rookie

Joined: Wed Jun 25, 2008 6:07 pm
Posts: 46
Post 
Ford,

You can exploit the truncation that happens when you cast a float to an int to accomplish that:

1) Multiply the float by 100
2) Cast it to an int (which will truncate the undesired fractional part)
3) Cast it back to a float
4) Divide by 100

Code:
f = ((float)((int)(f * 100))) / 100;


For more (or less) digits, just alter the number you use for multiplying and dividing.

For this to work, your numbers need to be small enough that you don't overflow the int when multiplying by 100. If that's a problem, you should do something more like this:

Code:
result  = (float)((int)f);
result += (float)((int)((f - result) * 100)) / 100;


It basically the same as what was above, except that it keeps the non-fractional part of the float out of multiplication operations -- allowing you to have bigger numbers without overflow.


Sat Aug 02, 2008 10:19 am
Profile
Guru
User avatar

Joined: Sat Mar 01, 2008 12:52 pm
Posts: 1030
Post 
hi,
thx a lot, it's fine.
I first thought.

But in fact, if you have
f=12.34567
and calculate with your formula
f = ((float)((int)(f * 100))) / 100;

you subsequently get f=12.34000, and
NOT: 12.34 <- this is what I needed!

I actually thought there should be a format function like ""%5.2f" as you use it as a format string in the printf command.
But your suggestion is fine, I'll take this, thx again!

_________________
regards,
HaWe aka Ford
#define S sqrt(t+2*i*i)<2
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;task main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PutPixel(x,y);}}}while(1)}


Sun Aug 03, 2008 4:11 pm
Profile
Rookie

Joined: Wed May 21, 2008 12:37 pm
Posts: 8
Location: Rio de Janeiro
Post 
Hi everyone!

I have two ideas. But since I am at the very beginning of using RobotC, they might be just stupid...

1) Is the 'string' data type just a normal array of characters terminated by a '0' char? If yes, you could type-cast the number that results from the idea of AvidProgrammer into a string variable and change the place of the string terminator:

Code:
float fValue1, fValue2;
string sValue;

fValue1 = 12.34567;
fValue2 = ((float)((int)(fValue1 * 100))) / 100; // fValue2 = 12.34000
sValue = (string)fValue2; // now we have sValue = "12.34000"
sValue[5] = 0; // and finally sValue = "12.34"


---

2) Browsing the RobotC help, I found that there is a function called
StringFormat(sDest, sFmtSpec, nParm1, nParm2)
that might work.

Using this, the code would become much simpler:

Code:
float fValue1;
string sValue;

fValue1 = 12.34567;
StringFormat(sValue, "%.2f", fValue1);


---

Could you, Ford Prefect, please test these two ideas? I am curious to know if they would work... (I do not have access to my NXT right now...).

Best regards to you all,
Eduardo.


Thu Aug 07, 2008 7:47 am
Profile WWW
Creator
Creator

Joined: Fri Feb 09, 2007 9:21 am
Posts: 615
Post 
Internal float representation uses binary arithmetic. Decimal fractions do not always fit into nice "binary value" storage so you get the "artifacts" you're experiencing. No amount of "* 100" and "/ 100" will overcome this immutable fact.

Sorry.


Fri Aug 08, 2008 1:22 am
Profile
Rookie

Joined: Wed May 21, 2008 12:37 pm
Posts: 8
Location: Rio de Janeiro
Post Re: truncate float numbers and converte to a string
I am sorry, Mr. Swan, but I can not understand your commentary. I have been a C/C++ scientific programmer for some years now, and nevertheless your point completely escapes me...

If all Ford Prefect wants is a string variable with the ASCII representation of a float truncated to 2 decimals, why would neither of my ideas work? I know my first idea would not work if string data types, in RobotC, are not null-terminated arrays of char (I really do not know if they are). But what is the problem with my second idea? Would rounding be the issue??

Please, elaborate on your last post. Thank you.

Best regards,
Eduardo.


Mon Aug 11, 2008 9:44 am
Profile WWW
Creator
Creator

Joined: Fri Feb 09, 2007 9:21 am
Posts: 615
Post Re: truncate float numbers and converte to a string
Yes, you're right. If you want a float variable with just two decimal points in the string you can simply use standard "int" to "string" / "char" formating routines.

But that was not the request. It was "how can I truncate a float to just 2 decimals before converting it to a string?" which is a different problem. I'm not sure why you would need this, but that was the problem.

Internal binary representation of of numbers does not always allow for exact representation of decimal numbers and there is no way around this.


Mon Aug 11, 2008 11:59 am
Profile
Guru
User avatar

Joined: Sat Mar 01, 2008 12:52 pm
Posts: 1030
Post Re: truncate float numbers and converte to a string
hello,
@Dick Swan: yes, that was my request. But actually that is exactly was the float-to-string-truncating function does:
first: round and truncate to 2 decimals,
second: convert to string

I wrote it that way because I wanted to avoid the other turn: first convert to string, and then truncate, because it's too fussy to find the decimal point in the string, count two decimals further, and than cut off the rest; beyond it, then there would be rounding mistakes.

EDIT:
and before that I wrote:
Ford Prefect wrote:
I actually thought there should be a format function like ""%5.2f" as you use it as a format string in the printf command.

I didn't find the RobotC command for this, cause the correct C command is
Code:
sprintf(StringVar, "%f\n", FloatVar);

=> would you be kind enough to use the original C commands, please? Your RobotC sometimes is too much kind of jabberwocky...

@Eduardo del Peloso:
thx, the code works fine!
Code:
/* float2string.c */

//*********************************//
#define printf  nxtDisplayTextLine //
#define sprintf StringFormat       //
//*********************************//

float floatVar;
string stringVar;
task main()
{
   floatVar  = 12.34567;
   sprintf(stringVar, "%.2f", floatVar);
   printf(1, "orig.=%f", floatVar);
   printf(3, "string=%s",stringVar);
  while(true) { //
  }
}

the display shows:
Quote:
orig.=12.345670

string=12.35

sic: correctly rounded values!

_________________
regards,
HaWe aka Ford
#define S sqrt(t+2*i*i)<2
#define F(a,b) for(a=0;a<b;++a)
float x,y,r,i,s,j,t,n;task main(){F(y,64){F(x,99){r=i=t=0;s=x/33-2;j=y/32-1;F(n,50&S){t=r*r-i*i;i=2*r*i+j;r=t+s;}if(S){PutPixel(x,y);}}}while(1)}


Mon Aug 11, 2008 12:52 pm
Profile
Display posts from previous:  Sort by  
Reply to topic   [ 8 posts ] 

Who is online

Users browsing this forum: No registered users and 2 guests


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 post attachments in this forum

Search for:
Jump to:  



Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.