Skip to content

Test lshift of zero#2154

Merged
youknowone merged 5 commits into
RustPython:masterfrom
yihyunjoon:test_lshift_of_zero
Sep 5, 2020
Merged

Test lshift of zero#2154
youknowone merged 5 commits into
RustPython:masterfrom
yihyunjoon:test_lshift_of_zero

Conversation

@yihyunjoon
Copy link
Copy Markdown
Contributor

It seems kinda rough code though, it passes the tests.
I'd like to get advice to improve this code.

Comment thread vm/src/obj/objint.rs Outdated
Comment on lines 195 to 216
if int2.is_negative() {
return Err(vm.new_value_error("negative shift count".to_owned()));
} else if int1.is_zero() {
return Ok(vm.ctx.new_int(0));
} else if *int2 > BigInt::from(usize::max_value()) {
return Err(vm.new_overflow_error("the number is too large to convert to int".to_owned()))
} else {
return Ok(vm.ctx.new_int(int1 << int2.to_usize().expect("Failed converting {} to rust usize")));
}
}

fn inner_rshift(int1: &BigInt, int2: &BigInt, vm: &VirtualMachine) -> PyResult {
let n_bits = get_shift_amount(int2, vm)?;
Ok(vm.ctx.new_int(int1 >> n_bits))
if int2.is_negative() {
return Err(vm.new_value_error("negative shift count".to_owned()));
} else if int1.is_zero() {
return Ok(vm.ctx.new_int(0));
} else if *int2 > BigInt::from(usize::max_value()) {
return Err(vm.new_overflow_error("the number is too large to convert to int".to_owned()))
} else {
return Ok(vm.ctx.new_int(int1 >> int2.to_usize().expect("Failed converting {} to rust usize")));
}
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems only shift operation is different and the other parts are the same. If we introduce a closure, they can be combined into a single function

Suggested change
if int2.is_negative() {
return Err(vm.new_value_error("negative shift count".to_owned()));
} else if int1.is_zero() {
return Ok(vm.ctx.new_int(0));
} else if *int2 > BigInt::from(usize::max_value()) {
return Err(vm.new_overflow_error("the number is too large to convert to int".to_owned()))
} else {
return Ok(vm.ctx.new_int(int1 << int2.to_usize().expect("Failed converting {} to rust usize")));
}
}
fn inner_rshift(int1: &BigInt, int2: &BigInt, vm: &VirtualMachine) -> PyResult {
let n_bits = get_shift_amount(int2, vm)?;
Ok(vm.ctx.new_int(int1 >> n_bits))
if int2.is_negative() {
return Err(vm.new_value_error("negative shift count".to_owned()));
} else if int1.is_zero() {
return Ok(vm.ctx.new_int(0));
} else if *int2 > BigInt::from(usize::max_value()) {
return Err(vm.new_overflow_error("the number is too large to convert to int".to_owned()))
} else {
return Ok(vm.ctx.new_int(int1 >> int2.to_usize().expect("Failed converting {} to rust usize")));
}
}
fn inner_shift<F>(int1: &BigInt, int2: &BigInt, shift_op: F, vm: &VirtualMachine) -> PyResult
where
F: Fn(&BitInt, usize) -> BigInt
{
if int2.is_negative() {
Err(vm.new_value_error("negative shift count".to_owned()));
} else if int1.is_zero() {
Ok(vm.ctx.new_int(0));
} else {
let int2 = int2.to_usize().ok_or_else(|| {
vm.new_overflow_error("the number is too large to convert to int".to_owned()))
})?;
Ok(vm.ctx.new_int(shift_op(int1, int2).expect("Failed converting {} to rust usize")));
}
}

Comment thread vm/src/obj/objint.rs Outdated
Comment on lines +194 to +200
fn inner_lshift(int1: &BigInt, int2: &BigInt, vm: &VirtualMachine) -> PyResult {
let n_bits = get_shift_amount(int2, vm)?;
Ok(vm.ctx.new_int(int1 << n_bits))
inner_shift(int1, int2, |a, b| a << b, vm)
}

fn inner_rshift(int1: &BigInt, int2: &BigInt, vm: &VirtualMachine) -> PyResult {
let n_bits = get_shift_amount(int2, vm)?;
Ok(vm.ctx.new_int(int1 >> n_bits))
inner_shift(int1, int2, |a, b| a >> b, vm)
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we don't need one line inner_lshift and inner_rshift anymore. caling inner_shift in each shift funciton will be enough.

Comment thread vm/src/obj/objint.rs Outdated
#[pymethod(name = "__rlshift__")]
fn rlshift(&self, other: PyObjectRef, vm: &VirtualMachine) -> PyResult {
self.general_op(other, |a, b| inner_lshift(b, a, vm), vm)
self.general_op(other, |a, b| inner_shift(a, b, |a, b| a << b, vm), vm)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the parameters are swapped

@youknowone youknowone merged commit f682a94 into RustPython:master Sep 5, 2020
@yihyunjoon yihyunjoon deleted the test_lshift_of_zero branch September 5, 2020 09:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants