…values are rounded to the closest multiple of 10 to the power minus ndigits; if two multiples are equally close, rounding is done toward the even choice (so, for example, both round(0.5) and round(-0.5) are 0, and round(1.5) is 2).
Note: The behavior of round() for floats can be surprising: for example, round(2.675, 2) gives 2.67 instead of the expected 2.68. This is not a bug: it’s a result of the fact that most decimal fractions can’t be represented exactly as a float.
I saw it.
But this is a merely short description how it is implemented.
The question is “why to use a non-precise processing”?
I would call this “weird”:
This is agreed, but in mathematics rounding “0.5” is always “up”…
Probably it should be the 4th method - “up”, “down”, current “even/odd” and “mathematical”.
I assume this convention differs around the world and/or across fields.
I would prefer .5 to round up because I am comfortable with it, but it’s not critical.
To be honest, I assumed that it was rounding up until I saw this thread!
Is there a way to have this without own calculating via special function or parameter? Didn’t find such. Wonder there is no other already asking/implemented it.
Rounding half away from zero
One may also round half away from zero (or round half toward infinity), a tie-breaking rule that is commonly taught and used, namely: If the fractional part of x is exactly 0.5, then y = x + 0.5 if x is positive, and y = x − 0.5 if x is negative.
For example, 23.5 gets rounded to 24, and −23.5 gets rounded to −24.
This method, also known as commercial rounding treats positive and negative values symmetrically, and therefore is free of overall positive/negative bias if the original numbers are positive or negative with equal probability. It does, however, still have bias away from zero.
So more or less a simpler way or a simple parameter to get this
{% set val = "-0.4" %}
{% set val = val|float %}
{% if val > 0 %}
{% if val % 1 >= 0.5 %}
{% set val = val|round(0,"ceil") %}
{% else %}
{% set val = val|round(0,"floor") %}
{% endif %}
{% else %}
{% if val % 1 > 0.5 %}
{% set val = val|round(0,"ceil") %}
{% else %}
{% set val = val|round(0,"floor") %}
{% endif %}
{% endif %}
{{ val }}
or
{% set val = "1.4" %}
{% set val = val|float %}
{% set val = ((val>0)-(val<0))*(val|abs+0.5)|int %}
{{ val }}