(
quotient: Node,
remainder: Node,
abs_divisor: Node,
dividend_is_negative: Node,
divisor_is_negative: Node,
)
| 237 | } |
| 238 | |
| 239 | fn adjust_negative( |
| 240 | quotient: Node, |
| 241 | remainder: Node, |
| 242 | abs_divisor: Node, |
| 243 | dividend_is_negative: Node, |
| 244 | divisor_is_negative: Node, |
| 245 | ) -> Result<(Node, Node)> { |
| 246 | // We compute the quotient and remainder using the same logic as numpy's // and %. |
| 247 | let g = quotient.get_graph(); |
| 248 | let result_is_negative = dividend_is_negative.add(divisor_is_negative.clone())?; |
| 249 | let remainder_bits = pop_last_dim(remainder.get_type()?.get_dimensions()).1; |
| 250 | let remainder_is_zero = unsqueeze( |
| 251 | g.custom_op( |
| 252 | CustomOperation::new(Equal {}), |
| 253 | vec![ |
| 254 | remainder.clone(), |
| 255 | g.zeros(array_type(vec![remainder_bits], BIT))?, |
| 256 | ], |
| 257 | )?, |
| 258 | -1, |
| 259 | )?; |
| 260 | // quotient = (-quotient if remainder is 0 else -quotient-1) |
| 261 | // if result_is_negative else quotient |
| 262 | let inverted_quotient = invert_bits(quotient.clone())?; // a.k.a (-quotient-1) |
| 263 | let negative_quotient = add_one(inverted_quotient.clone())?; |
| 264 | let quotient = g.custom_op( |
| 265 | CustomOperation::new(Mux {}), |
| 266 | vec![ |
| 267 | result_is_negative.clone(), |
| 268 | g.custom_op( |
| 269 | CustomOperation::new(Mux {}), |
| 270 | vec![ |
| 271 | remainder_is_zero.clone(), |
| 272 | negative_quotient, |
| 273 | inverted_quotient, |
| 274 | ], |
| 275 | )?, |
| 276 | quotient, |
| 277 | ], |
| 278 | )?; |
| 279 | // positive_remainder = 0 if remainder is 0 |
| 280 | // else abs(divisor) - remainder if result_is_negative else remainder |
| 281 | let positive_remainder = g.custom_op( |
| 282 | CustomOperation::new(Mux {}), |
| 283 | vec![ |
| 284 | remainder_is_zero, |
| 285 | remainder.clone(), |
| 286 | g.custom_op( |
| 287 | CustomOperation::new(Mux {}), |
| 288 | vec![ |
| 289 | result_is_negative, |
| 290 | g.custom_op( |
| 291 | CustomOperation::new(BinaryAdd { |
| 292 | overflow_bit: false, |
| 293 | }), |
| 294 | vec![abs_divisor, negative(remainder.clone())?], |
| 295 | )?, |
| 296 | remainder, |
no test coverage detected