Rounding
The round() built-in function takes an optional second argument.
From a typing perspective, round() has two overloads, one with 1 parameter,
and one with two.
For both overloads, optype provides separate operand interfaces:
CanRound1[R] and CanRound2[T, RT].
Additionally, optype also provides their (overloaded) intersection type:
CanRound[-T, +R1, +R2] = CanRound1[R1] & CanRound2[T, R2].
| operator | operand | |||
|---|---|---|---|---|
| expression | function | type | method | type |
round(_) |
do_round/1 |
DoesRound |
__round__/1 |
CanRound1[+R=int] |
round(_, n) |
do_round/2 |
DoesRound |
__round__/2 |
CanRound2[-T=int, +R=float] |
round(_, n=...) |
do_round |
DoesRound |
__round__ |
CanRound[-T=int, +R1=int, +R2=float] |
For example, type-checkers will mark the following code as valid (tested with pyright in strict mode):
x: float = 3.14
x1: CanRound1[int] = x
x2: CanRound2[int, float] = x
x3: CanRound[int, int, float] = x
Furthermore, there are the alternative rounding functions from the
math standard library:
| operator | operand | |||
|---|---|---|---|---|
| expression | function | type | method | type |
math.trunc(_) |
do_trunc |
DoesTrunc |
__trunc__ |
CanTrunc[+R=int] |
math.floor(_) |
do_floor |
DoesFloor |
__floor__ |
CanFloor[+R=int] |
math.ceil(_) |
do_ceil |
DoesCeil |
__ceil__ |
CanCeil[+R=int] |
Almost all implementations use int for R.
In fact, if no type for R is specified, it will default in int.
But technically speaking, these methods can be made to return anything.