RejectedSoftware Forums

Sign up

how to serialize float with two decimal points with vibe.data.json?

I have CSV source with numbers like 40.94, but after reading it and serializing to JSON I have something like 40.93999862670898 because of float representation, so my JSON file is very big. Is this possible to round it back when serializing?

Re: how to serialize float with two decimal points with vibe.data.json?

How do you serialize your data?

On Tue, 18 Jul 2017 15:07:09 GMT, Alexey Kulentsov wrote:

I have CSV source with numbers like 40.94, but after reading it and serializing to JSON I have something like 40.93999862670898 because of float representation, so my JSON file is very big. Is this possible to round it back when serializing?

Re: how to serialize float with two decimal points with vibe.data.json?

On Wed, 19 Jul 2017 07:41:31 GMT, orfeo wrote:

How do you serialize your data?

On Tue, 18 Jul 2017 15:07:09 GMT, Alexey Kulentsov wrote:

I have CSV source with numbers like 40.94, but after reading it and serializing to JSON I have something like 40.93999862670898 because of float representation, so my JSON file is very big. Is this possible to round it back when serializing?

struct CsvLogParser
{
	// ...

	struct Result
	{
		string[] names;
		Json[][] data;
	}
	
	static Result parseFile(string filename)
	{
		import std.algorithm: joiner;
		return parseRange(File(filename, "r").byLine.joiner("\n"), "s");
	}

	static Result parseRange(T)(T range, string prefix)
	{
		// ...
		Result result;
		enum floatMask = ctRegex!`^(\d*\.\d+)|(\d+\.\d*)$`;
		
		foreach(record; range.csvReader!(string))
		{
			string[] a = record.array;
			a[0] = convertDate(a[0]);
			result.data ~= a.map!((item){
			   if(!item.matchFirst(floatMask).empty)
				   return Json(item.to!float);
			   else
				   return Json(item);
			}).array;
		}
		
		// ...
			
		return result;
	}
}


class LogFilesDataPage : JsonPage!ForOnlyLogged
{
	// ...
	override Json getJson()
	{
		// ...
		foreach(filename; filenames)
		{
			// ...
			result[filename] = CsvLogParser.parseFile(client.logFilesDir~"/"~filename);
		}
		
		return serializeToJson(result);
	}
}

unittest
{
	// ...
	auto range = [ 
"01/03/2017 00:00:46,37.68,42.86,40.17,36.52,35.44,36.97,34.44,34.45",
"01/03/2017 01:00:32,37.41,42.28,39.56,35.77,33.73,35.68,33.8,34.29",
"01/03/2017 02:00:28,37.8,41.77,39.2,34.69,32.68,35.26,33.58,34.2",
"01/03/2017 03:00:24,37.9,41.46,38.43,33.28,32.13,35.14,33.52,34.17",
"01/03/2017 04:00:20,37.48,41.37,38.3,32.1,31.78,35.4,33.43,34.14",
"01/03/2017 05:00:16,42.65,43.85,38.8,31.21,31.56,34.96,33.44,34.11"
];
	// ...
}


Re: how to serialize float with two decimal points with vibe.data.json?

Am 18.07.2017 um 17:07 schrieb Alexey Kulentsov:

I have CSV source with numbers like 40.94, but after reading it and serializing to JSON I have something like 40.93999862670898 because of float representation, so my JSON file is very big. Is this possible to round it back when serializing?

This currently requires manual serialization unfortunately. There is an
open ticket that asks for a similar, although more general, feature:
#431

A more specific one, such as @floatPrecision(2) might be easier to
justify, though, as it could still guarantee that the generated JSON is
valid.

Re: how to serialize float with two decimal points with vibe.data.json?

On Wed, 9 Aug 2017 11:43:42 +0200, Sönke Ludwig wrote:

A more specific one, such as @floatPrecision(2) might be easier to
justify, though, as it could still guarantee that the generated JSON is
valid.

Yes, for my case it's enough, as UDA or even as the global serializeToJson() parameter.