Int64, json and rounding errors

Hi there, I spend a lot of time syncing between devices with a DB / files storing time stamps to work out who has the most up to date data.

Not ideal but mostly functional.

I’m using the unreal json system to store the timestamps. Original the timestamps are uint64s, the GetTicks of the UTC time at the time the file gets modified.

I’m getting what look like rounding errors for instance 636161691044680000 saved then loaded is 636161691044679936 when next read - suspiciously 64 off - the difference if you remove the bottom 8 bits.

The Json code seems to drive all numbers through a double.

Anyone faced this problem or similar? I’ll probably round my time stamps off to see if that helps but is there a decent way to get an accurate uint64 into json as a number not a string field?

And for more information the function I’m using is SetNumberField.

Example code:

void WriteJSon(FJsonObject &jsonObject)
		{
			jsonObject.SetNumberField("Time", Time);
			jsonObject.SetNumberField("Type", Type);
			jsonObject.SetStringField("System", System);
			jsonObject.SetStringField("MessageBody", MessageBody);
		}

My current thought is that this should be considered a bug in the json code - it should be capable of reading the same values that were written and if not should give you a decent error.

The solution seems to be to specialize FJsonValueNumber for integers - FJsonValueInteger.

Here’s a demo piece of code that demonstrates failures:

auto curTime = FDateTime::UtcNow().GetTicks();
	int iPassed = 0;
	int iFailed = 0;
	for (int i = 0; i < 10000; i++)
	{
		uint64 testIn = curTime + i;
		testContainer.SetNumberField("testValue", testIn);
		uint64 testOut = testContainer.GetNumberField("testValue");
		if (testIn == testOut)
		{
			iPassed++;
		}
		else
		{
			iFailed++;
		}
	}

Hi theonecalledtom,

This is somewhat similar to another issue that I looked into related to Json numerical values a few months ago. You are correct that the storing of Json numerical values as a double can affect the accuracy of large uint64 values. I have entered UE-39355 to ask that a new Json value be considered that can store uint64 values.

Thanks for the feedback - it didn’t look too hard to build in proper integer support. If I need the accuracy I can work around using strings but will avoid that until forced as it changes the json format.