# [erlang-questions] Floor Function?

David Mercer dmercer@REDACTED
Mon Mar 16 16:11:22 CET 2009

```On 3/16, Hynek Vychodil wrote:

Are you sure that there is big difference between compute X-T and decide X<T
or which one is less expensive? I'm not! If you haven't measured ...

For what it's worth, I timed them, and ROK's is about 40-50% faster.  That
being said, my question was related more to whether I was lacking in my
documentation-searching abilities rather than to any difficulty in writing a
floor function.  However, as an Erlang hobbyist, I enjoyed the exercise in
timing, and completely overengineered my test harness for your pleasure.
Here's my code, in case you spot some error and so want to appeal my
conclusions:

> floor:test(10000000).

[{ippolito,[{runtime,17766},

{wall_clock,17782},

{runtime_speed_vs_okeefe,0.6877181132500282}]},

{okeefe,[{runtime,12218},

{wall_clock,12218},

{runtime_speed_vs_ippolito,1.454084138156818}]}]

-module(floor).

-export([ippolito/1, okeefe/1]).

-spec ippolito(float()) -> integer().

-spec okeefe  (float()) -> integer().

-export([test/1]).

-spec test(non_neg_integer()) -> term().

ippolito(X) ->

T = trunc(X),

case (X - T) of

Neg when Neg < 0 -> T - 1;

Pos when Pos > 0 -> T;

_ -> T

end.

okeefe(X) ->

T = trunc(X),

if X < T -> T - 1

; true  -> T

end.

test(N) ->

Tests = [{ippolito, fun ippolito/1}, {okeefe, fun okeefe/1}],

Results = [ {Name, test(F, N)} || {Name, F} <- Tests ],

test(F, N) ->

Args = [-4.0, -2.75, -1.5, -0.1, 0.0, 1.1, 2.5, 3.75, 4.0],

% Check to make sure results are accurate

ResultsAreAccurate = lists:seq(-4, 4) == [F(X) || X <- Args],

if ResultsAreAccurate -> ok end,

Fun = fun() -> lists:foreach(F, Args) end,

statistics(runtime),

statistics(wall_clock),

repeat(N, Fun),

{_, RunTime} = statistics(runtime),

{_, WallClockTime} = statistics(wall_clock),

[ {runtime, RunTime}, {wall_clock, WallClockTime}].

repeat(0, _F) -> ok;

repeat(N, F) -> F(), repeat(N - 1, F).

filter_out(Name) ->

fun

({OtherName, _}) when OtherName == Name -> false;

(_) -> true

end.

filter_out(Name, List) -> lists:filter(filter_out(Name), List).

fun({Name, Stats}) ->

Others = filter_out(Name, FullResults),

RunTime = proplists:get_value(runtime, Stats),

Comparisons =

[ {list_to_atom("runtime_speed_vs_" ++ atom_to_list(OtherName)),
SpeedComparison}

|| {OtherName, OtherStats} <- Others

, OtherRunTime <- [proplists:get_value(runtime,
OtherStats)]

, SpeedComparison <- [OtherRunTime / RunTime]

],

{Name, Stats ++ Comparisons}

end.

Cheers,

David

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20090316/77f5bd63/attachment.htm>
```