www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Value of floating in JSONValue

reply "nrgyzer" <nrgyzer gmail.com> writes:
Hi everyone,

I'm facing a problem with the JSON functions. I've to communicate
with another PC using JSON. Here's a simple snipped which shows
my problem:

import std.json;
import std.stdio;
void main()
{
	double d = 1.23456789;
	JSONValue j = d;
	sendToRemote(toJSON(&j));
}

My problem is that the remote PC receives 1.23457 instead of
1.23456789. But when I add the following:

import std.json;
import std.stdio;
void main()
{
	double d = 1.23456789;
	JSONValue j = d;
	sendToRemote(toJSON(&j));
	writefln("%.8f", j.floating);
}

writefln() shows me 1.23456789. So, the value is correct. I think
the problem is the default representation of any floating point
number to string. Is there any chance I can send 1.23456789
instead of 1.23457 to my remote PC?

Note: I cannot use strings because the other PC expects a numeric
data type.
Aug 21 2014
next sibling parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 08/21/2014 11:53 AM, nrgyzer wrote:

      double d = 1.23456789;
      JSONValue j = d;
      sendToRemote(toJSON(&j));
 }

 My problem is that the remote PC receives 1.23457 instead of
 1.23456789.
I think it is due to the following code simply calling to!string in std/phobos/json.d: case JSON_TYPE.FLOAT: json.put(to!string(value.store.floating)); break;
 But when I add the following:

 import std.json;
 import std.stdio;
 void main()
 {
      double d = 1.23456789;
      JSONValue j = d;
      sendToRemote(toJSON(&j));
      writefln("%.8f", j.floating);
 }

 writefln() shows me 1.23456789. So, the value is correct.
It is more precise but still not correct because that specific double value cannot be represented exactly.
 Is there any chance I can send 1.23456789
 instead of 1.23457 to my remote PC?
You can call a function like the following: import std.string; import std.json; import std.stdio; string morePrecisely(double d) { return format("%.20g", d); } void main() { double d = 1.23456789; JSONValue root = [ "value" : d.morePrecisely ]; writeln(toJSON(&root)); } Of course do something more sensible than hard-coding the 20 in that format string. :)
 Note: I cannot use strings because the other PC expects a numeric
 data type.
I don't think it is a concern as JSON does not encode types. It is up to the receiver how to interpret the data. Here is the output of the program above: {"value":"1.2345678899999998901"} Ali
Aug 21 2014
parent reply "Idan Arye" <GenericNPC gmail.com> writes:
On Thursday, 21 August 2014 at 23:05:48 UTC, Ali Çehreli wrote:
 I don't think it is a concern as JSON does not encode types. It 
 is up to the receiver how to interpret the data. Here is the 
 output of the program above:

 {"value":"1.2345678899999998901"}

 Ali
JSON may not encode the very specific type the language that created it was using, but it does differ between strings and numbers. {"value":"1.2345678899999998901"} is different from {"value":1.2345678899999998901}, virtually any JSON implementation for any language(there might be exceptions - maybe TCL) will parse them to different language constructs, and code that expect one may fail, crash or misbehave when given the other.
Aug 21 2014
parent "nrgyzer" <nrgyzer gmail.com> writes:
On Thursday, 21 August 2014 at 23:29:56 UTC, Idan Arye wrote:
 On Thursday, 21 August 2014 at 23:05:48 UTC, Ali Çehreli wrote:
 I don't think it is a concern as JSON does not encode types. 
 It is up to the receiver how to interpret the data. Here is 
 the output of the program above:

 {"value":"1.2345678899999998901"}

 Ali
JSON may not encode the very specific type the language that created it was using, but it does differ between strings and numbers. {"value":"1.2345678899999998901"} is different from {"value":1.2345678899999998901}, virtually any JSON implementation for any language(there might be exceptions - maybe TCL) will parse them to different language constructs, and code that expect one may fail, crash or misbehave when given the other.
That's exactly my problem. The remote PC expects a numeric value with a precision of up to 6 floating points. So using a string instead of float would cause an error.
Aug 21 2014
prev sibling parent "Nobody" <Nobody somewhere.ut> writes:
On Thursday, 21 August 2014 at 18:53:08 UTC, nrgyzer wrote:
 Hi everyone,

 I'm facing a problem with the JSON functions. I've to 
 communicate
 with another PC using JSON. Here's a simple snipped which shows
 my problem:

 import std.json;
 import std.stdio;
 void main()
 {
 	double d = 1.23456789;
 	JSONValue j = d;
 	sendToRemote(toJSON(&j));
 }

 My problem is that the remote PC receives 1.23457 instead of
 1.23456789. But when I add the following:

 import std.json;
 import std.stdio;
 void main()
 {
 	double d = 1.23456789;
 	JSONValue j = d;
 	sendToRemote(toJSON(&j));
 	writefln("%.8f", j.floating);
 }

 writefln() shows me 1.23456789. So, the value is correct. I 
 think
 the problem is the default representation of any floating point
 number to string. Is there any chance I can send 1.23456789
 instead of 1.23457 to my remote PC?

 Note: I cannot use strings because the other PC expects a 
 numeric
 data type.
Hi, my answer will be a bit OT, and is not really an answer but: FP precision matters "only" during processing. I don't know which is the context but for example if it represents a parameter you could try - to encode it to a fraction representation like "1/3". - to encode it to a fixed-point float value. - mapping the value in the range of -1.0 to 1.0 because by nature, FP values are more accurate in this range. - to use a more accurate type: send a double (more precision), reduce it to a float (your 6 decimals are then granted). Note 1: still about the context, remember that this is a damn small delta. Does this delta is that much a concern ? Note 2: singles (we speak about IEEE 754, 32bits right ?) are not always 6 decimals precision, it's 5 >>OR<< 6.
Aug 22 2014