![]() |
|
Saving Floats |
Michael Jensen
Member #2,870
October 2002
![]() |
Ok, so a while back, I think KittyCat had posted, a method of saving floats (can't find it now) that basically involved some division, seperating it into two peices, and then saving each peice individually... it was kind of complicated but only like 5 lines or so of code... If anybody has any idea what I'm talking about, reposting this code would be greatly appreciated... The reason for it, instead of just saving 4 bytes from memory was for cross platform compatability... (not all compilers adhere to the same standards or some such...) Anyway, the reason I want it is because I'm writing a game in VB.NET (using allegro's file packing routines for saving data) that will save maps/tilesets to files on disk, and I need to save a single (a float is called a single in VB.) to a file. -- I've written some string/bitmap saving functions that seem to work pretty good, but saving with single.ToString()/loading with Single.Parse(x) is probably pretty bad for accuracy... Help! EDIT: Kitty Cat said:
To save a float/double:
|
Kitty Cat
Member #2,815
October 2002
![]() |
I can't gaurantee what kind of accurcy you'll get with that, though. If you know the size of the float, and know that floats will be the same endianess as integers, you can use a cast, though: void save_float(PACKFILE *pf, float f) { pack_iputl(pf, *(uint32_t*)&f); } float load_float(PACKFILE *pf) { int num = pack_igetl(pf); return *(float*)# }
-- |
Michael Jensen
Member #2,870
October 2002
![]() |
Since it's VB I can't guarantee the variable size of a single, or an int -- I got it working, and I also notice the evil accuracy. Thank you... 1/.34 = aprox 3, 1/3 = .333-> But that's good enough. -- Does Floor always round towards 0, or round down?
|
Jonatan Hedborg
Member #4,886
July 2004
![]() |
floor clips any decimals afaik.
|
Fladimir da Gorf
Member #1,565
October 2001
![]() |
Floor rounds always down, ceil always up. A cast rounds towards zero. OpenLayer has reached a random SVN version number ;) | Online manual | Installation video!| MSVC projects now possible with cmake | Now alvailable as a Dev-C++ Devpack! (Thanks to Kotori) |
Michael Jensen
Member #2,870
October 2002
![]() |
Ok, so it seems like this will work with negative numbers also then -- that's good. value = -3.5 fval = -4 {floor(value)} pval = 2 {1/(value-fval)} /* ---------------------------- */ output = -3.5 {fval + (1/pval)} Looks good.
|
gillius
Member #119
April 2000
|
Every computer I have ever programed on uses IEEE-754 format -- Intel, PowerPC, Motorola, SPARC, UltraSPARC. You can just save the data in binary form. I don't know if software emulators for ARM use IEEE-754, but I wouldn't be surprised if they did. If you are truly concerned about being able to load it, you can write an IEEE-754 loader in portable C or you can save as text. Gillius |
Michael Jensen
Member #2,870
October 2002
![]() |
When you save as text it rounds it anyway, and the only "binary" save method I have from the allegro packfile routines that doesn't require the data to be a pointer is save int32, int16, and int8 (char/byte) -- I could overload the int32 method to support single (float) and just hope that the marshalling converts it, but that could have some really evil side effects... edit:
|
gillius
Member #119
April 2000
|
You don't have to do rounding to print out a float. The Java language I believe specifies that a float is printed to contain exactly the number of digits that it takes to completely distinguish one float from another, and no more. In this manner, printing a float as text and reading it back in is an exact copy. Gillius |
Michael Jensen
Member #2,870
October 2002
![]() |
Hmmm... I guess that makes sense -- There is probably a way in VB.NET also, probably one of the ToString() format strings... I'll have to look into that. I guess I'm just soo used to string formatters messing with my floats...
|
|