Divide integers with floor, ceil and outwards rounding modes in C++ - c++

Recently, I saw this question which asks how you can divide integers with ceil rounding (towards positive infinity). Unfortunately the answers either don't work for signed integers or have problems with underflows and overflows.
For instance, the accepted answer has this solution:
q = 1 + ((x - 1) / y);
When x is zero, there is an underflow to ~0 and the result is incorrect.
How can you implement ceil rounding correctly for signed and unsigned integers and how do you implement other rounding modes like floor (towards negative infinity) and outwards (away from zero)?

In C++, the / division operation rounds using truncate (towards zero) by default. We can adjust the result of division towards zero to implement other rounding modes.
Note that when the division has no remainder, all rounding modes are equivalent because no rounding is necessary.
With that in mind, we can implement the different rounding modes.
But before we get started, we will need a helper template for the return types so that we don't use auto return types everywhere:
#include <type_traits>
/**
* Similar to std::common_type_t<A, B>, but if A or B are signed, the result will also be signed.
*
* This differs from the regular type promotion rules, where signed types are promoted to unsigned types.
*/
template <typename A, typename B>
using common_signed_t =
std::conditional_t<std::is_unsigned_v<A> && std::is_unsigned_v<B>,
std::common_type_t<A, B>,
std::common_type_t<std::make_signed_t<A>, std::make_signed_t<B>>>;
Ceil (towards +∞)
Ceil rounding is identical to truncate rounding for negative quotients, but for positive quotients and nonzero remainders we round away from zero. This means that we increment the quotient for nonzero remainders.
Thanks to if-constexpr, we can implement everything using only a single function:
template <typename Dividend, typename Divisor>
constexpr common_signed_t<Dividend, Divisor> div_ceil(Dividend x, Divisor y)
{
if constexpr (std::is_unsigned_v<Dividend> && std::is_unsigned_v<Divisor>) {
// quotient is always positive
return x / y + (x % y != 0); // uint / uint
}
else if constexpr (std::is_signed_v<Dividend> && std::is_unsigned_v<Divisor>) {
auto sy = static_cast<std::make_signed_t<Divisor>>(y);
bool quotientPositive = x >= 0;
return x / sy + (x % sy != 0 && quotientPositive); // int / uint
}
else if constexpr (std::is_unsigned_v<Dividend> && std::is_signed_v<Divisor>) {
auto sx = static_cast<std::make_signed_t<Dividend>>(x);
bool quotientPositive = y >= 0;
return sx / y + (sx % y != 0 && quotientPositive); // uint / int
}
else {
bool quotientPositive = (y >= 0) == (x >= 0);
return x / y + (x % y != 0 && quotientPositive); // int / int
}
}
At first glance, the implementations for signed types seem expensive, because they use both an integer division and a modulo division. However, on modern architectures division typically sets a flag that indicates whether there was a remainder, so x % y != 0 is completely free in this case.
You might also be wondering why we don't compute the quotient first and then check if the quotient is positive. This wouldn't work because we already lost precision during this division, so we can't perform this test afterwards. For example:
-1 / 2 = -0.5
// C++ already rounds towards zero
-0.5 -> 0
// Now we think that the quotient is positive, even though it is negative.
// So we mistakenly round up again:
0 -> 1
Floor (towards -∞)
Floor rounding is identical to truncate for positive quotients, but for negative quotients we round away from zero. This means that we decrement the quotient for nonzero remainders.
template <typename Dividend, typename Divisor>
constexpr common_signed_t<Dividend, Divisor> div_floor(Dividend x, Divisor y)
{
if constexpr (std::is_unsigned_v<Dividend> && std::is_unsigned_v<Divisor>) {
// quotient is never negative
return x / y; // uint / uint
}
else if constexpr (std::is_signed_v<Dividend> && std::is_unsigned_v<Divisor>) {
auto sy = static_cast<std::make_signed_t<Divisor>>(y);
bool quotientNegative = x < 0;
return x / sy - (x % sy != 0 && quotientNegative); // int / uint
}
else if constexpr (std::is_unsigned_v<Dividend> && std::is_signed_v<Divisor>) {
auto sx = static_cast<std::make_signed_t<Dividend>>(x);
bool quotientNegative = y < 0;
return sx / y - (sx % y != 0 && quotientNegative); // uint / int
}
else {
bool quotientNegative = (y < 0) != (x < 0);
return x / y - (x % y != 0 && quotientNegative); // int / int
}
}
The implementation is almost identical to that of div_ceil.
Away From Zero
Away from zero is the exact opposite of truncate. Basically, we need to increment or decrement depending on the sign of the quotient, but only if there is a remainder. This can be expressed as adding the sgn of the quotient onto the result:
template <typename Int>
constexpr signed char sgn(Int n)
{
return (n > Int{0}) - (n < Int{0});
};
Using this helper function, we can fully implement up rounding:
template <typename Dividend, typename Divisor>
constexpr common_signed_t<Dividend, Divisor> div_up(Dividend x, Divisor y)
{
if constexpr (std::is_unsigned_v<Dividend> && std::is_unsigned_v<Divisor>) {
// sgn is always 1
return x / y + (x % y != 0); // uint / uint
}
else if constexpr (std::is_signed_v<Dividend> && std::is_unsigned_v<Divisor>) {
auto sy = static_cast<std::make_signed_t<Divisor>>(y);
signed char quotientSgn = sgn(x);
return x / sy + (x % sy != 0) * quotientSgn; // int / uint
}
else if constexpr (std::is_unsigned_v<Dividend> && std::is_signed_v<Divisor>) {
auto sx = static_cast<std::make_signed_t<Dividend>>(x);
signed char quotientSgn = sgn(y);
return sx / y + (sx % y != 0) * quotientSgn; // uint / int
}
else {
signed char quotientSgn = sgn(x) * sgn(y);
return x / y + (x % y != 0) * quotientSgn; // int / int
}
}
Unresolved Problems
Unfortunately these functions won't work for all possible inputs, which is a problem that we can not solve.
For example, dividing uint32_t{3 billion} / int32_t{1} results in int32_t(3 billion) which isn't representable using a 32-bit signed integer.
We get an underflow in this case.
Using larger return types would be an option for everything but 64-bit integers, where there isn't a larger alternative available.
Hence, it is the responsibility of the user to ensure that when they pass an unsigned number into this function, it is equivalent to its signed representation.

I would simplify and use homogeneous argument type and let the users to make explicit type casts for heterogeneous inputs, if necessary. This way possible under- and overflows are moved outside these functions. Of course normal UB cases apply, eg. divide by zero and std::numeric_limits<T>::min() divided by -1 for signed T.
#include <type_traits>
//Division round up, aka take the ceiling, aka round toward positive infinity, eg. -1.5 -> -1, 1.5 -> 2
template<typename T>
requires std::is_integral_v<T>
constexpr T divRndUp(T a, T b) noexcept
{
if constexpr (std::is_unsigned_v<T>)
return a / b + (a % b != 0);
else
return a / b + (a % b != 0 && ((a < 0) == (b < 0)));
}
//Division round down, aka take the floor, aka round toward negative infinity, eg. -1.5 -> -2, 1.5 -> 1
template<typename T>
requires std::is_integral_v<T>
constexpr T divRndDwn(T a, T b) noexcept
{
if constexpr (std::is_unsigned_v<T>)
return a / b;
else
return a / b - (a % b != 0 && ((a < 0) != (b < 0)));
}
//Division round out, aka round out away from zero, aka round toward infinity, eg. -1.5 -> -2, 1.5 -> 2
template<typename T>
requires std::is_integral_v<T>
constexpr T divRndOut(T a, T b) noexcept
{
if constexpr (std::is_unsigned_v<T>)
return a / b + (a % b != 0);
else
return a / b + (a % b != 0 && ((a < 0) == (b < 0))) - (a % b != 0 && ((a < 0) != (b < 0)));
}
//Division round in, aka truncate, aka round in toward zero, aka round away from infinity, eg. -1.5 -> -1, 1.5 -> 1
template<typename T>
requires std::is_integral_v<T>
constexpr T divRndIn(T a, T b) noexcept
{
return a / b;
}

Related

How to modulo this formula?

I would like to write this formula in C++ language:
(2<=n<=1e5), (1<=k<=n), (2<=M<=1e9).
I would like to do this without using special structures.
Unfortunately in this formula there are a lot of cases which effectively make modulation difficult. Example: ((n-k)!) mod M can be equal to 0, or ((n-1)(n-2))/4 may not be an integer. I will be very grateful for any help.
(n−1)!/(n−k)! can be handled by computing the product (n−k+1)…(n−1).
(n−1)! (n−1)(n−2)/4 can be handled by handling n ≤ 2 (0) and n ≥ 3
(3…(n−1) (n−1)(n−2)/2) separately.
Untested C++:
#include <cassert>
#include <cstdint>
class Residue {
public:
// Accept int64_t for convenience.
explicit Residue(int64_t rep, int32_t modulus) : modulus_(modulus) {
assert(modulus > 0);
rep_ = rep % modulus;
if (rep_ < 0)
rep_ += modulus;
}
// Return int64_t for convenience.
int64_t rep() const { return rep_; }
int32_t modulus() const { return modulus_; }
private:
int32_t rep_;
int32_t modulus_;
};
Residue operator+(Residue a, Residue b) {
assert(a.modulus() == b.modulus());
return Residue(a.rep() + b.rep(), a.modulus());
}
Residue operator-(Residue a, Residue b) {
assert(a.modulus() == b.modulus());
return Residue(a.rep() - b.rep(), a.modulus());
}
Residue operator*(Residue a, Residue b) {
assert(a.modulus() == b.modulus());
return Residue(a.rep() * b.rep(), a.modulus());
}
Residue QuotientOfFactorialsMod(int32_t a, int32_t b, int32_t modulus) {
assert(modulus > 0);
assert(b >= 0);
assert(a >= b);
Residue result(1, modulus);
// Don't initialize with b + 1 because it could overflow.
for (int32_t i = b; i < a; i++) {
result = result * Residue(i + 1, modulus);
}
return result;
}
Residue FactorialMod(int32_t a, int32_t modulus) {
assert(modulus > 0);
assert(a >= 0);
return QuotientOfFactorialsMod(a, 0, modulus);
}
Residue Triangular(int32_t a, int32_t modulus) {
assert(modulus > 0);
return Residue((static_cast<int64_t>(a) + 1) * a / 2, modulus);
}
Residue F(int32_t n, int32_t k, int32_t m) {
assert(n >= 2);
assert(n <= 100000);
assert(k >= 1);
assert(k <= n);
assert(m >= 2);
assert(m <= 1000000000);
Residue n_res(n, m);
Residue n_minus_1(n - 1, m);
Residue n_minus_2(n - 2, m);
Residue k_res(k, m);
Residue q = QuotientOfFactorialsMod(n - 1, n - k, m);
return q * (k_res - n_res) * n_minus_1 +
(FactorialMod(n - 1, m) - q) * k_res * n_minus_1 +
(n > 2 ? QuotientOfFactorialsMod(n - 1, 2, m) *
(n_res * n_minus_1 + Triangular(n - 2, m))
: Residue(1, m));
}
As mentioned in the other answer dividing factorials can be evaluated directly without division. Also you need 64bit arithmetics in order to store your subresults. And use modulo after each multiplication otherwise you would need very huge numbers which would take forever to compute.
Also you mention ((n-1)(n-2))/4 can be non just integer how to deal with that is questionable as we do not have any context to what you are doing. However you can move /2 before brackets (apply it on (n-1)! so modpi without 2 beware not to divide the already modded factorial!!!) and then you have no remainder as the (n-1)*(n-2)/4 become (n-1)*(n-2)/2 and the (n-1)*(n-2) is always odd (divisible by 2). The only "problem" is when n=2 as the n*(n-1)/2 is 1 but the /2 moved before bracket will round down the (n-1)! so you should handle it as special case by not moving the /2 before brackets (not included in code below).
I see it like this:
typedef unsigned __int64 u64;
u64 modpi(u64 x0,u64 x1,u64 p) // ( x0*(x0+1)*(x0+2)*...*x1 ) mod p
{
u64 x,y;
if (x0>x1){ x=x0; x0=x1; x1=x; }
for (y=1,x=x0;x<=x1;x++){ y*=x; y%=p; }
return y;
}
void main()
{
u64 n=100,k=20,m=123456789,a,b,b2,c,y;
a =modpi(n-k+1,n-1,m); // (n-1)!/(n-k)!
b =modpi(1,n-1,m); // (n-1)! mod m
b2=modpi(3,n-1,m); // (n-1)!/2 mod m
c =((n*(n-1)))%m; // 2*( n*(n-1)/2 + (n-1)*(n-2)/4 ) mod m
c+=(((n-1)*(n-2))/2)%m;
y =(((a*(k-n))%m)*(n-1))%m; // ((n-1)!/(n-k)!)*(k-1)*(n-1) mod m
y+=b; // (n-1)! mod m
y-=(((a*k)%m)*(n-1))%m; // ((n-1)!/(n-k)!)*k*(n-1) mod m
y+=(b2*c)%m; // (n-1)!*( n*(n-1)/2 + (n-1)*(n-2)/4 ) mod m
// here y should hold your answer
}
however be careful older compilers do not have full support of 64 bit integers and can produce wrong results or even does not compile. In such case use big integer lib or compute using 2*32bit variables or look for 32 bit modmul implementation.
The expression implies the use of a floating point type. Therefore, use the function fmod to get the remainder of the division.

Negating INT_MIN in CPP

The question I am trying to solve is:
Implement pow(x, n), which calculates x raised to the power n (Leetcode problem 50)
I have the following code:
class Solution {
public:
double myPow(double x, int n) {
if (n == 0) {
cout << "in last";
return 1;
} else if (n < 0) {
x = 1 / x;
return myPow(x, -n);
} else if (n % 2 == 0) {
double y;
cout << "in even";
y = myPow(x, n / 2);
cout << "y is ";
cout << y;
return (y * y);
}
else {
cout << "in odd";
double j = myPow(x, n - 1);
cout << "j is ";
cout << x * j;
return (x * j);
}
}
};
When ran for the test case x=1.00000 and n = -2147483648. I am getting the error:
runtime error: negation of -2147483648 cannot be represented in type 'int'; cast to an unsigned type to negate this value to itself (solution.cpp)
Why do I get this and how shall I solve it? TIA
If you want to support -2147483648 then you need to use a long long type, not an int.
If int is a 32 bit 2's complement type then 2147483648 is actually a long or a long long type.
There are no such things as negative literals in C++ (-2147483648 is a compile time evaluable constant expression consisting of the negation of the literal 2147483648), so -2147483648 is either a long or a long long type too. This is why you'll often see INT_MIN defined as -2147483647 - 1.
If the above is the case on your platform then the behaviour of your code is undefined for that input, as you are overflowing an int type.
A 4 bytes (or 32 bits) int has a range of -2,147,483,648 to 2,147,483,647, thus if you negate -2,147,483,648 you can't represent it as int.
You could try using unsigned int (which has a range of
0 to 4,294,967,295) or long long int (which a range of -(2^63) to (2^63)-1) make this negation and fit the positive value there.
I opted for a different approach and handled this case separately since it is the only value that will cause us trouble.
Add 1 to that negative value before negating it.
To compensate for that I multiplicate the base once more separately.
if (n == -2,147,483,648)
{
return (1.0/x) * myPow(1.0/x, -(n + 1));
}
The full solution
double myPow(double x, int n)
{
if (n == 0) return 1.0;
if (n < 0)
{
if (n == -2,147,483,648)
{
return (1.0/x) * myPow(1.0/x, -(n + 1));
}
return myPow(1.0/x, -n);
}
return (n % 2 == 0) ? myPow(x * x, n / 2) : x * myPow(x * x, n / 2);
}

Find a,b,n so that (a^b)%n=x

Say I choose a value for x that can be between 0 and 2147483647. (Int32.MaxValue)
I am trying to figure out how I can find values for a,b,n so that (a^b)%n=x
I already know that I can use ModPow to verify the values, but I don't know how I can find a fitting a,b and n.
#include <iostream>
/// Calculate (a^b)%n
/// \param a The base
/// \param b The exponent
/// \param n The modulo
/// \return (a^b)%n
int ModPow(int a, int b, int n) {
long long x = 1, y = a;
while (b > 0) {
if (b % 2 == 1) {
x = (x * y) % n; // multiplying with base
}
y = (y * y) % n; // squaring the base
b /= 2;
}
return x % n;
}
int main() {
int x = 1337;
// How to find a,b,n so that (a^b)%n=x
int a = ?;
int b = ?;
int n = ?;
if(x == ModPow(a,b,n))
printf("ok");
return 0;
}
int n = 2147483647
int a = ModPow(x, 9241, n);
int b = 464773;
n = 231 − 1 is a prime number. So due to Fermat's little theorem, xn mod n = x and xn − 1 mod n = 1 (unless x = 0) so x2 n − 1 mod n = x, too. 2 n − 1 = 9241 × 464773. So (x9241 mod n)464773 mod n = x. Note that you need x < n for this to work; x = 2147483647 cannot work if n is a 31 bit (i.e. signed) integer, too.
It took me a while to get here; for a long time I've had this answer messing about with Carmichael numbers and the Carmichael function before I reached this easy solution. See edit history for details.
The modulus operator:
Yields the remainder given by the following expression, where e1 is the first operand and e2 is the second: e1 – (e1 / e2) * e2
Therefor whatever the max value of x is, n must be larger. Since you're validating with n as an int and you're specifying the range: 0 and numeric_limits<int>::max() that must be an exclusive range, and for n to be an int the only possible value it can take is: numeric_limits<int>::max().
With n forced our equation effectively becomes: ab = x.
We'll need to do a check here that x is not 1, if it is b = 0 and a can be anything in our legal range so we can arbitrarily pick a = 2. But baring this:
Our requirements are:
1 < a < x and a is an int
1 < b < x and b is an int
Given x, we can search for a combination of a and b that will fit as follows:
auto a = 0.0;
auto b = 1;
if(x == 1) {
a = 2.0;
b = 0;
} else {
while((a = pow(x, 1.0 / ++b)) > 2.0) {
double dummy;
if(modf(a, &dummy) == 0.0) {
break;
}
}
}
At this point, if a >= 2.0 then there is a valid solution to the problem. Now as you as you are probably well aware, pow is a very expensive function so this will likely take a very long time to execute for larger values of x, I'd personally suggest finding an a and b for every number for which such a pair exists and storing them in a map and doing a lookup on that.
Anyway this is a demonstration of working code:
Live Example

How to calculate -1 modulo 1000000007 in C++

I tried to get the result of -1 modulo 1000000007 using the % operator of C++
and fmod function.
The output is -1, but -1 modulo 1000000007==1000000006.
What have I done wrong?
Plainly said, you took the wrong operator.
C++ and C % is not modulo, but remainder.
assert(a / b * b + a % b == a); // for integral types
If a is non-negative, modulo and remainder are the same.
Otherwise the return-value is negative, just add b.
template<class T>
inline constexpr auto
modulo(T a, T b) -> decltype(a%b) {
auto r = a % b;
if (r < 0) r += b;
return r;
}
Or (also) for C:
#define modulo(a, b) (a % b < 0 ? a % b + b : a % b)
For completeness: Before C++11, a / b could always round down instead of always to 0, though C++03 already had a note that the next standard would probably mandate rounding to 0.
See Wikipedia on modulo:
Modulo is the remainder of euclidiean division, and always in range 0 <= modulo < divisor
And on remainder:
In mathematics, the remainder is the amount "left over" after performing some computation.
Modulo function that handles negative divisors as well as positive divisors:
template<class T>
inline constexpr auto
modulo(T a, T b) -> decltype(a%b) {
auto r = a % b;
if((b > 0 && r < 0) || (b < 0 && r > 0))
r += b;
return r;
}

Rounding up to the nearest multiple of a number

OK - I'm almost embarrassed posting this here (and I will delete if anyone votes to close) as it seems like a basic question.
Is this the correct way to round up to a multiple of a number in C++?
I know there are other questions related to this but I am specficially interested to know what is the best way to do this in C++:
int roundUp(int numToRound, int multiple)
{
if(multiple == 0)
{
return numToRound;
}
int roundDown = ( (int) (numToRound) / multiple) * multiple;
int roundUp = roundDown + multiple;
int roundCalc = roundUp;
return (roundCalc);
}
Update:
Sorry I probably didn't make intention clear. Here are some examples:
roundUp(7, 100)
//return 100
roundUp(117, 100)
//return 200
roundUp(477, 100)
//return 500
roundUp(1077, 100)
//return 1100
roundUp(52, 20)
//return 60
roundUp(74, 30)
//return 90
This works for positive numbers, not sure about negative. It only uses integer math.
int roundUp(int numToRound, int multiple)
{
if (multiple == 0)
return numToRound;
int remainder = numToRound % multiple;
if (remainder == 0)
return numToRound;
return numToRound + multiple - remainder;
}
Edit: Here's a version that works with negative numbers, if by "up" you mean a result that's always >= the input.
int roundUp(int numToRound, int multiple)
{
if (multiple == 0)
return numToRound;
int remainder = abs(numToRound) % multiple;
if (remainder == 0)
return numToRound;
if (numToRound < 0)
return -(abs(numToRound) - remainder);
else
return numToRound + multiple - remainder;
}
Without conditions:
int roundUp(int numToRound, int multiple)
{
assert(multiple);
return ((numToRound + multiple - 1) / multiple) * multiple;
}
This works like rounding away from zero for negative numbers
Version that works also for negative numbers:
int roundUp(int numToRound, int multiple)
{
assert(multiple);
int isPositive = (int)(numToRound >= 0);
return ((numToRound + isPositive * (multiple - 1)) / multiple) * multiple;
}
Tests
If multiple is a power of 2 (faster in ~3.7 times)
int roundUp(int numToRound, int multiple)
{
assert(multiple && ((multiple & (multiple - 1)) == 0));
return (numToRound + multiple - 1) & -multiple;
}
Tests
This works when factor will always be positive:
int round_up(int num, int factor)
{
return num + factor - 1 - (num + factor - 1) % factor;
}
Edit: This returns round_up(0,100)=100. Please see Paul's comment below for a solution that returns round_up(0,100)=0.
This is a generalization of the problem of "how do I find out how many bytes n bits will take? (A: (n bits + 7) / 8).
int RoundUp(int n, int roundTo)
{
// fails on negative? What does that mean?
if (roundTo == 0) return 0;
return ((n + roundTo - 1) / roundTo) * roundTo; // edit - fixed error
}
int roundUp(int numToRound, int multiple)
{
if(multiple == 0)
{
return 0;
}
return ((numToRound - 1) / multiple + 1) * multiple;
}
And no need to mess around with conditions
This is the modern c++ approach using a template function which is working for float, double, long, int and short (but not for long long, and long double because of the used double values).
#include <cmath>
#include <iostream>
template<typename T>
T roundMultiple( T value, T multiple )
{
if (multiple == 0) return value;
return static_cast<T>(std::round(static_cast<double>(value)/static_cast<double>(multiple))*static_cast<double>(multiple));
}
int main()
{
std::cout << roundMultiple(39298.0, 100.0) << std::endl;
std::cout << roundMultiple(20930.0f, 1000.0f) << std::endl;
std::cout << roundMultiple(287399, 10) << std::endl;
}
But you can easily add support for long long and long double with template specialisation as shown below:
template<>
long double roundMultiple<long double>( long double value, long double multiple)
{
if (multiple == 0.0l) return value;
return std::round(value/multiple)*multiple;
}
template<>
long long roundMultiple<long long>( long long value, long long multiple)
{
if (multiple == 0.0l) return value;
return static_cast<long long>(std::round(static_cast<long double>(value)/static_cast<long double>(multiple))*static_cast<long double>(multiple));
}
To create functions to round up, use std::ceil and to always round down use std::floor. My example from above is rounding using std::round.
Create the "round up" or better known as "round ceiling" template function as shown below:
template<typename T>
T roundCeilMultiple( T value, T multiple )
{
if (multiple == 0) return value;
return static_cast<T>(std::ceil(static_cast<double>(value)/static_cast<double>(multiple))*static_cast<double>(multiple));
}
Create the "round down" or better known as "round floor" template function as shown below:
template<typename T>
T roundFloorMultiple( T value, T multiple )
{
if (multiple == 0) return value;
return static_cast<T>(std::floor(static_cast<double>(value)/static_cast<double>(multiple))*static_cast<double>(multiple));
}
For anyone looking for a short and sweet answer. This is what I used. No accounting for negatives.
n - (n % r)
That will return the previous factor.
(n + r) - (n % r)
Will return the next. Hope this helps someone. :)
float roundUp(float number, float fixedBase) {
if (fixedBase != 0 && number != 0) {
float sign = number > 0 ? 1 : -1;
number *= sign;
number /= fixedBase;
int fixedPoint = (int) ceil(number);
number = fixedPoint * fixedBase;
number *= sign;
}
return number;
}
This works for any float number or base (e.g. you can round -4 to the nearest 6.75). In essence it is converting to fixed point, rounding there, then converting back. It handles negatives by rounding AWAY from 0. It also handles a negative round to value by essentially turning the function into roundDown.
An int specific version looks like:
int roundUp(int number, int fixedBase) {
if (fixedBase != 0 && number != 0) {
int sign = number > 0 ? 1 : -1;
int baseSign = fixedBase > 0 ? 1 : 0;
number *= sign;
int fixedPoint = (number + baseSign * (fixedBase - 1)) / fixedBase;
number = fixedPoint * fixedBase;
number *= sign;
}
return number;
}
Which is more or less plinth's answer, with the added negative input support.
First off, your error condition (multiple == 0) should probably have a return value. What? I don't know. Maybe you want to throw an exception, that's up to you. But, returning nothing is dangerous.
Second, you should check that numToRound isn't already a multiple. Otherwise, when you add multiple to roundDown, you'll get the wrong answer.
Thirdly, your casts are wrong. You cast numToRound to an integer, but it's already an integer. You need to cast to to double before the division, and back to int after the multiplication.
Lastly, what do you want for negative numbers? Rounding "up" can mean rounding to zero (rounding in the same direction as positive numbers), or away from zero (a "larger" negative number). Or, maybe you don't care.
Here's a version with the first three fixes, but I don't deal with the negative issue:
int roundUp(int numToRound, int multiple)
{
if(multiple == 0)
{
return 0;
}
else if(numToRound % multiple == 0)
{
return numToRound
}
int roundDown = (int) (( (double) numToRound / multiple ) * multiple);
int roundUp = roundDown + multiple;
int roundCalc = roundUp;
return (roundCalc);
}
Round to Power of Two:
Just in case anyone needs a solution for positive numbers rounded to the nearest multiple of a power of two (because that's how I ended up here):
// number: the number to be rounded (ex: 5, 123, 98345, etc.)
// pow2: the power to be rounded to (ex: to round to 16, use '4')
int roundPow2 (int number, int pow2) {
pow2--; // because (2 exp x) == (1 << (x -1))
pow2 = 0x01 << pow2;
pow2--; // because for any
//
// (x = 2 exp x)
//
// subtracting one will
// yield a field of ones
// which we can use in a
// bitwise OR
number--; // yield a similar field for
// bitwise OR
number = number | pow2;
number++; // restore value by adding one back
return number;
}
The input number will stay the same if it is already a multiple.
Here is the x86_64 output that GCC gives with -O2 or -Os (9Sep2013 Build - godbolt GCC online):
roundPow2(int, int):
lea ecx, [rsi-1]
mov eax, 1
sub edi, 1
sal eax, cl
sub eax, 1
or eax, edi
add eax, 1
ret
Each C line of code corresponds perfectly with its line in the assembly: http://goo.gl/DZigfX
Each of those instructions are extremely fast, so the function is extremely fast too. Since the code is so small and quick, it might be useful to inline the function when using it.
Credit:
Algorithm: Hagen von Eitzen # Math.SE
Godbolt Interactive Compiler: #mattgodbolt/gcc-explorer on GitHub
I'm using:
template <class _Ty>
inline _Ty n_Align_Up(_Ty n_x, _Ty n_alignment)
{
assert(n_alignment > 0);
//n_x += (n_x >= 0)? n_alignment - 1 : 1 - n_alignment; // causes to round away from zero (greatest absolute value)
n_x += (n_x >= 0)? n_alignment - 1 : -1; // causes to round up (towards positive infinity)
//n_x += (_Ty(-(n_x >= 0)) & n_alignment) - 1; // the same as above, avoids branch and integer multiplication
//n_x += n_alignment - 1; // only works for positive numbers (fastest)
return n_x - n_x % n_alignment; // rounds negative towards zero
}
and for powers of two:
template <class _Ty>
bool b_Is_POT(_Ty n_x)
{
return !(n_x & (n_x - 1));
}
template <class _Ty>
inline _Ty n_Align_Up_POT(_Ty n_x, _Ty n_pot_alignment)
{
assert(n_pot_alignment > 0);
assert(b_Is_POT(n_pot_alignment)); // alignment must be power of two
-- n_pot_alignment;
return (n_x + n_pot_alignment) & ~n_pot_alignment; // rounds towards positive infinity (i.e. negative towards zero)
}
Note that both of those round negative values towards zero (that means round to positive infinity for all values), neither of them relies on signed overflow (which is undefined in C/C++).
This gives:
n_Align_Up(10, 100) = 100
n_Align_Up(110, 100) = 200
n_Align_Up(0, 100) = 0
n_Align_Up(-10, 100) = 0
n_Align_Up(-110, 100) = -100
n_Align_Up(-210, 100) = -200
n_Align_Up_POT(10, 128) = 128
n_Align_Up_POT(130, 128) = 256
n_Align_Up_POT(0, 128) = 0
n_Align_Up_POT(-10, 128) = 0
n_Align_Up_POT(-130, 128) = -128
n_Align_Up_POT(-260, 128) = -256
Round to nearest multiple that happens to be a power of 2
unsigned int round(unsigned int value, unsigned int multiple){
return ((value-1u) & ~(multiple-1u)) + multiple;
}
This can be useful for when allocating along cachelines, where the rounding increment you want is a power of two, but the resulting value only needs to be a multiple of it. On gcc the body of this function generates 8 assembly instructions with no division or branches.
round( 0, 16) -> 0
round( 1, 16) -> 16
round( 16, 16) -> 16
round(257, 128) -> 384 (128 * 3)
round(333, 2) -> 334
Probably safer to cast to floats and use ceil() - unless you know that the int division is going to produce the correct result.
int noOfMultiples = int((numToRound / multiple)+0.5);
return noOfMultiples*multiple
C++ rounds each number down,so if you add 0.5 (if its 1.5 it will be 2) but 1.49 will be 1.99 therefore 1.
EDIT - Sorry didn't see you wanted to round up, i would suggest using a ceil() method instead of the +0.5
well for one thing, since i dont really understand what you want to do, the lines
int roundUp = roundDown + multiple;
int roundCalc = roundUp;
return (roundCalc);
could definitely be shortened to
int roundUp = roundDown + multiple;
return roundUp;
may be this can help:
int RoundUpToNearestMultOfNumber(int val, int num)
{
assert(0 != num);
return (floor((val + num) / num) * num);
}
To always round up
int alwaysRoundUp(int n, int multiple)
{
if (n % multiple != 0) {
n = ((n + multiple) / multiple) * multiple;
// Another way
//n = n - n % multiple + multiple;
}
return n;
}
alwaysRoundUp(1, 10) -> 10
alwaysRoundUp(5, 10) -> 10
alwaysRoundUp(10, 10) -> 10
To always round down
int alwaysRoundDown(int n, int multiple)
{
n = (n / multiple) * multiple;
return n;
}
alwaysRoundDown(1, 10) -> 0
alwaysRoundDown(5, 10) -> 0
alwaysRoundDown(10, 10) -> 10
To round the normal way
int normalRound(int n, int multiple)
{
n = ((n + multiple/2)/multiple) * multiple;
return n;
}
normalRound(1, 10) -> 0
normalRound(5, 10) -> 10
normalRound(10, 10) -> 10
I found an algorithm which is somewhat similar to one posted above:
int[(|x|+n-1)/n]*[(nx)/|x|], where x is a user-input value and n is the multiple being used.
It works for all values x, where x is an integer (positive or negative, including zero). I wrote it specifically for a C++ program, but this can basically be implemented in any language.
For negative numToRound:
It should be really easy to do this but the standard modulo % operator doesn't handle negative numbers like one might expect. For instance -14 % 12 = -2 and not 10. First thing to do is to get modulo operator that never returns negative numbers. Then roundUp is really simple.
public static int mod(int x, int n)
{
return ((x % n) + n) % n;
}
public static int roundUp(int numToRound, int multiple)
{
return numRound + mod(-numToRound, multiple);
}
This is what I would do:
#include <cmath>
int roundUp(int numToRound, int multiple)
{
// if our number is zero, return immediately
if (numToRound == 0)
return multiple;
// if multiplier is zero, return immediately
if (multiple == 0)
return numToRound;
// how many times are number greater than multiple
float rounds = static_cast<float>(numToRound) / static_cast<float>(multiple);
// determine, whether if number is multiplier of multiple
int floorRounds = static_cast<int>(floor(rounds));
if (rounds - floorRounds > 0)
// multiple is not multiplier of number -> advance to the next multiplier
return (floorRounds+1) * multiple;
else
// multiple is multiplier of number -> return actual multiplier
return (floorRounds) * multiple;
}
The code might not be optimal, but I prefer clean code than dry performance.
int roundUp (int numToRound, int multiple)
{
return multiple * ((numToRound + multiple - 1) / multiple);
}
although:
won't work for negative numbers
won't work if numRound + multiple overflows
would suggest using unsigned integers instead, which has defined overflow behaviour.
You'll get an exception is multiple == 0, but it isn't a well-defined problem in that case anyway.
c:
int roundUp(int numToRound, int multiple)
{
return (multiple ? (((numToRound+multiple-1) / multiple) * multiple) : numToRound);
}
and for your ~/.bashrc:
roundup()
{
echo $(( ${2} ? ((${1}+${2}-1)/${2})*${2} : ${1} ))
}
I use a combination of modulus to nullify the addition of the remainder if x is already a multiple:
int round_up(int x, int div)
{
return x + (div - x % div) % div;
}
We find the inverse of the remainder then modulus that with the divisor again to nullify it if it is the divisor itself then add x.
round_up(19, 3) = 21
Here's my solution based on the OP's suggestion, and the examples given by everyone else. Since most everyone was looking for it to handle negative numbers, this solution does just that, without the use of any special functions, i.e. abs, and the like.
By avoiding the modulus and using division instead, the negative number is a natural result, although it's rounded down. After the rounded down version is calculated, then it does the required math to round up, either in the negative or positive direction.
Also note that no special functions are used to calculate anything, so there is a small speed boost there.
int RoundUp(int n, int multiple)
{
// prevent divide by 0 by returning n
if (multiple == 0) return n;
// calculate the rounded down version
int roundedDown = n / multiple * multiple;
// if the rounded version and original are the same, then return the original
if (roundedDown == n) return n;
// handle negative number and round up according to the sign
// NOTE: if n is < 0 then subtract the multiple, otherwise add it
return (n < 0) ? roundedDown - multiple : roundedDown + multiple;
}
I think this should help you. I have written the below program in C.
# include <stdio.h>
int main()
{
int i, j;
printf("\nEnter Two Integers i and j...");
scanf("%d %d", &i, &j);
int Round_Off=i+j-i%j;
printf("The Rounded Off Integer Is...%d\n", Round_Off);
return 0;
}
Endless possibilities, for signed integers only:
n + ((r - n) % r)
/// Rounding up 'n' to the nearest multiple of number 'b'.
/// - Not tested for negative numbers.
/// \see http://stackoverflow.com/questions/3407012/
#define roundUp(n,b) ( (b)==0 ? (n) : ( ((n)+(b)-1) - (((n)-1)%(b)) ) )
/// \c test->roundUp().
void test_roundUp() {
// yes_roundUp(n,b) ( (b)==0 ? (n) : ( (n)%(b)==0 ? n : (n)+(b)-(n)%(b) ) )
// yes_roundUp(n,b) ( (b)==0 ? (n) : ( ((n + b - 1) / b) * b ) )
// no_roundUp(n,b) ( (n)%(b)==0 ? n : (b)*( (n)/(b) )+(b) )
// no_roundUp(n,b) ( (n)+(b) - (n)%(b) )
if (true) // couldn't make it work without (?:)
{{ // test::roundUp()
unsigned m;
{ m = roundUp(17,8); } ++m;
assertTrue( 24 == roundUp(17,8) );
{ m = roundUp(24,8); }
assertTrue( 24 == roundUp(24,8) );
assertTrue( 24 == roundUp(24,4) );
assertTrue( 24 == roundUp(23,4) );
{ m = roundUp(23,4); }
assertTrue( 24 == roundUp(21,4) );
assertTrue( 20 == roundUp(20,4) );
assertTrue( 20 == roundUp(19,4) );
assertTrue( 20 == roundUp(18,4) );
assertTrue( 20 == roundUp(17,4) );
assertTrue( 17 == roundUp(17,0) );
assertTrue( 20 == roundUp(20,0) );
}}
}
This is getting the results you are seeking for positive integers:
#include <iostream>
using namespace std;
int roundUp(int numToRound, int multiple);
int main() {
cout << "answer is: " << roundUp(7, 100) << endl;
cout << "answer is: " << roundUp(117, 100) << endl;
cout << "answer is: " << roundUp(477, 100) << endl;
cout << "answer is: " << roundUp(1077, 100) << endl;
cout << "answer is: " << roundUp(52,20) << endl;
cout << "answer is: " << roundUp(74,30) << endl;
return 0;
}
int roundUp(int numToRound, int multiple) {
if (multiple == 0) {
return 0;
}
int result = (int) (numToRound / multiple) * multiple;
if (numToRound % multiple) {
result += multiple;
}
return result;
}
And here are the outputs:
answer is: 100
answer is: 200
answer is: 500
answer is: 1100
answer is: 60
answer is: 90
I think this works:
int roundUp(int numToRound, int multiple) {
return multiple? !(numToRound%multiple)? numToRound : ((numToRound/multiple)+1)*multiple: numToRound;
}
The accepted answer doesn't work very well, I thought I'd try my hand at this problem, this should round up all integers you throw at it:
int round_up(int input, unsigned int multiple) {
if (input < 0) { return input - input % multiple; }
return input + multiple - (((input - 1) % multiple) + 1);
}
If the number is negative it's easy, take the remainder and add it onto the input, that'll do the trick.
If the number is not negative, you have to subtract the remainder from the multiple and add that to round up. The problem with that is that if input is exactly on a multiple, it will still get rounded up to the next multiple because multiple - 0 = multiple.
To remedy this we do a cool little hack: subtract one from input before doing the remainder, then add it back on to the resulting remainder. This doesn't affect anything at all unless input is on a multiple. In that case, subtracting one will cause the remainder to the previous multiple to be calculated. After adding one again, you'll have exactly the multiple. Obviously subtracting this from itself yields 0, so your input value doesn't change.