How do I do pow without the math.h library? - c

i have this code:
if (is_prime == 1) {
for (marsennloop = 1, marsenn = 0; marsennloop <= calc; marsennloop++) {
marsennloop = marsennloop * 2;
marsenncalc2 = marsennloop - 1;
if (marsenncalc2 == calc && calc != 1) {
marsenn = 1;
}
}
}
on the line "marsennloop = marsennloop * 2;" i am trying to do a pow function without using pow but this give me an incorrect output when i change this line to pow and use the same variables i get the correct output which leads me to believe the problem lies within that line of code.

power of two (2^n) is simply shift 1 << n
So naive function checking if the number is mersenne prime:
int ism(unsigned val)
{
int result = 0;
for(unsigned long long i = 2; i <= 1ULL << (CHAR_BIT * sizeof(val)); i <<= 1)
{
if(i - 1 == val)
{
result = 1;
break;
}
}
return result;
}
int main(void)
{
unsigned count = 0;
for(unsigned i = 1; i <= (1U << 20); i++)
{
if(ism(i))
{
printf("%u ", i);
if(!(++count % 16)) printf("\n");
}
}
}

If you want to test if the number is 2^n - 1, please try the following function:
int is_m(unsigned int x)
{
return (x & (x + 1)) == 0;
}
It returns 1 if x is 2^n - 1, else returns 0.

Related

C - Print all numbers with same count of set and unset bits

I have to print numbers with max N bits where count of bits set to 1 = count of bits set to 0. I ignoring leading zeros. I thinking that this applies only when count of bits is even.
My code:
int power(k) {
return 1 << k;
}
void print_numbers(int n){
n -= (n % 2); // FOR EVEN COUNT OF BITS
int exp = 1; // EXPONENTS WILL BE ODD (2^1, 2^3, 2^5, ...)
while (exp < n) {
int start = power(exp);
int end = power(exp + 1);
int ones = (exp + 1) / 2; // ALLOWED COUNT OF 1
for (int i = start; i < end; i++) {
int bits_count = 0;
for (int j = 0; j <= exp; j++){ // CHECK COUNT OF 1
bits_count += ((i >> j) & 1);
}
if (bits_count == ones){
printf("%d\n", i);
}
}
exp += 2;
}
For N = 12 this function print 637 numbers. Is this solution correct or am i wrong? Any idea for more efficient or better solution?
I came up with this, which is a totally different approach (and perfectible) but works:
#include <stdio.h>
void checker(int number)
{
int c;
int zeros = 0;
int ones = 0;
for (c = 31; c >= 0; c--)
{
if (number >> c & 1)
{
ones++;
}
else if(ones > 0)
{
zeros++;
}
}
if(zeros == ones)
{
printf("%i\n", number);
}
}
int main()
{
int c;
for (c = 4095; c >= 0; c--)
{
checker(c);
}
return 0;
}
Which get me 638 values (including 0)

How can I specifically take out numbers in an integer, in C?

Lets say I have an integer called SIN and the scanf input receives 193456787.
so SIN = 193456787;
What I want to do is add up all the other numbers after the first digit.
So 9 + 4 + 6 + 8 = 27
Can somebody please explain to a beginner how to do this?
Print the number and then sum every other digit
int sum_every_other_digit_after_first(unsigned long long x) {
char buf[sizeof x * CHAR_BIT];
sprintf(buf, "%llu", x);
char *p = buf;
int sum = 0;
while (*p) {
p++; // Skip digit
if (*p) {
sum += *p++ - '0';
}
}
return sum;
}
or as inspired by #PageNotFound
int sum_every_other_digit_after_first(unsigned long long x) {
int esum = 0;
int osum = 0;
while (x > 0) {
esum += x%10;
x /= 10;
if (x == 0) {
return osum;
}
osum += x%10;
x /= 10;
}
return esum;
}
or for fun, a recursive solution
int sum_every_other_digit_after_first_r(unsigned long long x, int esum, int osum) {
if (x >= 100) {
int digit2 = x % 100;
esum += digit2 % 10;
osum += digit2 / 10
return sum_every_other_digit_after_first_r(x / 100, esum, osum);
}
if (x >= 10) {
return esum + x % 10;
}
return osum;
}
sum_every_other_digit_after_first_r(1234567,0,0) --> 12
My solution
#include <stdio.h>
int main()
{
int SIN = 193456787;
int a = 0, b = 0, cnt = 0;
while (SIN > 0) {
if (cnt % 2) b += SIN % 10;
else a += SIN % 10;
cnt++;
SIN /= 10;
}
printf("%d\n", cnt%2 ? b : a);
return 0;
}
Note: Please comment if this is not what you intended, as your question is a little ambigous.
#include <stdio.h>
int main() {
unsigned number;
scanf("%u\n", &number);
unsigned result = 0;
unsigned tmp = number;
unsigned numberOfDigits = 0;
do
numberOfDigits++;
while((tmp /= 10) != 0);
if(numberOfDigits % 2 != 0)
number /= 10;
while(number >= 10) {
result += number % 10;
number /= 100; // Skip two digits
}
printf("%u\n", result);
}

Print integer as character digits (no arrays/printf/etc...)

I am attempting to print integers to the console in C with a few constraints, the most significant of which being that I may only write individual characters to the console as follows:
void my_char(char ch)
}
write(1, &ch, 1);
}
Other constraints include NO predefined methods (printf, log, etc). No recursion. Lastly, I may NOT create an array.
So far I have come up with a method that prints the numbers out perfectly well... backwards.
int main()
{
int i = -345320;
my_int(i);
return 0;
}
void my_int(int x)
{
char *a;
int n;
if(x < 0)
{
x = x * -1;
my_char('-');
}
while(x)
{
n = x % 10;
a = (char*)&n;
my_char(*a + 48);
x /= 10;
}
}
Are there other good ways to approach this or am I at least going in the right direction? I would ideally like to expand this to print an integer in any base I provide, but I need to start here.
I was playing with iterating a pointer over each Byte of the integer but I can't grasp how I would use those character values to re-create the integer.
Any advice is appreciated. I'd much rather receive some insight than just a code solution. I'd also love input on making it more lean.
Here's a general (ugly!) solution following your constraints. It uses the idea I gave in the comment above. It assumes 32-bit ints.
void my_int(int x) {
int n = 1000000000;
if (x == 0) {
my_char('0');
return;
}
if (x == INT_MIN) { // INT_MIN is in limits.h
my_char('-'); my_char('2'); my_char('1');
my_char('4'); my_char('7'); my_char('4');
my_char('8'); my_char('3'); my_char('6');
my_char('4'); my_char('8');
return;
}
if (x < 0) {
x *= -1;
my_char('-');
}
while (n > x) n /= 10;
while (n != 0) {
my_char(x / n % 10 + '0');
n /= 10;
}
}
This should do the trick. It prints the integer forwards.:
void my_int(int x)
{
int temp = 0;
int divFactor = 10;
if(x==0)
{
my_char('0');
return;
}
if(x < 0)
{
x = x * -1;
my_char('-');
}
temp = x;
while((temp /= 10) > 10) {divFactor *= 10;}
for(;divFactor > 0;divFactor /= 10)
{
temp = x;
temp /= divFactor;
my_char(temp + '0');
x -= divFactor * temp;
}
printf("\n done!");
}
int main()
{
int i = -1234001;
my_int(i);
return 0;
}
void my_int(int x)
{
int n;
int copy;
char digit;
// handle 0
if (!x)
{
my_char('0');
return;
}
// emit sign
if(x < 0)
{
x = x * -1;
my_char('-');
}
// count base-10 digits in x, store 10^n in n
n = 1;
copy = x/10; // shorten loop by 1 iteration
while (copy)
{
n *= 10;
copy /= 10;
}
// 'n' is now a digit selector
while (n)
{
digit = x/n;
my_char(digit + '0'); // print the most significant digit
x -= digit*n; // remove the most significant digit from x
n /= 10;
}
}

How to divide digits and compare them, in C

Write a program that will find the largest number smaller than N that is totally different from a given number X. One number is totally different from other only if it doesn't contain any of the digits from the other number. N and X are read from standard input. The problem should be solved without the use of arrays.
Example Input 1: 400 897
Example Output 1: 366
Example Input 2: 1000 1236498
Example Output 2:777
No it's not homework, it was on one of the midterms and it's been killing me. I though about taking the first numbers last digit with %10 then taking the second numbers digit with %10 comparing them but...I just can't get it to work...I ended up with an endless loop...I just don't understand how to get every digit of the numbers and compare them to the other number.
#include <stdio.h>
int main () {
int N, X, num_N, num_X, i, lastDigit_N, lastDigit_X, flag, smaller_than_N;
scanf("%d%d", &N, &X);
smaller_than_N = N - 1;
for (i = smaller_than_N; i > 0; i--) {
num_N = i;
num_X = X;
flag = 0;
while (num_N > 0) {
lastDigit_N = num_N % 10;
while (num_X > 0) {
lastDigit_X = num_X % 10;
if (lastDigit_N == lastDigit_X) {
break;
}
else {
flag = 1;
}
num_X /= 10;
}
num_N /= 10;
}
if(flag) {
printf("%d", i);
break;
}
}
return 0;
}
You could build a bitmask for your numbers showing the digits which are contained.
uint16_t num2bitmask(int number)
{
uint16_t result = 0;
while (number) {
int digit = number % 10;
number /= 10;
result |= (1 << digit);
}
return result;
}
With this function, you can create your bitmask for X and then iterate from N-1 down to 1 until you find a value which doesn't have any bits in common with the other value.
If you have a number with digits d_1, d_2, ..., d_n, and you're allowed to use digits in the set D, then possible solutions look like:
d_1, ..., d_{i-1}, max(d in D | d < d_i), max(d in D), ..., max(d in D).
That is, the digits are the same up to some point, then the next digit is as large as possible while being below the input digit, then the rest are just as large as possible.
Not all these "solutions" will be valid, but if you iterate through them in reverse order (there's exactly n for an input number of size n), the first valid one you find is the answer.
Some code, including tests:
#include <stdio.h>
int digit_length(int a) {
int r = 0;
while (a) {
a /= 10;
r += 1;
}
return r;
}
int get_digit(int a, int k) {
while (k--) a /= 10;
return a % 10;
}
int largest_different(int a, int b) {
int lena = digit_length(a);
int invalid = b ? 0 : 1;
for (; b; b /= 10) invalid |= 1 << (b % 10);
int max_valid = 9;
while (max_valid >= 0 && (invalid & (1 << max_valid)))
max_valid--;
if (max_valid == -1) return -1;
for (int i = 0; i < lena; i++) {
int d = get_digit(a, i) - 1;
while (d >= 0 && (invalid & (1 << d)))d--;
if (d < 0) continue;
int solution = 0;
for (int k = lena - 1; k >= 0; k--) {
solution *= 10;
solution += (k < i ? max_valid : k > i ? get_digit(a, k) : d);
}
return solution;
}
return -1;
}
int main(int argc, char *argv[]) {
struct {int n; int x; int want;} examples[] = {
{400, 897, 366},
{1000, 1236498, 777},
{998, 123, 997},
};
int error = 0;
for (int i = 0; i < sizeof(examples) / sizeof(*examples); i++) {
int got = largest_different(examples[i].n, examples[i].x);
if (got != examples[i].want) {
error = 1;
printf("largest_different(%d, %d) = %d, want %d\n",
examples[i].n, examples[i].x, got, examples[i].want);
}
}
return error;
}
There's not always a solution. In that case, the function returns -1.

Why this code works with visual studio on Windows 7 and doesnt work for linux correctly

long long int fun2(int a, int b, int m)
{
long long int res = 1;
long long int c = a % m;
for (int i = 1; i <= b; i <<= 1)
{
c = c % m;
if ((b & i) != 0)
{
res = res * c;
res = res % m;
}
c = c * c;
}
return res;
}
int fun(int num, int k)
{
srand((unsigned)time(NULL));
if (num <= 1)
{
return num * 10;
}
if (num == 2 || num == 3 || num == 5)
{
return num * 10 + 1;
}
if (num % 2 == 0)
{
return num * 10;
}
if (num % 3 == 0)
{
return num * 10;
}
if(num % 5 == 0)
{
return num * 10;
}
int s = 0;
int s_pow = 1;
while ((s_pow & (num - 1)) == 0)
{
s = s + 1;
s_pow = s_pow << 1;
}
int d = num / s_pow;
for (int i = 0; i < k; i++)
{
int a = (int)((num - 1) * rand() / (RAND_MAX + 1.0)) + 1;
if (fun2(a, d, num) != 1)
{
is_prime = false;
for (int r = 0; r <= s - 1; r++)
{
if (fun2(a, (1 << r) * d, num) == num - 1)
{
is_prime = true;
break;
}
}
if (!is_prime)
{
return num * 10;
}
}
}
return num * 10 + 1;
}
Where is a problem, maybe these long long int with int compares doesnt work correctly.
Compilation for windows and linus is without any warnings. It works but gives bad results for linux, for windows is ok. Please help.
#EDIT
I deleted code with INT_MIN and INT_MAX I just tried to fix the problem with this. (Sorry, should have delete it)
Problem SOLVED by myself !!!! Imagine that problem was in random a. I exchange this
int a = (int)((num - 1) * rand() / (RAND_MAX + 1.0)) + 1;
with this
int a = (int)(rand()%(num-1)) + 1;
and everything works perfect – user3144540

Resources