Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Write your own implementation of math's floor function, C

Tags:

c

math

floor

I was thinking about the floor function available in math.h. It is very easy to use it:

#include <stdio.h>
#include <math.h>
 
int main(void)
{
  for (double a = 12.5; a < 13.4; a += 0.1)
    printf("floor of  %.1lf is  %.1lf\n", a, floor(a));
  return 0;
}

What if I would like to write my own implementation of it? Would it look simply like this:

#include <stdio.h>
#include <math.h>

double my_floor(double num)
{
    return (int)num;
}

int main(void)
{
    double a;

    for (a = 12.5; a < 13.4; a += 0.1)
        printf("floor of  %.1lf is  %.1lf\n", a, floor(a));

    printf("\n\n");

    for (a = 12.5; a < 13.4; a += 0.1)
        printf("floor of  %.1lf is  %.1lf\n", a, my_floor(a));

    return 0;
}

?

It seems it does not work with negative numbers (my_floor), but the second one seems to be fine (my_floor_2):

#include <stdio.h>
#include <math.h>

double my_floor(double num)
{
    return (int)num;
}

double my_floor_2(double num)
{
    if(num < 0)
        return (int)num - 1;
    else
        return (int)num;
}

int main(void)
{
    double a1 = -12.5;

    printf("%lf\n", floor(a1));
    printf("%lf\n", my_floor(a1));
    printf("%lf\n", my_floor_2(a1));

    return 0;
}

program output:

-13.000000
-12.000000
-13.000000

Is one of them eventually correct or not?

like image 905
darias Avatar asked Jan 25 '17 16:01

darias


People also ask

What is the function of floor in C?

C floor() The floor() function calculates the nearest integer less than the argument passed.

How do you write a floor function?

The floor function (also known as the greatest integer function) ⌊ ⋅ ⌋ : R → Z \lfloor\cdot\rfloor: \mathbb{R} \to \mathbb{Z} ⌊⋅⌋:R→Z of a real number x denotes the greatest integer less than or equal to x.

What is an example of a floor function?

Floor Function Formula It gives the largest nearest integer of the specified value. Example: Find the floor value of 3.7. If we see, the number of integers less than 3.7, is 3,2,1,0 and so on. So, the highest integer will be 3.


1 Answers

Both of your attempts have limitations:

  • If the double value is outside the range of the int type, converting to int is implementation defined.
  • If the double value is negative but integral, returning (int)num - 1 is incorrect.

Here is an (almost) portable version that tries to handle all cases:

double my_floor_2(double num) {
    if (num >= LLONG_MAX || num <= LLONG_MIN || num != num) {
        /* handle large values, infinities and nan */
        return num;
    }
    long long n = (long long)num;
    double d = (double)n;
    if (d == num || num >= 0)
        return d;
    else
        return d - 1;
}

It should be correct if type long long has more value bits than type double, which is the case on most modern systems.

like image 95
chqrlie Avatar answered Oct 09 '22 07:10

chqrlie