Hexfloats

FluffyFreak
Posts: 1343
Joined: Tue Jul 02, 2013 1:49 pm
Location: Beeston, Nottinghamshire, GB
Contact:

Re: Hexfloats

Post by FluffyFreak »

Yeah that sounds like a workable approach, though you can probably do something like:
double valueToSave = 5.0;
SaveAsInteger(static_cast<Uint64>(valueToSave));
or to load:
Uint64 valueLoaded = LoadAsInteger();
double newValue = static_cast<double>(valueLoaded);
I do wish Microsoft would pull their finger out of their collective arse and implement C99, I mean it's C99 ffs, then we could avoid this kind of thing.
laarmen
Posts: 34
Joined: Fri Jul 05, 2013 8:49 am

Re: Hexfloats

Post by laarmen »

I'd be very surprised if the Windows and Linux floating point representation were different. After all, it usually all comes down to hardware, and I dare hope x86 processors all use IEEE floats ?


Also, no need for memcpy. A simple reinterpret_cast should to the trick.
robn
Posts: 302
Joined: Mon Jul 01, 2013 1:11 am
Location: Melbourne, Australia

Re: Hexfloats

Post by robn »

Half the point of the JSON savefile is to sort-of be human readable, so I'd still go with the hexfloats. You might like to just lift some code from a suitably-licensed libc somewhere.
robn
Posts: 302
Joined: Mon Jul 01, 2013 1:11 am
Location: Melbourne, Australia

Re: Hexfloats

Post by robn »

laarmen wrote:I'd be very surprised if the Windows and Linux floating point representation were different. After all, it usually all comes down to hardware, and I dare hope x86 processors all use IEEE floats ?
Its usually down to the options enabled on the platform in question. Here's an interesting article about it: http://christian-seiler.de/projekte/fpmath/

That said, the various options usually affect the results of operations, not the storage format so much. I'm pretty sure we've got all the glitches out between Windows, Mac and Linux these days.
nick
Posts: 85
Joined: Mon Sep 08, 2014 9:24 pm
Location: Plymouth, UK

Re: Hexfloats

Post by nick »

Thanks for your posts :)

I've left and commented out the unsuccessful "save as hexfloat string" code, incase someone can get it working.
I've also left and commented out the usual "save as high-precision decimal & exponent string" code, as a quick fallback incase "save via int" doesn't work on other platforms. It may work as it is, but might require an sprintf format specifier other than "%I32u" or "%I64u" (safest to use unsigned I think, because something odd might happen with the sign bit!)

I've allowed for float and double to each be either 4 or 8 bytes. Won't be difficult to extend to include other sizes if necessary.

I'm going to keep memcpy for now, because I've read a few things about it being the only way to guarantee that the bits are preserved, and it's finally working :)

Code: Select all

std::string DoubleToStr(double val)
{
	// Exact representation (but not human readable).
	static_assert(sizeof(double) == 4 || sizeof(double) == 8, "double isn't 4 or 8 bytes");
	if (sizeof(double) == 4)
	{
		uint32_t intVal;
		memcpy(&intVal, &val, 4);
		char str[16];
		std::sprintf(str, "%I32u", intVal);
		return str;
	}
	else // sizeof(double) == 8
	{
		uint64_t intVal;
		memcpy(&intVal, &val, 8);
		char str[32];
		std::sprintf(str, "%I64u", intVal);
		return str;
	}
}

double StrToDouble(std::string str)
{
	// Exact representation (but not human readable).
	static_assert(sizeof(double) == 4 || sizeof(double) == 8, "double isn't 4 or 8 bytes");
	if (sizeof(double) == 4)
	{
		uint32_t intVal;
		std::sscanf(str.c_str(), "%I32u", &intVal);
		double val;
		memcpy(&val, &intVal, 4);
		return val;
	}
	else // sizeof(double) == 8
	{
		uint64_t intVal;
		std::sscanf(str.c_str(), "%I64u", &intVal);
		double val;
		memcpy(&val, &intVal, 8);
		return val;
	}
}
I'm using std::sprintf and std::sscanf. I didn't realise they existed 'til the other day. The documentation for the default sscanf says "%a" is not supported, which is why I went to the standard lib versions. However, the hexfloat didn't work for std::sscanf either. Are the std:: functions always the same across all platforms?

The documentation for std::sscanf doesn't mention the "%I32u" or "%I64u", but rather "%lu" and "%llu" (which also work) so if need be, a platform #ifdef can be used to select the one that works.
nick
Posts: 85
Joined: Mon Sep 08, 2014 9:24 pm
Location: Plymouth, UK

Re: Hexfloats

Post by nick »

Hi robn, I've been writing my last post while your two have come in.

Yes, I agree about the hexfloats - their precision and compact form, and being human readable (via a hex calculator :) ) make them the ideal choice.

However, I need to move on due to approaching work committments so I'm going to push on and get the loading code written, which shouldn't be too taxing 'cos I've just got to mirror all the saving code (- in theory!)
Hoping to get it done within a week or two :)

Then will either install github (if I'm certain it won't affect tortoisesvn) or merge manually and post the changed files :)

Thanks for the link - will have a proper look tomorrow. But just read that MSVC++ doesn't do double-extended precision - that's a bit rubbish! (I never knew that).
FluffyFreak
Posts: 1343
Joined: Tue Jul 02, 2013 1:49 pm
Location: Beeston, Nottinghamshire, GB
Contact:

Re: Hexfloats

Post by FluffyFreak »

Nick, I have TortoiseSVN, TortoiseHG and TortoiseGit as well the official Git-For-Windows from GitHub all installed on this machine. They won't affect one another at all :)
nick
Posts: 85
Joined: Mon Sep 08, 2014 9:24 pm
Location: Plymouth, UK

Re: Hexfloats

Post by nick »

Hi FluffyFreak, if it's all working for you, then when the time comes I'll install what you've got: Git-For-Windows (not GitHub-For-Windows).
(I have Win 7 64 bit.)
The Git-For-Windows download is "Git-1.9.5-preview20141217.exe" - don't know what "preview" means?
I'll get the JSON load code done and tested first though.
Post Reply