Remainder % works but doesn't work

Hello, I am very new to rust, and I do not use any specificity of the language, yet I am facing a very odd problem.
I need to take the remainder by q/2 of some value stored in a two dimensional vector sample1[i][j]
and store it in a second two dimensional vector sample2 [i][j].

wether I do

sample2[l][d]= sample1[i][d]%(q>>1);

or

sample2[l][d]= redmod_int_sign(sample1[i][d],q);

where redmod_int_sign(i64,i64) is a function returning an i64 that I make myself substracting q as long the value is not in the correct range or a function using %, it returns and store values which are often much bigger than q/2 or smaller than -q/2.

I really don't get why. I printed the values, and they are in the correct range INSIDE the function, but not outside the function.

Do you have any idea of what I am doing wrong?
Thank you already.

Would you mind sharing redmod_int_sign?

Is sample2[l][d] intentional or it should be sample2[i][d]?

2 Likes

yes it is intentional, actually I don't exactly store sample1[i][d] but a linear combination of different sample1[i][j] coming from different loop on different i, since I only select some of them, I need another index l .

sure there are two versions of it, pretty basic:

fn redmod_int_sign(int: i64, q:i64)->i64{
    let q_2: i64= q>>1;
    let mut temp: i64 =int%q_2;
    if temp == q_2{    
        return temp-q;        
    }else{
        return temp;
    }
}

and

fn redmod_int_sign(int: i64, q:i64)->i64{
    let q_2: i64= (q>>1);
    let mut temp: i64 = int;
    
    while temp >= q_2{    
        temp = temp-q;        
    }
    while temp < -q_2{    
        temp = temp+q;        
    }
    return temp;
}

I even tried to recreate my own remainder with int - q_2*(int/q_2) .
But as I said, even if I directly apply sample1[i][j]%q_2, it sometimes is too big.

What you should do, instead, is not to recreate % which is working correctly in Rust, but to create minimal self-contained example.

9 times out of 10 you would find error during attempt to create such an example and 1 times of 10 others would be able to experiment with your code.

3 Likes

I don't see anything obviously wrong. Since you said the values are correct inside your function but not outside I thought maybe there was a problem with your return statements in the function. Note that temp == q_2 will never be true, since temp is the remainder of a signed modulo operation with q_2 as modulus. Hence temp will always be smaller than q_2.

Could it be that there's a bug in your linear combination?

Oh yes you are right, I should use %(q_2+1) since I want representatives in [q/2;q/2[ pretty rookie mistake. The linear combination is just a sum. I have three nested loops, (I know it's wrong), of index i,m,p, and I do things like that sample2[l][d]= redmod_int_sign(sample1[i][d]+sample1[m][d]-sample1[p][d],q); or alternatively I tried sample2[l][d]= (sample1[i][d]+sample1[m][d]-sample1[p][d])%(q>>1); and it still print big values when I print them. I find it super weird.

I am not sure of the expression "minimal self-contained example". to verify the values I immediately print them.

sample2[l][d]= redmod_int_sign(sample1[i][d]+sample1[m][d]-sample1[p][d],q);
               print!("sample2[{}][{}]:  {}\r",l,d,redmod_int_sign(sample1[i][d]+sample1[m][d]-sample1[p][d],q));
               io::stdout().flush().unwrap();

Do you mean check if redmod_int_sign(10909870,q); gives the correct answer? I did that but out of the loops.

Basically, it means to write the smallest complete program that you can which still shows the error. It's a lot easier to investigate problems if there's a running piece of code that we can mess with directly, instead of suggesting things for you to try, and then waiting for you to report back.

Generally, you do this by starting with a copy of your program and systematically remove the unrelated parts. Eventually, you should end up with something small enough to paste into the playground, or at least upload to someplace like GitHub or GitLab.

3 Likes

I think it's something with the print and returning to the same line because when I use println! instead of print! it doesn't happen. Thank you all then, and thanks for noticing the q/2 stuff, it creates me bigger statistics. unbelievable.