PDA

View Full Version : The sloppyness of FloatToStr!



WILL
30-07-2003, 09:38 PM
Ok take a look at the following code:
MrHappyString := FloatToStr(10000);
ShowMessage(MrHappyString);

Ok looks rather simple right? Well, $10 bucks says it'll return '9999.999843524425' or some other crap. :?

For my purposes I require a simple and *accurate* conversion of a int/real value to a string with no trailling 0s or unrequired decimal point.

Does anyone have some code suggestions to replace the FloatToStr function?

BlueCat
30-07-2003, 10:32 PM
Have you tried the format function? I use it like this:


lblFPS.Caption := Format ('%4.0f fps', [fps]);


eg. 28.345686797 would give you '28 fps'

WILL
30-07-2003, 10:35 PM
Wow, fast reply. :)

Ok I'll give it a try...

WILL
30-07-2003, 10:55 PM
Crap... still does it. I think it's because I'm trying to pass it as a general number... ie. Format('%g', [RealVar]);

See what I require is that if the Real holds the value of 10 then it'll return a string that says '10'. However if the Real holds a value of 25.75 then the string will be simply '25.75'. Either case, same line of code.

cairnswm
31-07-2003, 07:29 AM
label1.Caption := FormatFloat('###0.##',25.75);
label2.Caption := FormatFloat('###0.##',10);
label3.Caption := FormatFloat('###0.##',0.75);

Traveler
31-07-2003, 09:11 AM
Instead of FloatToStr, you could also try FloatToStrF

like this:


label1.Caption := FloattostrF(12345.6789,fffixed,7,2);

which results in 12345,68

WILL
31-07-2003, 04:46 PM
cairnswm: You da man! :D It worked finally. I was starting to think that there was something wrong with either Delphi(Delphi 5 Standard) or my processor(PIII 800 laptop)... :?

Traveler: Thanks I did try it, but I need to remove unwanted decimal points and 0s. Reason being is that this is for a script engine that has finished it's evaluation of a parameter and needs to return the resulting value to a tokenized symbol to be properly executed with all processed math functions.

Off-Topic-ish :arrow: LOL This thing has been getting more and more complicated by the feature. It would seem that script engines aren't the easiest things to do. But it's a damn cool feature to a game. ;)

Alimonster
04-08-2003, 10:45 AM
Keep in mind the nature of floating point numbers. For an example in base-10 -- how can you directly represent a number such as (1/3) with a finite amount of digits (remembering that those threes will keep going...). The same applies for singles/doubles in base-2 -- there are some numbers you can't represent exactly with the allocated amount of bits, so there will be some round-off error creeping in sometimes. Now, I'm not sure that this is the case here, but it may well be that your given numbers coincidentally have this problem. If you increase your precision (from singles to doubles or extended) and the problem goes away then you're fit to go.

The above is also the same reason that you shouldn't compare two floating point numbers directly (if a = b), but should always use an epsilon instead (maybe something like (if abs(a - b) < epsilon) where epsilon is a smallish number (maybe 1e-6 or something), off the top of my head).

Maybe the above doesn't apply in your case, though. At least you've found a solution!

Incidentally, would the following not do what you wanted?

procedure TForm1.Button1Click(Sender: TObject);
var
str: string;
begin
str := Format('%4.2f', [24.342343]);
ShowMessage(str);
end;

WILL
04-08-2003, 09:20 PM
Thanks for the post Ali, some information there.

As for your code; Like Traveler's suggestion, it would leave me with two possibly unwanted decimal points where I may need it to be rounded off to an Integer when converted back to a string. Thanks though.