Perform x % y on floats using Python semantics.
(self, lhs: Value, rhs: Value, line: int)
| 2483 | return self.add(FloatOp(lhs, rhs, op_id, line)) |
| 2484 | |
| 2485 | def float_mod(self, lhs: Value, rhs: Value, line: int) -> Value: |
| 2486 | """Perform x % y on floats using Python semantics.""" |
| 2487 | mod = self.add(FloatOp(lhs, rhs, FloatOp.MOD, line)) |
| 2488 | res = Register(float_rprimitive) |
| 2489 | self.add(Assign(res, mod)) |
| 2490 | tricky, adjust, copysign, done = BasicBlock(), BasicBlock(), BasicBlock(), BasicBlock() |
| 2491 | is_zero = self.add(FloatComparisonOp(res, Float(0.0), FloatComparisonOp.EQ, line)) |
| 2492 | self.add(Branch(is_zero, copysign, tricky, Branch.BOOL)) |
| 2493 | self.activate_block(tricky) |
| 2494 | same_signs = self.is_same_float_signs(lhs, rhs, line) |
| 2495 | self.add(Branch(same_signs, done, adjust, Branch.BOOL)) |
| 2496 | self.activate_block(adjust) |
| 2497 | adj = self.float_op(res, rhs, "+", line) |
| 2498 | self.add(Assign(res, adj)) |
| 2499 | self.add(Goto(done)) |
| 2500 | self.activate_block(copysign) |
| 2501 | # If the remainder is zero, CPython ensures the result has the |
| 2502 | # same sign as the denominator. |
| 2503 | adj = self.primitive_op(copysign_op, [Float(0.0), rhs], line) |
| 2504 | self.add(Assign(res, adj)) |
| 2505 | self.add(Goto(done)) |
| 2506 | self.activate_block(done) |
| 2507 | return res |
| 2508 | |
| 2509 | def compare_floats(self, lhs: Value, rhs: Value, op: int, line: int) -> Value: |
| 2510 | return self.add(FloatComparisonOp(lhs, rhs, op, line)) |
no test coverage detected