Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

math.floor(N) vs N // 1

Tags:

python

math

floor

I am wondering if anyone can give me any insight into how the following may be the same / different in Python3:

N // 1

and

from math import floor
floor(N)

I tried the following, which seems to indicate that they are equivalent:

import math
import random

for _ in range(0, 99999):
    f = random.random()
    n = random.randint(-9999, 9999)
    N = f * n
    n_div = N // 1; n_mth = math.floor(N)
    if n_div != n_mth:
        print("N // 1: {} | math.floor(N): {}".format(n_div, n_mth))
else: # yes, I realize this will always run
    print("Seem the same to me")

Thanks for comments below. Updated test to the following, which clearly shows float // N returns a float, while math.floor(N) returns an int in python3. As I understand it, this behavior is different in python2, where math.ceil and math.floor return floats.

Also note how unusual/silly it would be to use math.ceil or math.floor on an int instead of a float: either function operating on an int simply returns that int.

import math
import random

for _ in range(0, 99):
    N = random.uniform(-9999, 9999)
    n_div = N // 1; n_mth = math.floor(N)
    if n_div != n_mth:
        print("N: {} ... N // 1: {} | math.floor(N): {}".format(N, n_div, n_mth))
    elif type(n_div) != type(n_mth):
        print("N: {} ... N // 1: {} ({}) | math.floor(N): {} ({})".format(N, n_div, type(n_div), n_mth, type(n_mth)))
else:
    print("Seem the same to me")
like image 252
NotAnAmbiTurner Avatar asked Jun 03 '16 15:06

NotAnAmbiTurner


2 Answers

You will spot a difference when using floats:

>>> 1000.5//1
1000.0
>>> floor(1000.5)
1000

floor returns an integer. For most cases 1000 and 1000.0 are equivalent, but not always.

like image 184
Simon Fraser Avatar answered Nov 14 '22 22:11

Simon Fraser


  1. math.floor(N) returns an int, and N // 1 returns a float.

    >>> type(math.floor(-4.4))
    <class 'int'>
    >>> type((-4.4) // 1)
    <class 'float'>
    
  2. Because of this floor(nan) will raise ValueError while nan // 1 returns NaN (similar for ±inf.)

    >>> math.floor(math.nan)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    ValueError: cannot convert float NaN to integer
    >>> math.nan // 1
    nan
    

I don't think there are other differences when N is a float, since x//y is defined as ⌊x/y⌋.

like image 28
kennytm Avatar answered Nov 14 '22 22:11

kennytm