Calculate series: x = (x*7 + y) >> 3 - c++

I'm reading the UDT source. That is a excellent project, but it is so hard to understand some expressions:
m_iRTT = (m_iRTT * 7 + rtt) >> 3;
m_iBandwidth = (m_iBandwidth * 7 + *((int32_t *)ctrlpkt.m_pcData + 5)) >> 3;
In short expression form:
x = (x*7 + y) >> 3
Can someone explain what this expression does ?

To spell out x = (x*7 + y) >> 3:
x is multiplied by 7, then the result added to y, then that result shiftted 3 bits to the right and assigned to x.

Related

How to simplify this "clear multiple bits at once" function?

I finally figured out through trial and error how to clear multiple bits on an integer:
const getNumberOfBitsInUint8 = function(i8) {
let i = 0
while (i8) {
i++
i8 >>= 1
}
return i
}
const write = function(n, i, x) {
let o = 0xff // 0b11111111
let c = getNumberOfBitsInUint8(x)
let j = 8 - i // right side start
let k = j - c // right side remaining
let h = c + i
let a = x << k // set bits
let b = a ^ o // set bits flip
let d = o >> h // mask right
let q = d ^ b //
let m = o >> j // mask left
let s = m << j
let t = s ^ q // clear bits!
let w = n | a // set the set bits
let z = w & ~t // perform some magic https://stackoverflow.com/q/8965521/169992
return z
}
The write function takes an integer n, the index i to write bits into, and the bits value x.
Is there any way to simplify this function down and remove some steps? (Without just combining multiple operations on a single line)?
One possibility is to first clear the relevant part and then copy the bits into it:
return (n & ~((0xff << (8 - c)) >> i)) | (x << (8 - c - i))
assuming the left shift is restricted to 8 bits so the top bits disappear. Another is to use xor to find the bits to be changed :
return n ^ ((((n >> (8 - c - i)) ^ x) << (8 - c)) >> i)

Can someone explain how the shorthand assignment operator actually works?

#include <iostream>
using namespace std;
int main()
{
int x=2,a=3,b=2;
x*=a/b;
cout<<x<<" ";
x=2;
x=x*a/b;
cout<<x;
return 0;
}
I am getting output as:
2
3
while in my opinion x*=a/b; and x=x*a/b; mean the same thing.
Can anybody explain this behaviour?
They are not quite the same.
x *= a / b is grouped as x *= (a / b) and a / b takes place in integer arithmetic (it's 1).
x = x * a / b is grouped as x = ((x * a) / b). the integer division has a less drastic and different effect.
With integer division: 3/2 is 1.
x*=a/b; is evaluated as x *= (a / b) so x *= 3 / 2 -> x *= 1.
x=x*a/b; is evaluated as x = (x * a) / b; so (2 * 3) / 3 -> 6 / 2 -> 3
I am getting output as: 2 3 while in my opinion x*=a/b; and x=x*a/b;
mean the same thing. Can anybody explain this behaviour?
x *= a / b;
// ^^^^^
This is integer division, the rest is discarded and therefore 3 / 2 is 1.
Therefore the expression x *= a / b is the same as x *= 1 which stays 2.
x = x * a / b;
On the other hand is evaluated as
x = (x * a) / b;
The result is then
x = (2 * 3) / 2;
becomes
x = 6 / 2;
which is 3
Per [expr.ass]/6 E1 *= E2 is exactly he same as E1 = E1 * E2. That does not mean that x*=a/b; is the same as x=x*a/b;. Since E2 is a/b, x*=a/b; is actually equivalent to x=x*(a/b); which does produce the same results.

C++ define expression evaluation [duplicate]

This question already has answers here:
The need for parentheses in macros in C [duplicate]
(8 answers)
Closed 7 years ago.
Suppose we have this expression:
#define cube(x) x * x * x
And then we call it:
int n = 3, v;
v = cube(n + 1); // v = 10
v = cube((n + 1)); // v = 64
v = cube(n); // v = 27
So the question is: why first operation do not make v = 64?
Macros are not evaluated (in the sense of the common interpretation of evaluation), they are expanded at compile time.
Before the file is compiled, there is another program called the C Preprocessor that replaces the macro invocation literally/textually and prepares the file for actual compilation, so for your macro
#define cube(x) x * x * x when you do this
This
v = cube(n + 1);
is replaced with this (expaned is the correct term)
v = n + 1 * n + 1 * n + 1;
// Simplifies to
v = n + n + n + 1;
// and again
v = 3 * n + 1;
which for n = 3 gives you 10 exactly the observed result.
Note, that when you add parentheses
v = cube((n + 1));
then, the expansion is
v = (n + 1) * (n + 1) * (n + 1);
which is what you would expect cube() to do, so prevent this you should redefine your macro like this
#define cube(x) ((x) * (x) * (x))
If you are using gcc try
gcc -E source.c
and check the result to verify how the macro was expanded.

Reach A Target number only using other two numbers

I am having two numbers L and R, L means left and R means Right.
I have to get to a certain number(F) using L and R.
Every time i have to start with zero as initial.
Example :
L : 1
R : 2
F : 3
SO minimum number of steps needed to get to F is 3.
Ans : First R, Second R, Third L.
IN this way i need to find the minimum number of ways to do it.
My approach:
Quo = F/R;
Remain : F%R;
x*R-Y*L = Remain
==> (x*R - Remain)/L = Y
this equation is break when (x*R - Remain)%L = 0, so we find x and y from the equation above.
So final Steps would be Quo + x(No. of right steps) + y( no. of left steps).
For Above Example :
Quo = 3/2 = 1;
Remain = 3%2 =1;
Y = (x*2 -1)/1
(x*2 -1)%1 is zero for x=1;
Now increase x from zero,
So x is 1, y is 1
Final Ans = Quo (1) + x (1) + y(1) = 3.
My code :
#include <iostream>
using namespace std;
int main()
{
int F,R,L;
cin >> F;
cin >> R;
cin >> L;
int remain = F%R;
int quo = F/R;
int Right = 0;
int left = 0;
int mode = 1;
while( mode !=0)
{
Right++;
mode = (R*Right - remain)%L;
left = (R*Right - remain)/L;
}
int final = quo + Right + left;
cout << final;
}
But i Don't think it is the good approach as i am putting x in loop which can be pretty costly
Can you please suggest me a good approach to do this question ?
In the given below equation
x*R - Remain = 0modL
where R, L and Remain are fixed.
It can be written as
((x*R)mod L - Remain mod L) mod L = 0
If Remain mod L = 0, then x*R should be multiple of L which makes x to 0modL.
Means x can be 0, nR where n is Integer.
So, simply, you can try x between 0 and L-1 to find x.
So, your loop can run from 0 to L-1 which will keep your loop finite.
Please note that this mod is different from %. -1 mod L = L-1 whereas -1%L = -1
There is another approach.
x*R mod L - Remain mod L = 0 mod L
leads to
x*R mod L = Remain mod L
(x* (R mod L)) mod L = (Remain mod L)
You can compute inverse of R (say Rinv) in field of L (if it does exists) and compute x = (Remain*Rinv)modL.
If inverse does not exists, it means equation cannot be satisfied.
Note: I am not mathematical expert. So, please give your opinion if anything is wrong.
See: https://www.cs.cmu.edu/~adamchik/21-127/lectures/congruences_print.pdf

Need clarification about this loop performing multiplication

int x, y; // x is a non-negative integer
p = 0;
while (x > 0)
{
if ( x % 2 == 1 )
p = p + y;
y = y*2;
x = x/2;
}
// p == a*b here
I understand that this loop finds the product of 'a' and 'b' using the algebra:
a * b = (1/2)a * 2b
but I don't understand the code:
if ( x % 2 == 1 )
p = p + y;
I was hoping someone could explain why 'p' is assigned 'p + y' on odd values of x.
while (x > 0) {
if (x % 2 == 1)
p = p + y;
y = y*2;
x = x/2;
}
imagine x = 4, y = 5
iterations:
x is even, y = 10, x = 2 (i.e. x can be divided, y should be doubled)
x is even, y = 20, x = 1
x is odd, p = 20, y = 40, x = 0 (i.e. x can not be divided anymore, y should be added to p)
x > 0 is false, loop ends
p = 4 * y
now imagine x is odd at the beginning, let's say x = 5, y = 2:
x is odd, p = 2, y = 4, x = 2
(5/2 = 2.5, new value of x will be rounded down, y should be added BEFORE it is doubled)
x is even, y = 8, x = 1
x is odd, p = 10, y = 16, x = 0
p = y + 4*y
that first y is the reason, adding it to the result before it is doubled (1 * y) is in this case equivalent to 0.5 * (2 * y)
Because these are integers, a / 2 will be an integer. If a is odd, that integer has been rounded down, and you’re missing one-half b in the next iteration of the loop, i.e. one whole b in the current iteration of the loop (since b [y] is doubled each time).
If x is odd, x = x/2 will set x to 0.5 less than x/2 (because integer division rounds it down). p needs to be adjusted to allow for that.
Think of multiplication as repeated addition, x*y is adding y together x times. It is also the same as adding 2*y together x/2 times. Conceptually it is somewhat unclear what it means if x is odd. For example, if x=5 and y=3, what does it mean to add 2.5 times? The code notices when x is odd, adds y in, then does the y=y*2 and x=x/2. When x is odd, this throws away the .5 part. So in this example, you add y one time, then x becomes 2 (not 2.5) because integer division throws away the fraction.
At the end of each loop, you will see that the product of the original x and y is equal to p + x*y for the current values of p, x, and y. The loop iterates until x is 0, and the result is entirely in p.
It also helps to see what is going on if you make a table and update it each time through the loop. These are the values at the start of each iteration:
x | y | p
----------
5 | 3 | 0
2 | 6 | 3
1 | 12 | 3
0 | 24 | 15
This works by observing that (for example) y * 10 = y * 8 + y * 2.
It's pretty much like doing multiplication on paper in school. For example, to multiply 14 x 21, we multiply one digit at a time (and shift left a place where needed) so we add 1x14 + 2 x 14 (shifted left one digit).
14
x 21
----
14
280
Here, we're doing pretty much the same thing, but working in binary instead of decimal. The right shifting has nothing to do with the numbers being odd, and everything to do with simply finding which bits in the number are set.
As we shift one operand right to find whether a bit is set, we also shift the other operand left, just like we add zeros to shift numbers left when doing arithmetic on paper in decimal.
So, viewing things in binary, we end up with something like:
101101
x 11010
--------
1011010
+ 101101000
+ 1011010000
If we wanted to, instead of shifting the operand right, we could just shift the mask left so instead of repeatedly anding with 1, we'd and with 1, then with 2, then with 4, and so on (in fact, it would probably make a lot more sense that way). For better or worse, however, in assembly language (where this sort of thing is normally done) it's usually a little easier to shift the operand and use a constant for the mask than load the mask in a register and shift it when needed.
You should rewrite x as 2*b+1 (assuming x is odd). Then
x*y = (2*b+1)*y = (2*b)*y + y = b*(2*y) + y = (x/2)*(2*y) + y
where (x/2) is meant to be the integer division. With the operation rewritten this way, you see the x/2, the 2y and the +y appear.