Opened 9 years ago

Closed 9 years ago

#9802 closed Bugs (fixed)

It seems as if integer division is being returned as a floating point

Reported by: ajgibson@… Owned by: John Maddock
Milestone: To Be Determined Component: multiprecision
Version: Boost 1.55.0 Severity: Problem
Keywords: Cc: ajgibson@…

Description

#include <iostream>
#include <boost/multiprecision/cpp_int.hpp>

int main()
{
    const boost::multiprecision::cpp_int max = 6;
    const boost::multiprecision::cpp_int factor = 4;
    const boost::multiprecision::cpp_int result = factor * factor * (max/factor); 
    
    std::cout << max << '/' << factor << " = " << max/factor << std::endl;
    std::cout << result << std::endl;
    
    const boost::multiprecision::cpp_int result2 = 4 * 4 * (6/4);
    
    std::cout << result2 << std::endl;
}

---
6/4 = 1
24
16

The documentations states that the result of arithmetic is, "An unmentionable-type expression template type when ExpressionTemplates is true." The return type though seems questionable when doing integer arithmetic it currently is returning floating point instead of integer values. So for example when you do 6 / 4 you get 1.5 instead of 1.

Change History (3)

comment:1 by anonymous, 9 years ago

Component: Nonemultiprecision
Owner: set to John Maddock

comment:2 by Steven Watanabe, 9 years ago

This is happening because the expression template system is re-associating the operations in number::do_multiplies.

   template <class Exp>
   void do_multiplies(const Exp& e, const detail::divides&)
   {
      typedef typename Exp::left_type left_type;
      typedef typename Exp::right_type right_type;
      do_multiplies(e.left(), typename left_type::tag_type());
      do_divide(e.right(), typename right_type::tag_type());
   }

Note how this effectively turns ... * (a / b) into ... * a / b.

comment:3 by John Maddock, 9 years ago

Resolution: fixed
Status: newclosed

The result isn't a floating point type: rather the expression templates can radically re-order many operations. However, this is a bug, so I've disabled some reordering operations specifically for integer types: https://github.com/boostorg/multiprecision/commit/9eb732b956803f4999da50e155e757083e89beb3.

Note: See TracTickets for help on using tickets.