Fixed incorrect loop termination in lcm_range.

lcm_range used to incorrectly terminate on value of 1. Instead, it should
terminate on 0 since any further elements of the range no longer affect
the result of the function.

Also, added tests for the gcd_range and lcm_range functions verifying
that they terminate their loops at the correct points.
This commit is contained in:
Andrey Semashev
2019-03-26 01:55:18 +03:00
parent 5195d682ec
commit 33c165552c
2 changed files with 38 additions and 27 deletions

View File

@ -508,11 +508,12 @@ gcd_range(I first, I last) BOOST_GCD_NOEXCEPT(I)
BOOST_ASSERT(first != last);
typedef typename std::iterator_traits<I>::value_type T;
T d = *first++;
T d = *first;
++first;
while (d != T(1) && first != last)
{
d = gcd(d, *first);
first++;
++first;
}
return std::make_pair(d, first);
}
@ -523,11 +524,12 @@ lcm_range(I first, I last) BOOST_GCD_NOEXCEPT(I)
BOOST_ASSERT(first != last);
typedef typename std::iterator_traits<I>::value_type T;
T d = *first++;
while (d != T(1) && first != last)
T d = *first;
++first;
while (d != T(0) && first != last)
{
d = lcm(d, *first);
first++;
++first;
}
return std::make_pair(d, first);
}

View File

@ -542,6 +542,15 @@ void variadics()
BOOST_TEST_EQ(boost::integer::gcd_range(i, i + 4).second, i + 4);
BOOST_TEST_EQ(boost::integer::lcm_range(i, i + 4).first, 11704);
BOOST_TEST_EQ(boost::integer::lcm_range(i, i + 4).second, i + 4);
unsigned i_gcd_unity[] = { 44, 56, 1, 88 };
BOOST_TEST_EQ(boost::integer::gcd_range(i_gcd_unity, i_gcd_unity + 4).first, 1);
BOOST_TEST_EQ(boost::integer::gcd_range(i_gcd_unity, i_gcd_unity + 4).second, i_gcd_unity + 3);
unsigned i_lcm_unity[] = { 44, 56, 0, 88 };
BOOST_TEST_EQ(boost::integer::lcm_range(i_lcm_unity, i_lcm_unity + 4).first, 0);
BOOST_TEST_EQ(boost::integer::lcm_range(i_lcm_unity, i_lcm_unity + 4).second, i_lcm_unity + 3);
#ifndef BOOST_NO_CXX11_VARIADIC_TEMPLATES
BOOST_TEST_EQ(boost::integer::gcd(i[0], i[1], i[2], i[3]), 4);
BOOST_TEST_EQ(boost::integer::lcm(i[0], i[1], i[2], i[3]), 11704);