Formatting a float to a string

Cheree Bury
ChereeMotion Owner
Join date: 6 Jun 2007
Posts: 666

06292008 12:39
It seems like this should be available, but I can't seem to find it.
I need to convert a floating point number to a string. I want to set the number of decimal places, and trim the zeroes off of both sides. I would think this would have been written hundreds of times.
Does anyone have it? or am I gonna have to write it?

Osgeld Barmy
Registered User
Join date: 22 Mar 2005
Posts: 3,336

06292008 14:32
(string) 1.258975648842135484310135454

Lee Ponzu
What Would Steve Do?
Join date: 28 Jun 2006
Posts: 1,770

06292008 15:17
Another common trick is to pass the float thru an integer. So, if you want two decimal places you do something like
float x = 3.1415926 integer i = 100 * x; // i will be 314 x = 0.01 * i;
or
x = 0.01 * (integer)(100 * x);
You can truncate the string if you like, too.
_____________________
So many monkeys, so little Shakespeare.

Cheree Bury
ChereeMotion Owner
Join date: 6 Jun 2007
Posts: 666

06302008 04:52
Thanks for your responses,
I guess I wasn't very clear about my request. What I was hoping for would be something like Visual Basic's Format function. Maybe not as elaborate, but somewhat similar.
Maybe I will start coding it; and hope that Mono shows up soon.

Very Keynes
LSL is a Virus
Join date: 6 May 2006
Posts: 484

07012008 01:06
Mono should be up next month, but it wont help you as we will not have any access to it other than via LSL and it has been stated several times that there will be no language changes so as to ensure 100% compatability between scripts Compiled to MONO and scripts compiled to LSLRuntime. So go a head, create the function and post it in the Library, I am sure many others will make use of your work.

Haruki Watanabe
llSLCrash(void);
Join date: 28 Mar 2007
Posts: 434

07012008 03:33
I didn't test this inworld, so it might need some changes (and, as usual, I'm sure that there's a more elegant solution)...
[Edit] Nice try  but it doesn't work... :( I'll elaborate a little more on this an repost the script later.

Jesse Barnett
500,000 scoville units
Join date: 21 May 2006
Posts: 4,160

07012008 07:26
The easiest, least intensive solution is what Lee posted. There are no trim right/trim left functions.
_____________________
I (who is a she not a he) reserve the right to exercise selective comprehension of the OP's question at anytime. From: someone I am still around, just no longer here. See you across the aisle. Hope LL burns in hell for archiving this forum

Haruki Watanabe
llSLCrash(void);
Join date: 28 Mar 2007
Posts: 434

07012008 07:37
I tried to make a function which formats a number with thousandseparators and free configurable decimal separator.
Would result in something like 4'123'456,735 (instead of 4123456.735)
Tried to do it with some typecasting instead of multiplication and found out that typecasting from a float to a string fails miserably.
Try this:
float test = 8.123456; llOwnerSay("TEST: " + (string)test);
Will result in 8.123456
float test = 18.123456; llOwnerSay("TEST: " + (string)test);
Will result in 18.123455
float test = 118.123456; llOwnerSay("TEST: " + (string)test);
Will result in 118.123459
LSL sucks...

Cheree Bury
ChereeMotion Owner
Join date: 6 Jun 2007
Posts: 666

07022008 05:40
From: Lee Ponzu Another common trick is to pass the float thru an integer. So, if you want two decimal places you do something like
float x = 3.1415926 integer i = 100 * x; // i will be 314 x = 0.01 * i;
or
x = 0.01 * (integer)(100 * x);
You can truncate the string if you like, too. This is a common way of truncating the numbers, but it doesn't finish the job. When I use this procedure, my resulting string = 3.1400000 when I want it to be 3.14 And when the number is 3.0000000, I want it to output 3.0 (I do not want to truncate that final 0.) So I will work on it (and pass the resulting code here when I have it.) Thanks

Domino Marama
Domino Designs
Join date: 22 Sep 2006
Posts: 1,126

07022008 06:26
string formatFloat( float num, integer places ) { float f = llPow( 10.0, places ); integer i = llRound(num * f); return (string)((integer)(i / f)) + "." + llGetSubString((string)i , places, 1); }
you could set a string to the return value and check for trailing 0s if you don't like the fixed format.
Edit: Forgot to mention. This way fails for values between 0.099999 and 0.0999999, for my use this wasn't an issue. it's an easy patch if you need the full range:
string formatFloat( float num, integer places ) { float f = llPow( 10.0, places ); integer i = llRound(num * f); string s = "00000" + (string)i; // number of 0s is max places value  1 return (string)((integer)(i / f)) + "." + llGetSubString( s, places, 1); }

Dora Gustafson
Registered User
Join date: 13 Mar 2007
Posts: 779

07022008 06:36
From: Haruki Watanabe LSL sucks... aha... One of the conditions in LSL are 32bit floats, 8 for the exponent and 24 for the mantissa. One bit is for the sign so 23 bits are left for digits: 11111111111111111111111binary equals 8388607decimal. That is 7 decimal digits! More decimal digits can arise from the binary to decimal conversion but give no sense.
_____________________
From Studio Dora

Deanna Trollop
BZ Enterprises
Join date: 30 Jan 2006
Posts: 671

07022008 09:29
From: Dora Gustafson One bit is for the sign so 23 bits are left for digits But the mantissa is assumed to be preceded by a 1 in all cases except when the exponent field is 127. (Note, that's a binary exponent, 2^n, not a decimal exponent). So for the vast majority of applications, the mant is effectively 24 bits. But as you yourself pointed out in another thread, extremely large negative exponent values are possible (specifically, binary 126), so the smallest decimal value expressible by a 32bit float is approx ±1.4e45, which would take many more than 6 decimal places to represent.

Ordinal Malaprop
really very ordinary
Join date: 9 Sep 2005
Posts: 4,607

07022008 09:37
An automatically truncating float to string function, looking backwards from the last digit: string float2string(float f) { string s = (string)f; string digit = ""; do { if (digit == "0") s = llGetSubString(s, 0, 2); digit = llGetSubString(s, 1, 1); } while (digit == "0"); if (digit == ".") s = s + "0"; return s; }
_____________________
http://ordinalmalaprop.com/forum/  visit Ordinal's Scripting Colloquium for scripting discussion with actual working BBCode!
http://ordinalmalaprop.com/engine/  An Engine Fit For My Proceeding, my Aethernet Journal
http://www.flickr.com/groups/slgriefbuild/  Second Life Griefbuild Digest, pictures of horrible ad griefing and land spam, and the naming of names

Cheree Bury
ChereeMotion Owner
Join date: 6 Jun 2007
Posts: 666

07052008 08:56
From: Domino Marama string formatFloat( float num, integer places ) { float f = llPow( 10.0, places ); integer i = llRound(num * f); return (string)((integer)(i / f)) + "." + llGetSubString((string)i , places, 1); }
you could set a string to the return value and check for trailing 0s if you don't like the fixed format.
Edit: Forgot to mention. This way fails for values between 0.099999 and 0.0999999, for my use this wasn't an issue. it's an easy patch if you need the full range:
string formatFloat( float num, integer places ) { float f = llPow( 10.0, places ); integer i = llRound(num * f); string s = "00000" + (string)i; // number of 0s is max places value  1 return (string)((integer)(i / f)) + "." + llGetSubString( s, places, 1); } I was just working on this problem. Thanks for the update. Now, the final problem: negative numbers don't work. 0.033699 comes out as 0.34 (with places=3) Update: I have modified your code to allow for negatives: string formatFloat( float num, integer places ) { string negSign = ""; if (num < 0.0) negSign = ""; float f = llPow( 10.0, places ); integer i = llRound(llFabs(num) * f); string s = "00000" + (string)i; // number of 0s is max places value  1 return negSign + (string)((integer)(i / f)) + "." + llGetSubString( s, places, 1); }
