Writing / loading a float to / from disk?

Started by LeChuck, Thu 20/09/2007 10:45:41

Previous topic - Next topic

LeChuck

I want to create a running game where the distance ran is measured with the help of a float value with two decimals. My problem is writing and reading this value to and from disk.

// room header
float stepcountinmeters = 0.00;
float stepcountinfeet = 0.00;

//rep exec
if (countdown == 0) { //game is finished
            float hiscore = stepcountinmeters;
   float hischandle = FileOpen("hiscore.dat", FILE_READ);         
   if ((hischandle == 0) || (hiscore > hischandle)){
   FileWriteInt(hischandle, hiscore);
            }
            FileClose(hischandle);
           
            Wait(40);
            cEgo.ChangeRoom(1);
}

Getting the obvious "cannot convert float to int" error when compiling, and that is expected, really. I know I can't use FileWriteInt to write a float value with, but what are my options here? Converting the float value to a string and then back again to be able to compare the numbers (for determining if the current score is the highscore)? I tried this, but it was a catastrophic failure.

I really do not want to lose the two decimal numbers by converting to an int.

Ashen

#1
Will it always be 2 decimal places (or at least, is that all you're interesed in)? If so, what if you multiply the float by 100.0, and covert that to an int. Then you should be able to read it back, convert to float and divide by 100.0.

Out of curiosity, how exactly was coverting to a String "a catastrophic failure"? By default, I think AGS uses 6 decimal places, so '2.25' would be copied to a String as '2.250001'; but, you can get around this using the %.Xf String formatting method, e.g.:
Code: ags

String Temp = String.Format("%.2f", my_float);


Would convert the float, and keep it to 2 dps. I haven't tested either of these with writing/reading files, though.

Oh, and what version are you using? You've got the old style (pre 2.7) File functions in there, but float is only supported in 2.7 and up.
I know what you're thinking ... Don't think that.

Khris

String s=String.Format("%.2f", f);

float f=s.AsFloat;
Btw, you can't write to AND read from a file without closing and re-opening it first.
Look up File.Open.

And what exactly does "catastrophic failure" mean? Did you get error messages...?

Edit: Ashen beat me.

Gilbert

Well I think there're many possible ways, depending on your needs, for example:
1. If you only need to keep a certain number of decimal points, say 2 decimal points:
   (a) when written to file:
         multiply the number by 100.0,
         convert it to an int and
         write it to file
   (b) when reading it back:
         read it as int,
         convert it to float and then
         divide it by 100.0
2. Convert it to string (are you sure this won't work? How did you do it?):
   (a) when written to file:
         convert it to String by something like String tmpstr = String.Format("%f", hiscore);
         write it to file as String
   (b) when reading it back:
        read it as String, say String tmpstr = hischandle.ReadStringBack();
        convert it to float via hiscore = tmpstr.AsFloat();

I think it's fair to include direct read/write functions for float though, feel free to suggest this in the Technical Forum if you like.

Ashen (and KhrisMUC :P)  beated me to that, but I'll just post.

Ashen

Well, between the three of us we've given a pretty complete answer, I'd say...
I know what you're thinking ... Don't think that.

FSi++

Or you can use fixed-point arithmetics and store it as an int everywhere dividing it by 100 when necessary. That will improve the accuracy of computation due to the way ints and floats are stored by AGS.

SMF spam blocked by CleanTalk