I'm trying to learn Rust by translating C++ code from the "Elements of Programming" book by Stepanov and McJones. Here's a simple code snippet:
extern crate num_bigint;
use num_bigint::BigInt;
pub fn fibonacci_matrix_multiply(x: (&BigInt, &BigInt), y: (&BigInt, &BigInt)) -> (BigInt, BigInt) {
(x.0 * (y.1 + y.0) + x.1 * y.0, x.0 * y.0 + x.1 * y.1)
}
pub fn power_accumulate_positive(
mut r: (&BigInt, &BigInt),
mut a: (&BigInt, &BigInt),
mut n: i32,
) -> (BigInt, BigInt) {
loop {
if n & 1 == 1 {
r = fibonacci_matrix_multiply(r, a);
if n == 1 {
return r;
}
}
a = fibonacci_matrix_multiply(a, a);
n = n / 2;
}
}
fn main() {}
Here's the error messages:
error[E0308]: mismatched types
--> src/main.rs:16:17
|
16 | r = fibonacci_matrix_multiply(r, a);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected reference, found struct `num_bigint::BigInt`
|
= note: expected type `(&num_bigint::BigInt, &num_bigint::BigInt)`
found type `(num_bigint::BigInt, num_bigint::BigInt)`
error[E0308]: mismatched types
--> src/main.rs:18:24
|
18 | return r;
| ^ expected struct `num_bigint::BigInt`, found reference
|
= note: expected type `(num_bigint::BigInt, num_bigint::BigInt)`
found type `(&num_bigint::BigInt, &num_bigint::BigInt)`
error[E0308]: mismatched types
--> src/main.rs:21:13
|
21 | a = fibonacci_matrix_multiply(a, a);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected reference, found struct `num_bigint::BigInt`
|
= note: expected type `(&num_bigint::BigInt, &num_bigint::BigInt)`
found type `(num_bigint::BigInt, num_bigint::BigInt)`
I understand that I'm returning a tuple of structs and trying to assign it to a tuple of references, but I don't know how to solve the problem.
Is there a reason you can't take the BigInt
s by value instead of by reference? This would remove all the borrow checker errors. Unless it's a clear and measured bottleneck to clone the BigInt
s, passing by reference won't be much faster and it's less ergonomic.
Here's a working solution that doesn't use references (and instead clones the values)
extern crate num_bigint;
use num_bigint::BigInt;
pub fn fibonacci_matrix_multiply(x: (BigInt, BigInt), y: (BigInt, BigInt)) -> (BigInt, BigInt) {
(&x.0 * (&y.1 + &y.0) + &x.1 * &y.0, x.0 * y.0 + x.1 * y.1)
}
pub fn power_accumulate_positive(
mut r: (BigInt, BigInt),
mut a: (BigInt, BigInt),
mut n: i32,
) -> (BigInt, BigInt) {
loop {
if n & 1 == 1 {
r = fibonacci_matrix_multiply(r, a.clone());
if n == 1 {
return r;
}
}
a = fibonacci_matrix_multiply(a.clone(), a);
n = n / 2;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With