Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ceil function using limited set of arithmetic operators

Tags:

algorithm

math

Is it possible to calculate a ceiling (e.g ceil(2.12) = 3) with only a few arithmetic operations available: * - + / I.e. without casting and other software tricks, only using division/mul/sub/addition and comparison operators?

Clarifications:

  • Complexity is important, but I will be glad to hear any solutions.
  • Modulus not available.
  • Values are positive.
  • Operations are not rounding.
  • By software tricks I meant mod, bit level manipulations, etc.

Basically I have a system which allows assigning expressions to variables where expression can contain only the above 4 arithmetic operation, comparisons, and loops. E.g.

var x = if (A * (1.434 + 0.4325)) > 54.4534) then 45.6 else then 43.435

and I would like to do

var x = CEIL(...)

like image 870
orom Avatar asked Mar 04 '13 12:03

orom


People also ask

How the Ceil () function will operate?

The ceil function returns the smallest possible integer value which is equal to the value or greater than that. This function is declared in “cmath” header file in C++ language. It takes single value whoes ceil value is to be calculated. The datatype of variable should be double/float/long double only.

Why ceil function is not working?

This is because the expressions are evaluated before being passed as an argument to the ceil function. You need to cast one of them to a double first so the result will be a decimal that will be passed to ceil.

How do I find the value of ceil?

Using simple maths, we can add the denominator to the numerator and subtract 1 from it and then divide it by denominator to get the ceiling value. Given below is the illustration of the above approach: C++ Java.


1 Answers

It is possible, but don't expect any amazing performance. The simplest algorithm (th(x)) is:

frac = x;
while(frac<0) frac+=1;
while(frac>=1) frac-=1;

if(frac>0) return x-frac+1;
else return x;

You can do better via binary search (th(log x)):

lower = 0;
upper = 0;
if(x>0){
  upper = 1;
  while (x > upper) upper *= 2;
}else if(x<0){
  lower = -1;
  while (x > lower) lower *= 2;
}

while(upper-lower > 1){
  //mid is guaranteed to be integer, since the upper-lower is a power of two
  mid = (upper+lower)/2; 
  if(x > mid) lower = mid;
  else if(x < mid) upper = mid;
  else return mid;
}

return upper; // lower for floor
like image 151
John Dvorak Avatar answered Sep 22 '22 12:09

John Dvorak