Search code examples
c++multiplication

Problem with multiplying 2 numbers in truncation procedure


I need truncation of 2 decimal digits after decimal comma. I am using following code in C++:

auto doubleTmp = value * 100.00;
int64_t tmp = static_cast<int64_t>(doubleTmp);
double res = ( static_cast<double>(tmp) ) /100.00;

but for example when I set value = 70.82 doubleTmp is 70.8199999 and result is 70.81. What will better way for this and why?


Solution

  • The problem is that neither the input value nor the result res is representable in a computer memory accurately for 70.82. As @MatthieuBrucher suggested, you should use std::lround; consider the following code:

    auto value = 70.82;
    std::cout << std::fixed << std::setprecision(20) << value << std::endl;
    
    auto tmp = std::lround(value * 100.0);
    std::cout << tmp << std::endl;
    
    double res = static_cast<double>(tmp) / 100.00;
    std::cout << std::fixed << std::setprecision(20) << res << std::endl;
    

    Which gives the following output:

    70.81999999999999317879
    7082
    70.81999999999999317879
    

    However, you can store the result as a pair of integral numbers, where the first one will represent the integral part and the second one the fractional part:

    auto res_integral = tmp / 100;
    auto res_fractional = tmp % 100;
    std::cout << res_integral << "." << res_fractional << std::endl;
    

    Or, simply store it as tmp with the knowledge that you are storing 100*x instead of x.