1

Precision is the number of digits in a number. Scale is the number of digits to the right of the decimal point in a number. For example, the number 123.45 has a precision of 5 and a scale of 2.

I need to convert a double with a maximum scale of 7(i.e. it may have 7 digits after the decimal point) to a __int128. However, given a number, I don't know in advance, the actual scale the number has.

#include <iostream> #include "json.hpp" using json = nlohmann::json; #include <string> static std::ostream& operator<<(std::ostream& o, const __int128& x) { if (x == std::numeric_limits<__int128>::min()) return o << "-170141183460469231731687303715884105728"; if (x < 0) return o << "-" << -x; if (x < 10) return o << (char)(x + '0'); return o << x / 10 << (char)(x % 10 + '0'); } int main() { std::string str = R"({"time": [0.143]})"; std::cout << "input: " << str << std::endl; json j = json::parse(str); std::cout << "output: " << j.dump(4) << std::endl; double d = j["time"][0].get<double>(); __int128_t d_128_bad = d * 10000000; __int128_t d_128_good = __int128(d * 1000) * 10000; std::cout << std::setprecision(16) << std::defaultfloat << d << std::endl; std::cout << "d_128_bad: " << d_128_bad << std::endl; std::cout << "d_128_good: " << d_128_good << std::endl; } 

Output:

input: {"time": [0.143]} output: { "time": [ 0.143 ] } 0.143 d_128_bad: 1429999 d_128_good: 1430000 

As you can see, the converted double is not the expected 1430000 instead it is 1429999. I know the reason is that a float point number can not be represented exactly. The problem can be solved if I know the number of digit after the decimal point.

For example,

I can instead use __int128_t(d * 1000) * 10000. However, I don't know the scale of a given number which might have a maximum of scale 7.

Question> Is there a possible solution for this? Also, I need to do this conversion very fast.

14
  • "a __int128 with a maximum scale of 7(i.e. it may have 7 digits after the decimal point)" -- good news! An integer has no digits after the decimal point, so done! Did you misplace your "with" phrase? Perhaps you meant "a double with a maximum scale of 7 to a __int128"? Or maybe "convert, with a maximum scale of 7, to a __int128"? Or maybe... "convert a double, that had been converted from a decimal representation with a maximum scale of 7, to a int128"? Commented Apr 15, 2022 at 3:53
  • 1
    How about __int128(d * 10000000+0.5) ? Commented Apr 15, 2022 at 4:56
  • @JaMiT, I rewrite the OP to remove the confusion. Commented Apr 15, 2022 at 12:12
  • 1
    Note that the linked documentation is talking about a decimal datatype, rather than a double (binary) representation. Commented Apr 15, 2022 at 12:22
  • 1
    Since you always multiply by 10000000 regardless of the number's scale, and want to convert the result to integer: Does this answer your question? Conversion from double to integer Commented Apr 17, 2022 at 5:16

1 Answer 1

1

I'm not familiar with this library, but it does appear to have a mechanism to get a json object's string representation (dump()). I would suggest you parse that into your value rather than going through the double intermediate representation, as in that case you will know the scale of the value as it was written.

Sign up to request clarification or add additional context in comments.

1 Comment

In the real production data, the data is of an array with a very large number set. It is not applicable and expensive to call dump first and then do all those parsings manually.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.