Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Truncate Double Values #362

Closed
jsx7ba opened this issue Jun 23, 2015 · 6 comments · Fixed by #536
Closed

Truncate Double Values #362

jsx7ba opened this issue Jun 23, 2015 · 6 comments · Fixed by #536

Comments

@jsx7ba
Copy link

jsx7ba commented Jun 23, 2015

It'd be nice if the GenericValue::Double() method took a default parameter to truncate double values:

v.Double(12.529999732971191); ---> 12.529999732971191
v.Double(12.529999732971191, 3) ---> 12.529

@miloyip
Copy link
Collaborator

miloyip commented Jun 24, 2015

I am not sure if this feature should be added. There are different ways to do the "truncations" or "rounding".

I think, a way of doing this externally is:

double RoundDecimal(double d, double p) {
    std::round(d * p) / p;
}

double TruncDecimal(double d, double p) {
    std::trunc(d * p) / p; // C++11
}

v.Double(RoundDecimal(12.529999732971191, 1000.0)); // 12.530
v.Double(TruncDecimal(12.529999732971191, 1000.0)); // 12.529

But if this is really common, I think it is also possible to add this feature, which may also reduces some computation overheads.

@jsx7ba
Copy link
Author

jsx7ba commented Jun 24, 2015

I tried your suggestion with a different implementation. Given the following:
Value v;
double x = -3.18842;
v.Double(Truncate(x, 3));

In the JSON document, v was written as -3.188000202178955. I think the Double() method only needs to worry about truncation. The caller can implement the rounding:

v.Double(RoundDecimal(-3.18842, 2), 2); // -3.19

@miloyip
Copy link
Collaborator

miloyip commented Jun 25, 2015

Can you show your implementation?
Actually, this feature is a bit complicated, since rounding/trancation has quite some options. For example, currently it will generate scientific notation for some range of exponents(like %g). Should trancation applies to the mantissa or the actual decimals?

@jsx7ba
Copy link
Author

jsx7ba commented Jun 25, 2015

Sure, this is a temporary solution I put together. It seems to work with cout, but only 0-5 decimal places.

template<unsigned decimals>
double Truncate(double val)
{
      double devisor = 1.0;
      for(int i=0; i!=decimals; i++)
          devisor /= 10;
      return val - fmod(val, devisor);
}

cout << Truncate<2>(3.141596) << endl; // 3.14

I work for a company that uses your excellent library to encode scientific data. For our purposes, we're only interested in truncating decimal places. The accuracy of 7 decimal places generally isn't repeatable across platforms, so the remaining digits have no use for us.

Regarding scientific notation, I'm not sure it's important to use. We're wanting to truncate mainly to save some bytes and parse time in javascript. Some of our documents are 4MB in size and in a few examples truncating to 3 decimal places saved us 1.1MB.

@bbassett17
Copy link

Truncating is a need for our software. We have values with 3 significant decimal places. I have not found a way using the Writer.Double method to print them rounded and truncated to 3 decimal places.

@miloyip
Copy link
Collaborator

miloyip commented Feb 11, 2016

Added in PR #536.
The current implementation simply truncate decimal places (not rounding, not significant digits).
Please review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants