0

If I give a double value and an integer value, I want to round that double to the precision of the integer value accurately. In the end, I want to get a double value which is more accurate as the output.

I tried it using the boost multi-precision library like the one below.

#include <boost/multiprecision/cpp_dec_float.hpp>

int main() {
    double input = 7.7778
    int precision = 3;

    using my_dec_100 = boost::multiprecision::cpp_dec_float_50;

    double intpart, fracpart;
    fracpart = modf(input, &intpart);
    int decimalLength = 0;
    if (fracpart > 0){
        decimalLength = std::ceil(-std::log10(std::pow(10, -std::numeric_limits<double>::digits10) * fracpart));
    }

    double rounded = std::floor(input * std::pow(10, precision) + 0.5) / std::pow(10, precision);
    my_dec_100 f11(my_dec_100(rounded * std::pow(10, decimalLength)) / std::pow(10, decimalLength));
    double output = f11.convert_to<double>();
    std::cout << std::setprecision(precision) << std::fixed << output << std::endl;  
    return 0;
}

But I am not sure whether this is working for each and every value. I want to work this even for a long fractional part also. ex:- 7.1346745428482672454818495 Also, here I have used the boost library to create f11 only. Is there any other way I can achieve this functionality using the boost multi-precision library?

Yasara
  • 17
  • 3
  • 1
    *"to the precision of the integer value accurately"* -- Every integer value has a precision of 1; every digit down to the ones' digit is precise, and no other digits are (largely because there are no other digits). Based on your code, you mean you want to round a floating-point number to a power of 10, where the power is the integer? (This is close to what your phrasing might mean if you replaced "of" with "given by", although that would still leave some details ambiguous.) – JaMiT Jul 06 '23 at 05:00
  • *"I want to work this even for a long fractional part also. ex:- 7.1346745428482672454818495"* -- What does your current code give for this input? Questions that are basically "please test my code" are typically off-topic for Stack Overflow. – JaMiT Jul 06 '23 at 05:03
  • You can't. Floating-point doesn't have decimal places. It has binary places, and the two are incommensurable. If you want decimal places, you must use a decimal radix. See my answer [here](https://stackoverflow.com/questions/153724/how-to-round-a-number-to-n-decimal-places-in-java) for proof. And you will never get those 25 decimal places of precision from a `double`. More likely you will get something like `7.1346745428482670000000000`. – user207421 Jul 06 '23 at 05:06
  • "But I am not sure whether this is working for each and every value." - I suggest you unit test some subranges of the values doubles can have. For example, 10 representable values either side of all integers in a modest range (e.g. -1100 to +1100), and the 10 values up to and including the largest value you care about, and from and above the most-negative. To do this, you can use std::next_after to nudge the double between neighbouring representable values. – Tony Delroy Jul 06 '23 at 05:08
  • 1
    You can't. A floating point variable (with a base-2 mantissa, which is most common in practice) cannot exactly represent values that are powers of `0.1` (`0.01`, `0.0001`, etc) and can represent some but not all multiples of those (e.g. `0.25` representable, `0.2` not). It is the same explanation for why a fraction "one third" cannot be exactly represented with a finite number of decimal places (just in base 2, different values are affected). Multi-precision libraries work by having arbitrarily extendable representations, which floating point does not. – Peter Jul 06 '23 at 05:16

0 Answers0