I'm working on a project that doesn't use any c libraries and can't figure it out
How do I create my own floor function in C? - Stack Overflow
How do the floor and ceiling functions work on negative numbers? - Mathematics Stack Exchange
Compilation error; why can't gcc recognize the floor function here?
Does anyone know how to create a floor function in c
Videos
The easiest solution would probably be to just let C do it. Per ยง 6.3.1.4 of the C11 spec:
When a finite value of real floating type is converted to an integer type other than _Bool, the fractional part is discarded (i.e., the value is truncated toward zero).
So, all you need to do is convert the value to an integer, than convert that back to a float:
float myFloor(float value) {
return (float) (int) value;
}
If you need to handle negatives, you can easily do so:
float myFloor(float value) {
float tmp = (float) (int) value;
return (tmp != value) ? (tmp - 1.0f) : tmp;
}
One way is to convert-
float myFloor(float value) {
return (float) (int) value;
}
but you can't tackle it this way. The best way of writing your own implementation is to steal the one from the C Standard Library on your platform. But note that might contain platform-specific nuances so might not be portable.
The C Standard Library floor function is typically clever in that it doesn't work by taking a conversion to an integral type. If it did then you'd run the risk of signed integer overflow, the behaviour of which is undefined. (Note that the smallest possible range for an int is -32767 to +32767).
The precise implementation is also dependent on the floating point scheme used on your platform.
For a platform using IEEE754 floating point, and a long long type you could adopt this scheme:
- If the magnitude of the number is greater than the 53rd power of 2, return it back (as it's already integral).
- Else, cast to a 64 bit type (long long), and return it back.
The first is the correct: you round "down" (i.e. the greatest integer LESS THAN OR EQUAL TO $-0.8$).
In contrast, the ceiling function rounds "up" to the least integer GREATER THAN OR EQUAL TO $-0.8 = 0$.
$$ \begin{align} \lfloor{-0.8}\rfloor & = -1\quad & \text{since}\;\; \color{blue}{\bf -1} \le -0.8 \le 0 \\ \\ \lceil {-0.8} \rceil & = 0\quad &\text{since} \;\; -1 \le -0.8 \le \color{blue}{\bf 0} \end{align}$$
In general, we must have that $$\lfloor x \rfloor \leq x\leq \lceil x \rceil\quad \forall x \in \mathbb R$$
And so it follows that $$-1 = \lfloor -0.8 \rfloor \leq -0.8 \leq \lceil -0.8 \rceil = 0$$
K.Stm's suggestion is a nice, intuitive way to recall the relation between the floor and the ceiling of a real number $x$, especially when $x\lt 0$. Using the "number line" idea and plotting $-0.8$ with the two closest integers that "sandwich" $-0.8$ gives us:
$\qquad\qquad$
We see that the floor of $x= -0.8$ is the first integer immediately to the left of $-0.8,\;$ and the ceiling of $x= -0.8$ is the first integer immediately to the right of $-0.8$, and this strategy can be used, whatever the value of a real number $x$.
Keep in mind that $\lfloor x \rfloor \le x \le \lceil x \rceil$, so it's the first one.
More precisely, for $x \in \Bbb{R}$, $$ \lfloor x \rfloor = \max \{ z \in \Bbb{Z} : z \le x \} $$ while $$ \lceil x \rceil = \min \{ z \in \Bbb{Z} : x \le z \}. $$