Skip to content

Commit 68e15a2

Browse files
committed
Add basic float.__round__ without ndigits support
1 parent fd91d26 commit 68e15a2

File tree

2 files changed

+40
-1
lines changed

2 files changed

+40
-1
lines changed

tests/snippets/math_basics.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,10 @@
1818
assert a - 3 == 1
1919
assert -a == -4
2020
assert +a == 4
21+
22+
assert round(1.2) == 1
23+
assert round(1.8) == 2
24+
assert round(0.5) == 0
25+
assert round(1.5) == 2
26+
assert round(-0.5) == 0
27+
assert round(-1.5) == -2

vm/src/obj/objfloat.rs

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@ use super::objbytes;
22
use super::objint;
33
use super::objstr;
44
use super::objtype;
5+
use crate::function::OptionalArg;
56
use crate::obj::objtype::PyClassRef;
67
use crate::pyobject::{
7-
IntoPyObject, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol,
8+
IdProtocol, IntoPyObject, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue,
9+
TypeProtocol,
810
};
911
use crate::vm::VirtualMachine;
1012
use num_bigint::{BigInt, ToBigInt};
@@ -357,6 +359,36 @@ impl PyFloat {
357359
self.value.to_bigint().unwrap()
358360
}
359361

362+
#[pymethod(name = "__round__")]
363+
fn round(&self, ndigits: OptionalArg<PyObjectRef>, vm: &VirtualMachine) -> PyObjectRef {
364+
let ndigits = match ndigits {
365+
OptionalArg::Missing => None,
366+
OptionalArg::Present(ref value) => {
367+
if !vm.get_none().is(value) {
368+
// retrive int to implement it
369+
Some(vm.ctx.not_implemented())
370+
} else {
371+
None
372+
}
373+
}
374+
};
375+
if ndigits.is_none() {
376+
let fract = self.value.fract();
377+
let value = if fract.abs() == 0.5 {
378+
if self.value.trunc() % 2.0 == 0.0 {
379+
self.value - fract
380+
} else {
381+
self.value + fract
382+
}
383+
} else {
384+
self.value.round()
385+
};
386+
vm.ctx.new_int(value.to_bigint().unwrap())
387+
} else {
388+
vm.ctx.not_implemented()
389+
}
390+
}
391+
360392
#[pymethod(name = "__int__")]
361393
fn int(&self, vm: &VirtualMachine) -> BigInt {
362394
self.trunc(vm)

0 commit comments

Comments
 (0)