17
\$\begingroup\$

Your task is to implement a floor function in as few bytes as possible.

A floor function is a function that takes a real number and returns the largest integer less than or equal to the input.

Your program should support both positive and negative inputs. Since it is provably impossible to support all real numbers you need only support a reasonable subset of them. This subset should include positive numbers, negative numbers and of course numbers that are not integers. Such number systems include fixed-point numbers, floating point numbers and strings.

Your code may be a complete program or function.

This is so answers will be scored in bytes with less bytes being a better score.

\$\endgroup\$
8
  • 1
    \$\begingroup\$ Any limits on the size of the numbers to be handled correctly? Need to treat negatives? \$\endgroup\$ Commented Jan 31, 2011 at 17:00
  • 1
    \$\begingroup\$ I ask about range because single precision IEEE 745 floating point runs up to 2^127, which is to say that 64 bit integers would not be sufficient. \$\endgroup\$ Commented Jan 31, 2011 at 17:21
  • \$\begingroup\$ @dmckee The problem definition states any real number, not just positive ones. As far as number size is concerned, let's assume that is not a concern (i.e., an answer that handles that case is not necessarily better than an answer that doesn't handle that case, unless of course it is of equal or lesser length). \$\endgroup\$ Commented Jan 31, 2011 at 19:39
  • 2
    \$\begingroup\$ In golfscript, this would be zero bytes since x is already an integer :) \$\endgroup\$
    – gnibbler
    Commented Jan 31, 2011 at 20:53
  • 1
    \$\begingroup\$ @TheGuywithTheHat Type casting is fine, but this does not give the correct answer. \$\endgroup\$ Commented Apr 7, 2014 at 17:15

44 Answers 44

8
\$\begingroup\$

PARI/GP (10)

In gp (and some other languages) x%1 gives the decimal part of x:

f(x)=x-x%1

NOTE: For negative x, x%1 returns (1 - abs(decimal part of x)), so the above works both for positive and negative numbers.

\$\endgroup\$
8
  • 1
    \$\begingroup\$ @Joey: no it does not. Yields -4 for floor(-3.1234); -4 for floor(-4). What do you get? \$\endgroup\$
    – Eelvex
    Commented Jan 31, 2011 at 17:10
  • 1
    \$\begingroup\$ x - x % 1 gives -3 for -3.1234, surely, when the expected answer is -4 \$\endgroup\$
    – Nellius
    Commented Jan 31, 2011 at 17:30
  • \$\begingroup\$ @Nellius: NO, because -3.1234%1 = 0.8766. \$\endgroup\$
    – Eelvex
    Commented Jan 31, 2011 at 17:39
  • 1
    \$\begingroup\$ Ok, I take that back, partially. Because the sign of the modulus result depends on the operand in some languages but not in others. For me, -3.14 % 1 yields -.14 (PowerShell). Now, if you'd be so kind to make a null edit so I can take the downvote back? :-) \$\endgroup\$
    – Joey
    Commented Jan 31, 2011 at 17:40
  • 1
    \$\begingroup\$ You can shave off 2 characters with x->x-x%1. If not for the restriction you could use x->x\1 which is another 2 characters shorter. \$\endgroup\$
    – Charles
    Commented Apr 28, 2015 at 14:48
6
\$\begingroup\$

Javascript - 6 bytes

Usage of the arrow function declaration (as an anonymous function here) and a bitwise "AND" operator

x=>x&x

Try it online!

or alternatively using the bitwise "OR" operator:

x=>x|0

Try it online!

\$\endgroup\$
2
  • 2
    \$\begingroup\$ Welcome to the site! You can shave two bytes off, by removing the name of the function; as long as functions aren't recursive, the name isn't necessary. Also, is it possible to provide a link to a site such as TryItOnline where other users can verify your answer? \$\endgroup\$ Commented Jul 14, 2020 at 19:22
  • 1
    \$\begingroup\$ Surely. Thank you for the advice :) \$\endgroup\$ Commented Jul 14, 2020 at 21:10
5
\$\begingroup\$

Python (20)

f=lambda x:int(x//1)

or, if the result doesn't need to be of type int, 15 characters:

f=lambda x:x//1
\$\endgroup\$
1
  • \$\begingroup\$ Two notes: 1. you can skip the f= part, as it is not recursive. 2. please state, that this is Python 3 code and not Python 2 \$\endgroup\$
    – movatica
    Commented Jan 21, 2021 at 17:06
5
\$\begingroup\$

JavaScript, 50 34 33 32 characters

function f(n){return~~n-(~~n>n)}

Works the same way as the PHP one I submitted.

\$\endgroup\$
3
  • 1
    \$\begingroup\$ 32 chars if you drop the ; \$\endgroup\$
    – zzzzBov
    Commented Mar 12, 2011 at 6:04
  • 4
    \$\begingroup\$ If you use ES6, it is 14 characters:n=>~~n-(~~n>n) \$\endgroup\$ Commented Dec 26, 2015 at 14:07
  • \$\begingroup\$ 8 bytes: n=>n-n%1 \$\endgroup\$ Commented Apr 29, 2021 at 11:22
4
\$\begingroup\$

DC (15 bytes)

Makes use of a nifty little trick that occurs during division in DC. Add a 'p' to then end to get output (it performs the floor correctly anyway), I assume that stuff is not already on the stack, and that input is in stdin.

[1-]sazk?z/d0>a

EG: echo 0 2.6 - | dc -e '[1-]sazk?z/d0>ap'

\$\endgroup\$
4
\$\begingroup\$

Python (81)

def f(x):return str(x - float("." + str(float(x)).split('.')[-1])).split('.')[0]
\$\endgroup\$
1
  • 2
    \$\begingroup\$ You can go down to 76 bytes by removing unnecessary spaces! def f(x):return str(x-float("."+str(float(x)).split('.')[-1])).split('.')[0] \$\endgroup\$
    – Daniel
    Commented Dec 26, 2015 at 5:03
3
\$\begingroup\$

C (51)

int F(float x){int i=x-2;while(++i<=x-1);return i;}
\$\endgroup\$
5
  • \$\begingroup\$ Generally code gold answers are expected to be in the form of either a function or a complete program (here the OP has selected a function), so you need the int f(float c){} bit. \$\endgroup\$ Commented Jan 31, 2011 at 17:32
  • \$\begingroup\$ @dmckee: forgot that, sorry. \$\endgroup\$
    – Eelvex
    Commented Jan 31, 2011 at 17:44
  • \$\begingroup\$ Why <=x-1? would <x not be exactly the same thing, but 3 characters shorter? \$\endgroup\$
    – Nellius
    Commented Jan 31, 2011 at 20:11
  • \$\begingroup\$ @Nellius: no, it's not the same (unfortunately). \$\endgroup\$
    – Eelvex
    Commented Jan 31, 2011 at 20:21
  • \$\begingroup\$ @Nellius: only when x is an integer: compare "<=3.5-1" with "<3.5". \$\endgroup\$ Commented Feb 2, 2011 at 1:50
3
\$\begingroup\$

LISP (26)

(Same trick as in PARI/GP answer)

(defun f(x)(- x(mod x 1)))
\$\endgroup\$
2
  • \$\begingroup\$ You can strip off the space before the (mod. \$\endgroup\$ Commented Jan 31, 2011 at 20:06
  • \$\begingroup\$ @Chris: :) Thx. \$\endgroup\$
    – Eelvex
    Commented Jan 31, 2011 at 20:12
3
\$\begingroup\$

C 126 (including NL)

Doesn't use any built-in conversion such as (int)x.

r(float x) {
int
p=*(int*)&x,
f=p&8388607|1<<23,
e=((p>>23)&255)-150;
if(e>0)f*=1<<e;
if(e<0)f/=1<<-e;
return p>>31?-f-1:f;
}
\$\endgroup\$
3
\$\begingroup\$

J 7 chars

f=:-1&|  NB. x - (x mod 1)

eg.

f 3.14
3
f _3.14
_4
\$\endgroup\$
1
  • 1
    \$\begingroup\$ Is there a good reason this isn't the accepted answer? \$\endgroup\$
    – cat
    Commented Dec 26, 2015 at 20:02
3
\$\begingroup\$

C (80)

Well it's not the shortest, but it's a great opportunity to show off my bit twiddling skills :D.

main(){int I,X=0x7FFFFF;scanf("%f",&I);printf("%d",((I&X)|X+1)>>-(I>>23)+150);}
\$\endgroup\$
3
\$\begingroup\$

C, 42 41 bytes

int F(float x){int i=x;return i<=x?i:i-1;}

Try it online!

int F(float x){int i=x;return x>i?i:i-1;}

Try it online!

\$\endgroup\$
3
  • \$\begingroup\$ Welcome to Code Golf, nice first answer! \$\endgroup\$
    – rydwolf
    Commented Jan 21, 2021 at 14:21
  • \$\begingroup\$ Hi there, welcome to CGCC. If you haven't seen it yet, tips for golfing in C and tips for golfing in <all languages> might be interesting to read through. :) Some golfs you could do to your current function: <= could be > (and the values swapped) for -1 byte; return can be x= for -5 bytes; and you can remove the leading int (it will give a warning, but we can ignore that) for -4 bytes. So in total: F(float x){int i=x;x=i>x?i-1:i;} (32 bytes). Enjoy your stay! :) \$\endgroup\$ Commented Jan 21, 2021 at 16:28
  • \$\begingroup\$ @KevinCruijssen Thanks for the tips. I don't understand all your tips. It looks too nonstandard to me. So I only used your first tip. \$\endgroup\$
    – elechris
    Commented Jan 22, 2021 at 13:12
2
\$\begingroup\$

Ruby 1.9 (12 14)

 f=->x{x-x%1}

It's more a "for the record" type solution along the lines of the PARI/GP one.

>> f[3.4] #=> 3.0
>> f[-3.4] #=> -4.0
\$\endgroup\$
1
  • \$\begingroup\$ You don't need the parentheses around x%1. \$\endgroup\$
    – Ventero
    Commented Mar 14, 2011 at 19:22
2
\$\begingroup\$

Julia, 17 bytes

f(x)=x-x%1-(x<0)

port of the PARI/GP answer

f(-pi) = -4
f(pi) = 3
\$\endgroup\$
2
\$\begingroup\$

APL, 1 byte (SBCS)

According to the updated rules, built-ins are allowed:

APL (dzaima/APL), 5 4 bytes

Anonymous tacit prefix function abiding by the old prohibition on built-ins:

⊢-1|

Try it online!

 the argument

- minus

1| the division remainder when divided by 1

\$\endgroup\$
2
\$\begingroup\$

Turing Machine Code, 39 bytes

0 * * r 0
0 _ _ l 1
1 * _ l 1
1 . _ l 2

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Perl (23)

$_=int($_)-(int($_)>$_)

Example:

perl -ple '$_=int($_)-(int($_)>$_)'

Every value entered on input will now be printed "floored".

Its bass5098's technique, but smaller =).

As a function(36):

sub f{int($_[0])-(int($_[0])>$_[0])}
\$\endgroup\$
2
  • \$\begingroup\$ Any particular reason for shying away from regex? \$\endgroup\$
    – Codefun64
    Commented Dec 27, 2015 at 7:07
  • \$\begingroup\$ This can be shortened by getting rid of the default variable: $_=(int)-($_<int) \$\endgroup\$
    – Xcali
    Commented Apr 30, 2021 at 0:44
1
\$\begingroup\$

C# (56 chars):

My quick and naive answer earlier had a stupid logical flaw in it. Two approaches here, which I believe are both the same length. Double approach relies on the fact that casting to int removes the decimal part of a double.

int F(double d){return(int)(d%1==0?d:(int)d-(d<0?1:0));}

Decimal approach relies on the fact that d%1 returns the decimal part of the number for decimal data type.

int F(decimal d){return(int)(d%1==0?d:d-d%1-(d<0?1:0));}

Could save a few characters in both cases by returning their own type instead of int, but I feel a floor function should return an int.

\$\endgroup\$
1
  • \$\begingroup\$ You can use float instead and save a byte. \$\endgroup\$
    – Joey
    Commented Mar 12, 2011 at 10:52
1
\$\begingroup\$

PHP, 51 45 43 37 characters

function f($n){return~~$n-(~~$n>$n);}

This should be able to be applied to most languages that do not support the n%1 trick.

\$\endgroup\$
1
  • \$\begingroup\$ Since this does not need to be an independently working program, I think you can safely trim the first 3 characters (i.e. the <? ) off your solution. \$\endgroup\$ Commented Jan 31, 2011 at 21:55
1
\$\begingroup\$

RProgN 2, 4 bytes

]1%-

Explained

]1%-
]   # Duplicate the implicit input
 1% # Modulo 1
   -# Subtract Modulo 1 of the input from the input, inplicitly outputting the floor'd result.

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Java 8, 19 bytes

Lambda from double to int. There are plenty of choices for types to assign to: Function<Double, Integer>, DoubleFunction<Integer>, or DoubleToIntFunction.

n->(int)(n<0?n-1:n)

Try It Online

\$\endgroup\$
1
\$\begingroup\$

x86_64 machine language (Linux), 11 bytes

0:       c4 e3 79 0b c0 01       vroundsd $0x1,%xmm0,%xmm0,%xmm0
6:       f2 0f 2c c0             cvttsd2si %xmm0,%eax
a:       c3                      retq

This requires a processor with AVX instructions.

To Try it online!, compile and run the following C program.

#include<stdio.h>
#include<math.h>
int f(double x){return floor(x);}
const char g[]="\xc4\xe3\x79\x0b\xc0\x01\xf2\x0f\x2c\xc0\xc3";

int main(){
  for( double d = -1.5; d < 1.5; d+=.2 ) {
    printf( "%f %d %d\n", d, f(d), ((int(*)(double))g)(d) );
  }
}

\$\endgroup\$
1
\$\begingroup\$

Excel, 7

Tested in Excel Online. Closing parens not counted toward score.

The only reason I posted this is because, oddly enough, it seems to work the exact same as FLOOR.MATH() with 1 argument.

=INT(A1)

Semantically, at least to me, it would make sense if this didn't work for negative numbers. However, INT(-.5) is -1 for some reason. TRUNC() does what I think INT() should do.

\$\endgroup\$
1
\$\begingroup\$

C (gcc), 16 15 bytes

g;f(d){g=d>>9;}

Try it online!

Such number systems include fixed-point numbers, floating point numbers and strings.

I don't know why people insist on using floats... Fixed point is much easier 🙂

Uses 32-bit fixed9 precision. Abuses arithmetic shift right. Return hack, not much else to say.

\$\endgroup\$
3
  • \$\begingroup\$ I think you can save 3 bytes by cutting off g; and doing d>>=9; \$\endgroup\$
    – anotherOne
    Commented Jan 21, 2021 at 19:31
  • \$\begingroup\$ Nah, that doesn't work. Undefined behavior is weird. \$\endgroup\$
    – EasyasPi
    Commented Jan 22, 2021 at 3:11
  • \$\begingroup\$ Oh all right, it was worth trying \$\endgroup\$
    – anotherOne
    Commented Jan 22, 2021 at 12:56
1
\$\begingroup\$

x86-64 machine code, 7 bytes

Machine code:

00000000: 66 0f 3a 0b c0 01 c3                             f.:....

Assembly:

        .intel_syntax noprefix
        .globl floor_sse4
floor_sse4:
        roundsd xmm0, xmm0, 1
        ret

Try it online!

Accepts a double in an xmm0.

Returns the floored double in xmm0.

Outgolfs the previous answer without cheesing with fixed point.

  • Nowhere did it say the return type had to be an int, just an integer. Therefore, I can just skip the conversion code, storing the integer as a double. JavaScript has been doing it for decades.
  • This one only requires SSE4.1. 😏

Yes, I know the SSE conversion functions are a little redundant in the test code.

x86-64 machine code, fixed point joke, 1 byte

Machine code:

00000000: c3                                               .

Assembly:

        .intel_syntax noprefix
        .globl floor_fixed
floor_fixed:
        ret

Try it online!

This function takes a 16-bit fixed8 in ax and returns a signed 8-bit integer in ah. It is not sign extended.

Nobody gave any specifics about precision 😂

\$\endgroup\$
1
\$\begingroup\$

05AB1E, 2 bytes

Try it online or verify all values in the range \$[5,-5]\$ in \$0.1\$ increments.

Explanation:

O   # Sum the stack, which will use the (implicit) input-string if the stack is empty
    # (the input is read as string by default, so this `O` basically casts it to a float)
 ï  # Floor this input-float
    # (and output the resulting integer implicitly)

Although it may look pretty straight-forward, there are actually some things to note:

In the legacy version of 05AB1E, which was built in Python. The ï builtin would translate to the following code snippets:

# Pop number
a = str(number)         # Cast number to a string
a = ast.literal_eval(a) # Evaluate this string as Python structure (so it goes back to a float)
a = int(a)              # Cast this float to an integer (which will truncate)

So whether you had string input or decimal input, it would cast it to a string during the code execution anyway, before casting it to an integer to truncate all decimal values.

Try it online with -0.5 as decimal argument.
Try it online with "-0.5" as string argument.

The new version of 05AB1E is built in Elixir however. Now, the ï builtin translates to the following code snippets (huge parts removed to only keep the relevant stuff):

call_unary(fn x -> to_integer(x) end, a)      # Call the function `to_integer`, which will:
                                              # (I've only kept relevant parts of this function)
 is_float(value) -> round(Float.floor(value)) #  If it's a float: floor it down
 true ->                                      #  Else (it's a string):
     case Integer.parse(to_string(value)) do  #   Parse it from string to integer
        :error -> value                       #   If this resulted in an error: return as is
        {int, string} ->
            cond do                           #   Else it was parsed without errors:
                Regex.match?(~r/^\.\d+$/, string) -> int
                                              #    If it contains no decimal values:
                                              #      Return parsed int
                true -> value                 #    Else: return as is

Or as a TL;DR: float inputs are floored; string inputs are truncated.

Try it online with -0.5 as decimal argument.
Try it online with "-0.5" as string argument.

As you can see, a string input gives the incorrect floored result for negative decimals. Unfortunately, the default (implicit) input from STDIN is always a string, so we'll have to convert it to a float first (for which I've used O - which only works on an empty stack in the new 05AB1E version built in Elixir; for the legacy 05AB1E version built in Python, the sum would result in 0 for an empty stack).

\$\endgroup\$
4
  • \$\begingroup\$ In your TIO the floor of (for example) -4.7 is -4, but it actually is -5 \$\endgroup\$
    – anotherOne
    Commented Jan 21, 2021 at 19:20
  • \$\begingroup\$ @Davide Ah, I apparently had the output of negative values reversed. I thought the string input gave the correct results, but instead the float inputs give the correct results. Should be fixed now (at the cost of a byte). \$\endgroup\$ Commented Jan 22, 2021 at 7:40
  • 1
    \$\begingroup\$ Yeah it works now, I am sorry for the 100% increase in the number of bytes \$\endgroup\$
    – anotherOne
    Commented Jan 22, 2021 at 12:59
  • 1
    \$\begingroup\$ @Davide haha, np. Due to lack of test cases, I simply reversed the intended outputs for negative inputs. Thanks for noticing! \$\endgroup\$ Commented Jan 22, 2021 at 13:09
1
\$\begingroup\$

Vyxal, 3 bytes

1%-

Push input, modulo with 1 and negate!

Try it!

Vyxal, 1 byte

Though a builtin.....

Try it!

\$\endgroup\$
1
\$\begingroup\$

Hexagony, 31 bytes

,{.4{?<.(@!?\"!3'-<_".$>@>?~..@
    , { . 4
   { ? < . (
  @ ! ? \ " !
 3 ' - < _ " .
  $ > @ > ? ~
   . . @ . .
    . . . .

Try it online! or Try it online differently!

Takes input of the form +/-a.b, ex: +4.5 or -0.1 or +3. Since hexagony doesn't have built in decimal types, the input must contain a + if positive in order to not cut off the first digit of the number. This answer can definitely be improved, but its a start.

\$\endgroup\$
1
\$\begingroup\$

floor, 5 bytes

floor

The floor function is a (the only) built-in.

Full program (17 bytes):

Floor only accepts integers as program Input, so the program uses two inputs to generate a rational number to be passed to the floor function

f:x y->floor(x/y)

implementation

\$\endgroup\$
0
\$\begingroup\$

MATL, 5 bytes

The programming language used in this answer was created after the challenge was posted.

it1\-

Examples

>> matl it1\-
> 5.6
5

>> matl it1\-
> -5.2
-6

Explanation

Pretty straightforward. It uses a modulo operation with divisor 1.

i      % input                                                              
t      % duplicate                                                          
1      % number literal                                                     
\      % modulus after division
-      % subtraction
\$\endgroup\$
2
  • \$\begingroup\$ You should note that this language was developed wayyyyyy after this challenge. \$\endgroup\$
    – cat
    Commented Dec 26, 2015 at 17:58
  • 1
    \$\begingroup\$ @cat Sorry, I hadn't noticed. Disclaimer added \$\endgroup\$
    – Luis Mendo
    Commented Dec 26, 2015 at 18:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.