Rust "attempt to multiply with overflow" when using .pow() function - rust

I am trying to solve
Magnet particules in boxes
Here is my code:
fn doubles(maxk: i32, maxn: i32) -> f64 {
let mut result: f64 = 0.0;
let mut k = 1;
let mut n = 1;
while k <= maxk {
while n <= maxn {
result += 1.0 / (k as i64 * (((n + 1) as i32).pow((2 * k) as u32)) as i64) as f64;
n += 1;
}
n = 1;
k += 1;
}
result
}
Tests like gives me an error "attempt to multiply with overflow"
dotest(10, 1000, 0.6921486500921933);
dotest(10, 10000, 0.6930471674194457);
Trouble with pow() function.
How could I modify my code?

Use f64, because it has bigger range than integer.
fn doubles(maxk: i32, maxn: i32) -> f64 {
let mut result: f64 = 0.0;
let mut k = 1;
let mut n = 1;
while k <= maxk {
while n <= maxn {
-- result += 1.0 / (k as i64 * (((n + 1) as i32).pow((2 * k) as u32)) as i64) as f64;
+ result += 1.0 / (k as f64 * (((n + 1) as f64).powf((2 * k) as f64))) as f64;
+ result += 1. / k as f64 / (1. + n as f64).powf(2. * k as f64);
n += 1;
}
n = 1;
k += 1;
}
result
}

Related

When is a Reborrow just a NOP?

I'm interested in this program:
fn main() {
let mut y = 13;
let mut x = &y;
x = &*x;
println!("{}", x);
}
In this case, the statement x = &*x; is translated into the following MIR:
_4 = _2; // scope 2 at src/main.rs:4:9: 4:12
_3 = _4; // scope 2 at src/main.rs:4:9: 4:12
_2 = move _3; // scope 2 at src/main.rs:4:5: 4:12
Basically, x = &*x; is translated as x = x; (i.e. a NOP). If I change the program like so:
fn main() {
let mut i = 13;
let mut j = 13;
let mut y = &i;
let mut x = &j;
x = &*y;
println!("{}", x);
}
Then, again, x = &*y; is essentially translated as x = y;.
Now my question (finally): Is a reborrow &*y when y is an immutable borrow always equivalent to just reading y?
Of course, I understand that if y was a mutable borrow this would be an entirely different thing.

How to resolve a possible multiplicative overflow to get correct modulus operation?

I have to perform (a * b) % m, but a, b, and m are 128-bit unsigned types, and overflow during multiplication is a large possibility. How can I still get a correct answer (probably using % more)?
I'm trying to implement the modular exponent function in Rust, where the largest built-in type is u128 (which is the max I can use). All three variables are really large, and so (a * b) > 2^128 is easy. I can use a.overflowing_mul(b) to detect whether an overflow occurred, but I do not know how to go back from the overflowed result (which can be thought of as (a * b) % 2^128) to get (a * b) % m.
My modular exponent code looks like this (currently no overflowing support is added):
fn mod_exp(b: u128, e: u128, m: u128) {
(0..e).fold(1, |x, _| (x * b) % m)
// ^^^^^^^^^^^
}
From a mathematical perspective:
(a * b) % m IS ACTUALLY (a * b) % B % m
| B = current base (2^128)
Examples:
// Mathematical
(9 * 13) % 11 = 7
// Real (base 20):
(9 * 13) % (B = 20) % 11 = 6
^^^^^^^^^^ ^ should be 7
(8 * 4) % 14 = 4
(8 * 4) % (B = 16) % 14 = 0
^^^^^^^^^^ ^ should be 4
This implementation, based on splitting the 128-bit product into four 64-bit products, is five times as fast as num_bigint::BigUint, ten times as fast as uint::U256, and 2.3 times as fast as gmp::mpz::Mpz:
fn mul_mod(a: u128, b: u128, m: u128) -> u128 {
if m <= 1 << 64 {
((a % m) * (b % m)) % m
} else {
let add = |x: u128, y: u128| x.checked_sub(m - y).unwrap_or_else(|| x + y);
let split = |x: u128| (x >> 64, x & !(!0 << 64));
let (a_hi, a_lo) = split(a);
let (b_hi, b_lo) = split(b);
let mut c = a_hi * b_hi % m;
let (d_hi, d_lo) = split(a_lo * b_hi);
c = add(c, d_hi);
let (e_hi, e_lo) = split(a_hi * b_lo);
c = add(c, e_hi);
for _ in 0..64 {
c = add(c, c);
}
c = add(c, d_lo);
c = add(c, e_lo);
let (f_hi, f_lo) = split(a_lo * b_lo);
c = add(c, f_hi);
for _ in 0..64 {
c = add(c, c);
}
add(c, f_lo)
}
}
(Warning: none of these implementations are suitable for use in cryptographic code, since they are not hardened against side channel attacks.)

How to implement the pipe / compose function? [duplicate]

I'm trying to write a function that composes two functions. The initial design is pretty simple: a function that takes two functions and returns a composed function which I can then compose with other functions, since Rust doesn't have rest parameters. I've run into a wall built with frustrating non-helpful compiler errors.
My compose function:
fn compose<'a, A, B, C, G, F>(f: F, g: G) -> Box<Fn(A) -> C + 'a>
where
F: 'a + Fn(A) -> B + Sized,
G: 'a + Fn(B) -> C + Sized,
{
Box::new(move |x| g(f(x)))
}
How I would like to use it:
fn main() {
let addAndMultiply = compose(|x| x * 2, |x| x + 2);
let divideAndSubtract = compose(|x| x / 2, |x| x - 2);
let finally = compose(*addAndMultiply, *divideAndSubtract);
println!("Result is {}", finally(10));
}
The compiler doesn't like that, no matter what I try, the trait bounds are never satisfied. The error is:
error[E0277]: the size for values of type `dyn std::ops::Fn(_) -> _` cannot be known at compilation time
--> src/main.rs:13:19
|
13 | let finally = compose(*addAndMultiply, *divideAndSubtract);
| ^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `dyn std::ops::Fn(_) -> _`
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
note: required by `compose`
--> src/main.rs:1:1
|
1 | / fn compose<'a, A, B, C, G, F>(f: F, g: G) -> Box<Fn(A) -> C + 'a>
2 | | where
3 | | F: 'a + Fn(A) -> B + Sized,
4 | | G: 'a + Fn(B) -> C + Sized,
5 | | {
6 | | Box::new(move |x| g(f(x)))
7 | | }
| |_^
As #ljedrz points out, to make it work you only need to reference the composed functions again:
let finally = compose(&*multiply_and_add, &*divide_and_subtract);
(Note that in Rust, convention dictates that variable names should be in snake_case)
However, we can make this better!
Since Rust 1.26, we can use abstract return types (previously featured gated as #![feature(conservative_impl_trait)]). This can help you simplify your example greatly, as it allows you to skip the lifetimes, references, Sized constraints and Boxes:
fn compose<A, B, C, G, F>(f: F, g: G) -> impl Fn(A) -> C
where
F: Fn(A) -> B,
G: Fn(B) -> C,
{
move |x| g(f(x))
}
fn main() {
let multiply_and_add = compose(|x| x * 2, |x| x + 2);
let divide_and_subtract = compose(|x| x / 2, |x| x - 2);
let finally = compose(multiply_and_add, divide_and_subtract);
println!("Result is {}", finally(10));
}
Finally, since you mention rest parameters, I suspect that what you actually want is to have a way to chain-compose as many functions as you want in a flexible manner. I wrote this macro for this purpose:
macro_rules! compose {
( $last:expr ) => { $last };
( $head:expr, $($tail:expr), +) => {
compose_two($head, compose!($($tail),+))
};
}
fn compose_two<A, B, C, G, F>(f: F, g: G) -> impl Fn(A) -> C
where
F: Fn(A) -> B,
G: Fn(B) -> C,
{
move |x| g(f(x))
}
fn main() {
let add = |x| x + 2;
let multiply = |x| x * 2;
let divide = |x| x / 2;
let intermediate = compose!(add, multiply, divide);
let subtract = |x| x - 2;
let finally = compose!(intermediate, subtract);
println!("Result is {}", finally(10));
}
Just add references in finally and it will work:
fn main() {
let addAndMultiply = compose(|x| x * 2, |x| x + 2);
let divideAndSubtract = compose(|x| x / 2, |x| x - 2);
let finally = compose(&*addAndMultiply, &*divideAndSubtract);
println!("Result is {}", finally(10));
}
Dereferencing addAndMultiply or divideAndSubtract uncovers a trait object which is not Sized; it needs to either be wrapped in a Box or referenced in order for it to be passed to a function with a Sized constraint.
macro_rules! comp {
($f: expr) => {
move |g: fn(_) -> _| move |x: _| $f(g(x))
};
}
fn main() {
let add1 = |x| x + 1;
let add2 = |x| x + 2;
let add3 = comp!(add1)(add2);
println!("{}", add3(3));
}
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=1c6915d94f7e1e35cf93fb21daceb9ef

If a function depends on another function, how can I assign a variable to the end product?

fn add(x: i32, y: i32) -> fn() {
let z = x + y;
mul(z, 2);
}
fn mul(x1: i32, y1: i32) -> fn() {
let z1 = x1 * y1;
sub(z1, 2);
}
fn sub(x2: i32, y2: i32) -> (i32) {
let z2 = x2 - y2;
z2
}
fn main() {
let R = add(2, 2);
println!("{}", R);
}
Assigning R to add(2, 2) doesn't work. I need to be able to assign R from add -> mul -> sub which returns z2.
So, the process is add(2, 2) -> mul(4, 2) -> sub(8, 2) thus getting R = 6. How do I go about doing this?
This is the error I get:
error[E0277]: the trait bound `fn(i32): std::fmt::Display` is not satisfied
--> testzz.rs:20:16
|
20 | println!("{}", R);
| ^ the trait `std::fmt::Display` is not implemented for
`fn(i32)`
|
= note: `fn(i32)` cannot be formatted with the default formatter; try using
`:?` instead if you are using a format string
= note: required by `std::fmt::Display::fmt`
It seems to me that you are confused about the syntax of return types of functions. The code compiles perfectly after a couple of minor edits:
fn add(x: i32, y: i32) -> i32 {
let z = x + y;
mul(z, 2)
}
fn mul(x1: i32, y1: i32) -> i32 {
let z1 = x1 * y1;
sub(z1, 2)
}
fn sub(x2: i32, y2: i32) -> i32 {
let z2 = x2 - y2;
z2
}
Note that the return type of all functions is now i32. Returning fn() means something completely different and doesn't make sense in this case. Also, I removed the semicolons at the end of add and mul so Rust knows that they are the return values.

Tree Fold in Rust

I am trying to implement tree fold in rust. My first attempt compiles and runs as expected.
pub enum Tree<T> {
Leaf,
Node(Box<Tree<T>>, T, Box<Tree<T>>)
}
impl<T, U: Copy> Tree<T> {
fn fold(self, f: |l: U, x: T, r: U| -> U, acc: U) -> U {
match self {
Leaf => acc,
Node(box l, x, box r) => {
let l = l.fold(|l,x,r| {f(l,x,r)}, acc);
let r = r.fold(|l,x,r| {f(l,x,r)}, acc);
f(l, x, r)
}
}
}
}
fn main() {
let tl = Node(box Leaf, 1i, box Leaf);
let tr = Node(box Leaf, 2i, box Leaf);
let t = Node(box tl, 3i, box tr);
println!("size(t) == {}", t.fold(|l,_,r|{l + 1i + r}, 0))
}
However, when I try to move the implementation of size into the impl block to make it a method:
pub enum Tree<T> {
Leaf,
Node(Box<Tree<T>>, T, Box<Tree<T>>)
}
impl<T, U: Copy> Tree<T> {
fn fold(self, f: |l: U, x: T, r: U| -> U, acc: U) -> U {
match self {
Leaf => acc,
Node(box l, x, box r) => {
let l = l.fold(|l,x,r| {f(l,x,r)}, acc);
let r = r.fold(|l,x,r| {f(l,x,r)}, acc);
f(l, x, r)
}
}
}
fn size(self) -> uint {
self.fold(|l, _, r| {l + 1u + r}, 0u)
}
}
fn main() {
let tl = Node(box Leaf, 1i, box Leaf);
let tr = Node(box Leaf, 2i, box Leaf);
let t = Node(box tl, 3i, box tr);
println!("size(t) == {}", t.size())
}
I get the following error in the rust playpen.
<anon>:28:31: 28:39 error: cannot determine a type for this expression: unconstrained type
<anon>:28 println!("size(t) == {}", t.size())
^~~~~~~~
note: in expansion of format_args!
<std macros>:2:23: 2:77 note: expansion site
<std macros>:1:1: 3:2 note: in expansion of println!
<anon>:28:5: 29:2 note: expansion site
error: aborting due to previous error
playpen: application terminated with error code 101
Program ended.
I was hoping someone could shed some light on what I'm doing wrong and how to fix it.
There is a crucial difference between your two things.
In the first, you had this:
t.fold(|l,x,r|{l + x + r}, 0)
In the second, you have this (shown with self changed to t):
t.fold(|l, x, r| {l + 1 + r}, 0)
See the difference? l + 1 + r is not l + x + r.
(Since then, all cases have become l + 1 + r, for size, rather than l + x + r, for sum.)
After you’ve done that, you’ll run into issues because uint is not int. You’ll need to sort out your Ts and Us. Basically, you want l, x, r and 0 all to be of the same type, the T of earlier. This requires further constraints on T:
It must be Copy, to satisfy U.
You must be able to add a T to a T and get a T. This is std::num::Add<T, T>.
You must be able to get a zero of type T. That is the std::num::Zero trait and the Zero::zero() method.
You must be able to get a one of type T. That is the std::num::One trait and the One::one() method.
While we’re at it, U should probably be a generic on the fold function specifically rather than the impl block, though either will do.
In the end, we end up with this functioning code:
use std::num::Zero;
pub enum Tree<T> {
Leaf,
Node(Box<Tree<T>>, T, Box<Tree<T>>)
}
impl<T> Tree<T> {
fn fold<U: Copy>(self, f: |l: U, x: T, r: U| -> U, acc: U) -> U {
match self {
Leaf => acc,
Node(box l, x, box r) => {
let l = l.fold(|l, x, r| f(l, x, r), acc);
let r = r.fold(|l, x, r| f(l, x, r), acc);
f(l, x, r)
}
}
}
}
impl<T: Copy + Add<T, T> + Zero + One> Tree<T> {
fn size(self) -> T {
self.fold(|l: T, _: T, r: T| l + One::one() + r, Zero::zero())
}
}
fn main() {
let tl = Node(box Leaf, 1i, box Leaf);
let tr = Node(box Leaf, 2i, box Leaf);
let t = Node(box tl, 3i, box tr);
println!("size(t) == {}", t.size())
}
(Note how the curly braces around the contents of a closure aren’t necessary, too.)

Resources