| Formatting a float to a string | 
        
        
            
                | Cheree Bury ChereeMotion Owner Join date: 6 Jun 2007 Posts: 666 | 06-29-2008 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 | 06-29-2008 14:32 (string) 1.258975648842135484310135454 | 
        
            
                | Lee Ponzu What Would Steve Do? Join date: 28 Jun 2006 Posts: 1,770 | 06-29-2008 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 | 06-30-2008 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 | 07-01-2008 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 | 07-01-2008 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 | 07-01-2008 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 | 07-01-2008 07:37 I tried to make a function which formats a number with thousand-separators 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 | 07-02-2008 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 | 07-02-2008 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 | 07-02-2008 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 | 07-02-2008 09:29 From: Dora Gustafson One bit is for the sign so 23 bits are left for digitsBut 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 32-bit float is approx ±1.4e-45, which would take many more than 6 decimal places to represent. | 
        
            
                | Ordinal Malaprop really very ordinary   Join date: 9 Sep 2005 Posts: 4,607 | 07-02-2008 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 | 07-05-2008 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); } |