Skip to content

Commit

Permalink
mod_base: add filter round_significant (0.x) (#3143)
Browse files Browse the repository at this point in the history
  • Loading branch information
mworrell committed Oct 11, 2022
1 parent 6c91749 commit cf2b546
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 0 deletions.
33 changes: 33 additions & 0 deletions doc/ref/filters/filter_round_significant.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
.. highlight:: django
.. include:: meta-round_significant.rst

Round a number value to a number of significant digits.
The significance defaults to two digits.

Example::

{{ 1256|round_significant }}
{{ 1256|round_significant:1 }}
{{ 1256|round_significant:3 }}

Results in::

1300
1000
1260

Floating point values are also rounded to a number of digits. For example
if ``n`` is set to ``1256.78`` then::

{{ n|round_significant }}
{{ n|round_significant:3 }}
{{ n|round_significant:5 }}

Results in::

1300.0
1260.0
1256.8

Input values that are not a number are converted to a floating point value. If the
conversion fails then ``undefined`` is returned.
1 change: 1 addition & 0 deletions doc/ref/filters/numbers/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ Numbers
../filter_minmax
../filter_rand
../filter_round
../filter_round_significant
../filter_to_integer
61 changes: 61 additions & 0 deletions modules/mod_base/filters/filter_round_significant.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
%% @author Marc Worrell <marc@worrell.nl>
%% @copyright 2022 Marc Worrell
%% @doc Round a value to the give significant digits. If you need to
%% round to a number of digits after the decimal point then use the
%% "round" filter.

%% Copyright 2022 Marc Worrell
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
%%
%% http://www.apache.org/licenses/LICENSE-2.0
%%
%% Unless required by applicable law or agreed to in writing, software
%% distributed under the License is distributed on an "AS IS" BASIS,
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.

-module(filter_round_significant).

-export([
round_significant/2,
round_significant/3
]).

round_significant(Value, Context) ->
round_significant(Value, 2, Context).

round_significant(undefined, _Significance, _Context) ->
undefined;
round_significant(N, Significance, _Context) when is_integer(N) ->
Digits = digits(N),
if
Digits =< Significance ->
N;
true ->
Delta = Digits - Significance,
Divider = math:pow(10, Delta),
erlang:trunc(erlang:round(N / Divider) * Divider)
end;
round_significant(N, Significance, _Context) ->
try
F = z_convert:to_float(N),
Digits = digits(N),
Delta = abs(Digits - Significance),
Divider = math:pow(10, Delta),
if
Digits =< Significance ->
erlang:round(F * Divider) / Divider;
true ->
erlang:round(F / Divider) * Divider
end
catch
_:_ -> undefined
end.

digits(N) ->
1 + erlang:trunc(math:log10(N)).

0 comments on commit cf2b546

Please sign in to comment.