I am pretty sure I got this right just want to make sure though... In the following code, we have omitted the definitions of constants M and N
here are the two functions in question arith and optarith:
#define M /* Mystery number 1 */
#define N /* Mystery number 2 */
unsigned int arith(unsigned int x, unsigned int y){
unsigned int result = 0;
result = x * M + y/N;
return result;
}
We compiled this code for particular values of M and N. The compiler optimized the multiplication and
division. The following is a translation of the generated machine code back into C:
unsigned int optarith(unsigned int x, unsigned int y){
unsigned int t = 3 * x;
x <<= 6;
x -= 2 * t;
y >>= 4;
y = y/3;
return x + y;
}
so here's my work
so to find value M for the operation M * x
x <<= 6; // same as x = x * 64
x-= 2 * t; //same as x = x - 2 * (3 * x)
so basically x = 64x - 6x which is just 58x therefore M = 58
and to find the value N for operation y/N
y >>= 4; same as y = y/16;
y = y/3; same as y = (y/16)/3;
that makes y/48 so N = 48
Did I do this correctly?
Related
I need to write a program that takes 2 digits(X and n) and then prints X with last n digits of X reversed.
For example
Input: 12345 3
Output: 12543
Input: 523 2
Output: 532
I already wrote a control mechanism for checking n is greater or equal than the number of digits of X
For example if inputs are 6343 and 7, program prints that inputs should be changed and takes input again.
My main problem is I couldn't find an algorithm for reversing last n digits. I can reverse any int with this code
int X, r = 0;
printf("Enter a number to reverse\n");
scanf("%d", &n);
while (X != 0)
{
r = r * 10;
r = r + n%10;
X = X/10;
}
printf("Reverse of the number = %d", r);
But I couldn't figure how two reverse just last digits. Can you give me any idea for that?
I couldn't figure how to reverse just last digits
Separate the number using pow(10,n) - see later code.
unsigned reverse_last_digits(unsigned x, unsigned n) {
unsigned pow10 = powu(10, n);
unsigned lower = x%pow10;
unsigned upper = x - lower;
return upper + reverseu(lower, n);
}
Create a loop that extracts the least-significant-digit (%10) and builds up another integer by applying that digit. (y = y*10 + new_digit)
unsigned reverseu(unsigned x, unsigned n) {
unsigned y = 0;
while (n-- > 0) {
y = y*10 + x%10;
x /= 10;
}
return y;
}
For integer type problems, consider integer helper functions and avoid floating point functions like pow() as they may provide only an approximate results. Easy enough to code an integer pow().
unsigned powu(unsigned x, unsigned expo) {
unsigned y = 1;
while (expo > 0) {
if (expo & 1) {
y = x * y;
}
expo >>= 1;
x *= x;
}
return y;
}
Test
int main() {
printf("%u\n", reverse_last_digits(12345, 3));
printf("%u\n", reverse_last_digits(523, 2));
printf("%u\n", reverse_last_digits(42001, 3));
printf("%u\n", reverse_last_digits(1, 2));
}
Output
12543
532
42100
10
Code uses unsigned rather than int to avoid undefined behavior (UB) on int overflow.
It is an easy one.
1. let say the number you want to reverse is curr_number;
2. Now, the places you want to reverse is x;
(remember to verify that x must be less than the number of digit of curr_number);
3. now, just take a temp integer and store curr_number / pow(10,x) ('/' = divide and pow(10,x) is 10 to the power x)
4. now, take a second number temp2, which will store curr_number-(temp * pow(10,x) )
5. reverse this temp2 (using your function)
6. now, answer = (temp * pow(10,x) ) + (temp2) //(note temp2 is reversed)
example with steps:
curr_number = 1234567
places you want to reverse is 3
temp = 1234567 / (10^3) i.e (1234567/1000) = 1234 (because it is int type)
temp2 = 1234567 - (1234*10^3) i.e 1234567 - 1234000 = 567
reverse(567) = 765
answer = (1234 * 10^3) + 765 = 1234765
Create two variables
lastn which stores the last n digits (345)
r which stores the reversed last n digits (543)
Subtract lastn from the original number (12345 - 345 = 12000)
Add r to the above number (12000 + 543 = 12543)
int c = 0; // count number of digits
int original = x;
int lastn = 0;
while (x != 0 && c < n) {
r = r * 10;
r = r + x % 10;
lastn += (x % 10) * pow(10, c);
x = x / 10;
c++;
}
printf("reversed: %d\n", original - lastn + r);
In case you don't have problems using char, you can do this
#include <stdio.h>
#include <string.h>
#define SIZE 10
int main() {
char n[SIZE]; // the Number;
int x; // number of last digits of n to reverse
int len; // number of digits of n
scanf("%s%d", n, &x);
len = strlen(n);
for(int i = 0; i < len; i++) {
i < len - x ? printf("%c", n[i]) : printf("%c", n[2*len -1 - i - x]);
}
return 0;
}
If you want you can make the program more readable by splitting the for in two
for(int i = 0; i < len - x; i++) {
printf("%c", n[i]);
}
for(int i = len-1; i >= len - x; i--) {
printf("%c", n[i]);
}
Note: the program won't work if n > x (i.e. if you want to swap more digits than you got)
I try two function for modular exponentiation for big base return wrong results,
One of the function is:
uint64_t modular_exponentiation(uint64_t x, uint64_t y, uint64_t p)
{
uint64_t res = 1; // Initialize result
x = x % p; // Update x if it is more than or
// equal to p
while (y > 0)
{
// If y is odd, multiply x with result
if (y & 1)
res = (res*x) % p;
// y must be even now
y = y>>1; // y = y/2
x = (x*x) % p;
}
return res;
}
For input x = 1103362698 ,y = 137911680 , p=1217409241131113809;
It return the value (x^y mod p):749298230523009574(Incorrect).
The correct value is:152166603192600961
The other function i try, gave same result, What is wrong with these functions?
The other one is :
long int exponentMod(long int A, long int B, long int C)
{
// Base cases
if (A == 0)
return 0;
if (B == 0)
return 1;
// If B is even
long int y;
if (B % 2 == 0) {
y = exponentMod(A, B / 2, C);
y = (y * y) % C;
}
// If B is odd
else {
y = A % C;
y = (y * exponentMod(A, B - 1, C) % C) % C;
}
return (long int)((y + C) % C);
}
With p = 1217409241131113809, this value as well as any intermediate values for res and x will be larger than 32 bits. This means that multiplying two of these numbers could result in a value larger than 64 bits which overflows the datatype you're using.
If you restrict the parameters to 32 bit datatypes and use 64 bit datatypes for intermediate values then the function will work. Otherwise you'll need to use a big number library to get correct output.
Using frama-c, I need to analyse Euclid's algorithm for computing greatest common divisor between two numbers with Bezozut coefficients. The algorithm takes two positive integers x and y as input and calculates two integers s and t such that
s · x + t · y = gcd(x, y)
When I run the code using
frama-c-gui -val euclidEVA.c
to analyse, I have some unsigned overflow & out of bounds write alarms generated.
///*#
//requires ...
//*/
int main(int x, int y, int* pp, int* qp)
{
int s = 1, t = 0, u = 0, v = 1;
///*#
//loop invariant ...
//*/
while(y > 0)
{
int r = x % y;
int q = x / y;
x = y;
y = r;
int w = u;
u = s - u * q;
s = w;
w = v;
v = t - v * q;
t = w;
}
*pp = s; *qp = t;
return x;
}
What precondition can I add to validate the memory access?
What loop invariant can I add to limit s and t?
What loop invariant can I add to bound u and v?
What precondition can I add for the bounds of x and y at the beginning?
Any comments on the alarms (signed overflow & out of bounds write) generated please?
screenshot of Alarms generated
Thanks.
Can anyone help me out with the pollard rho implementation? I have implemented this in C. It's working fine for numbers upto 10 digits but it's not able to handle greater numbers.
Please help me out to improve it to carry out factorization of numbers upto 18 digits . My code is this:
#include<stdio.h>
#include<math.h>
int gcd(int a, int b)
{
if(b==0) return a ;
else
return(gcd(b,a%b)) ;
}
long long int mod(long long int a , long long int b , long long int n )
{
long long int x=1 , y=a ;
while(b>0)
{
if(b%2==1) x = ((x%n)*(y%n))%n ;
y = ((y%n)*(y%n))%n ;
b/=2 ;
}
return x%n ;
}
int isprimes(long long int u)
{
if(u==3)
return 1 ;
int a = 2 , i ;
long long int k , t = 0 , r , p ;
k = u-1 ;
while(k%2==0)
{ k/=2 ; t++ ; }
while(a<=3) /*der are no strong pseudoprimes common in base 2 and base 3*/
{
r = mod(a,k,u) ;
for(i = 1 ; i<=t ; i++)
{
p = ((r%u)*(r%u))%u ;
if((p==1)&&(r!=1)&&(r!=(u-1)))
{ return 0 ; }
r = p ;
}
if(p!=1)
return 0 ;
else
a++ ;
}
if(a==4)
return 1 ;
}
long long int pol(long long int u)
{
long long int x = 2 , k , i , a , y , c , s;
int d = 1 ;
k = 2 ;
i = 1 ;
y = x ;
a = u ;
if(isprimes(u)==1)
{
return 1;
}
c=-1 ;
s = 2 ;
while(1)
{
i++;
x=((x%u)*(x%u)-1)% u ;
d = gcd(abs(y-x),u) ;
if(d!=1&&d!=u)
{ printf("%d ",d);
while(a%d==0) { a=a/d; }
x = 2 ;
k = 2 ;
i = 1 ;
y = x ;
if(a==1)
{ return 0 ; }
if(isprimes(a)!=0)
{ return a ; }
u=a ;
}
if(i==k)
{y = x ; k*=2 ; c = x ;} /*floyd cycle detection*/
if(c==x)
{ x = ++s ; }
}
return ;
}
int main()
{
long long int t ;
long long int i , n , j , k , a , b , u ;
while(scanf("%lld",&n)&&n!=0)
{ u = n ; k = 0 ;
while(u%2==0)
{ u/=2 ; k = 1 ; }
if(k==1) printf("2 ") ;
if(u!=1)
t = pol(u) ;
if(u!=1)
{
if(t==1)
{ printf("%lld",u) ; }
else
if(t!=0)
{ printf("%lld",t) ; }
}
printf("\n");
}
return 0;
}
sorry for the long code ..... I am a new coder.
When you're multiplying two numbers modulo m, the intermediate product can become nearly m^2. So if you use a 64-bit unsigned integer type, the maximal modulus it can handle is 2^32, if the modulus is larger, overflow may happen. It will be rare when the modulus is only slightly larger, but that makes it only less obvious, you cannot rely on being lucky if the modulus allows the possibility of overflow.
You can gain a larger range by a factor of two if you choose a representative of the residue class modulo m of absolute value at most m/2 or something equivalent:
uint64_t mod_mul(uint64_t x, uint64_t y, uint64_t m)
{
int neg = 0;
// if x is too large, choose m-x and note that we need one negation for that at the end
if (x > m/2) {
x = m - x;
neg = !neg;
}
// if y is too large, choose m-y and note that we need one negation for that at the end
if (y > m/2) {
y = m - y;
neg = !neg;
}
uint64_t prod = (x * y) % m;
// if we had negated _one_ factor, and the product isn't 0 (mod m), negate
if (neg && prod) {
prod = m - prod;
}
return prod;
}
So that would allow moduli of up to 2^33 with a 64-bit unsigned type. Not a big step.
The recommended solution to the problem is the use of a big-integer library, for example GMP is available as a distribution package on most if not all Linux distros, and also (relatively) easily installable on Windows.
If that is not an option (really, are you sure?), you can get it to work for larger moduli (up to 2^63 for an unsigned 64-bit integer type) using Russian peasant multiplication:
x * y = 2 * (x * (y/2)) + (x * (y % 2))
so for the calculation, you only need that 2*(m-1) doesn't overflow.
uint64_t mod_mult(uint64_t x, uint64_t y, uint64_t m)
{
if (y == 0) return 0;
if (y == 1) return x % m;
uint64_t temp = mod_mult(x,y/2,m);
temp = (2*temp) % m;
if (y % 2 == 1) {
temp = (temp + x) % m;
}
return temp;
}
Note however that this algorithm needs O(log y) steps, so it's rather slow in practice. For smaller m you can speed it up, if 2^k*(m-1) doesn't overflow, you can proceed in steps of k bits instead of single bits (x*y = ((x * (y >> k)) << k) + (x * (y & ((1 << k)-1)))), which is a good improvement if your moduli are never larger than 48 or 56 bits, say.
Using that variant of modular multiplication, your algorithm will work for larger numbers (but it will be significantly slower). You can also try test for the size of the modulus and/or the factors to determine which method to use, if m < 2^32 or x < (2^64-1)/y, the simple (x * y) % m will do.
You can try this C implementation of Pollard Rho :
unsigned long long pollard_rho(const unsigned long long N) {
// Require : a composite number N, not a square.
// Ensure : res is a non-trivial factor of N.
// Option : define a timeout, define a rand function.
static const int timeout = 18;
static unsigned long long rand_val = 2994439072U;
rand_val = (rand_val * 1025416097U + 286824428U) % 4294967291LLU;
unsigned long long res = 1, a, b, c, i = 0, j = 1, x = 1, y = 1 + rand_val % (N - 1);
for (; res == 1; ++i) {
if (i == j) {
if (j >> timeout)
break;
j <<= 1;
x = y;
}
a = y, b = y;
for (y = 0; a; a & 1 ? b >= N - y ? y -= N : 0, y += b : 0, a >>= 1, (c = b) >= N - b ? c -= N : 0, b += c);
y = (1 + y) % N;
for (a = N, b = y > x ? y - x : x - y; (a %= b) && (b %= a););
res = a | b;
}
return res;
}
Otherwise there is a pure C quadratic sieve which factors numbers from 0 to 300-bit.
The output is
x=1000300 y=1000000, z=1000300
I can understand how I got x and z but c's y's output makes no sense.
#include <stdio.h>
int main()
{ int i=0;
float a = 100;
a = a*a*a*a*a;
float c = 3;
float x = 1000000*c + a;
float y = a;
float z = 0;
for (i=0; i<1000000; i++)
{ y += c;
z += c;
}
z += a;
x /= 10000;
y /= 10000;
z /= 10000;
printf("x=%.0f y=%.0f, z=%.0f\n", x, y, z);
}
The value in y starts out at 1E10 (from the assignment to a). You add 3 to this a million times.
The trouble is that a float has at most 7 significant decimal digits, so you effectively do not change y each time, hence the result divided by 10,000 is 10,000,000 1,000,000 as displayed.
If you coded it with double, you would see more nearly the result you expect.