Reputation: 1549
I'm learning C by translating some of the things I have done in Python to C. I have tried to look online as much as I can before coming here but it seems really difficult to find answers to what I'm looking for.
What follows is my (so-far) translation of the Miller-Rabin test for a number's primality.
#include <stdio.h>
#include <math.h>
_Bool prime(long long n);
int main() {
int i = 6;
for (i; i < 9; i++) {
if (prime(i)) {
printf("%i\n", prime(i));
}
}
}
_Bool prime(long long n) {
int s = 0;
int r = 0;
int a_index = 0;
// printf("the value of a_index when initialised is: %d\n", a_index);
// printf("the value of s when initialised is: %d\n", s);
int *a_list;
_Bool is_prime = 1;
_Bool composite_part_a = 1;
_Bool composite_part_b = 1;
long long d = n - 1;
while (d % 2 == 0) {
s++;
d = d / 2;
}
if (4759123141 <= n && n < 2152302898747) {
// malloc
a_list[0] = 2;
a_list[1] = 3;
a_list[2] = 5;
a_list[3] = 7;
a_list[4] = 11;
}
else if (9080191 <= n && n < 4759123141) {
// malloc
a_list[0] = 2;
a_list[1] = 7;
a_list[2] = 61;
}
else if (1373653 <= n && n < 9080191) {
// malloc
a_list[0] = 31;
a_list[1] = 73;
}
else if (4 <= n && n < 1373653) {
a_list = (int *) malloc(sizeof(int) * 2);
a_list[0] = 2;
a_list[1] = 3;
printf("the value of a_list[0] upon its first assignment is: %d\n", a_list[0]);
// printf("the first element of a_list is: %d\n", a_list[0]);
// printf("the second element of a_list is: %d\n", a_list[1]);
}
else if (n == 3 | n == 2) {
return 1;
}
else if (n % 2 == 0 | n == 1) {
return 0;
}
printf("the value of a_list[0] over here is: %d\n", a_list[0]);
// printf("%d\n", a_list[1]);
for (a_index; a_index < sizeof(a_list) / sizeof(int); a_index++) {
printf("test");
if ((long long)pow(a_index[a_list], d) % n != 1) {
composite_part_a = 1;
}
else {
composite_part_a = 0;
}
// printf("the value of r is: %d\n", r);
// printf("the value of s is: %d\n", s);
for (r; r < s; r++) {
printf("%lld\n", (int)pow(a_list[a_index], exp2(r) * d) % n);
if ((long long)pow(a_index[a_list], exp2(r) * d) % n != -1) {
composite_part_b = 1;
}
else {
composite_part_b = 0;
break;
}
}
if (composite_part_a && composite_part_b) {
return 0;
}
}
return is_prime;
}
The trouble with learning C is there isn't much good literature for pure beginners, outside of what I hear about K&R but that's in the mail and I can't get my hands on it right now. The program returns these errors:
3.c: In function ‘prime’:
3.c:52:26: warning: incompatible implicit declaration of built-in function ‘malloc’ [enabled by default]
/tmp/ccGQnk9T.o: In function `prime':
3.c:(.text+0x272): undefined reference to `pow'
3.c:(.text+0x2b9): undefined reference to `exp2'
3.c:(.text+0x2db): undefined reference to `pow'
3.c:(.text+0x30b): undefined reference to `exp2'
3.c:(.text+0x32d): undefined reference to `pow'
collect2: ld returned 1 exit status
First off, haven't I included to introduce pow and else? I know it's not proper to ask two questions and my main question is about pow and exp2, but if you do have a suggestion about the malloc as well feel free to include it.
Upvotes: 1
Views: 2282
Reputation: 451
You need to include <stdlib.h>
for malloc and free.
For the math stuff to work you have to link it,
gcc 3.c -lm
Where -l
is the library flag and m is tell it to use the math library
Also you need to move the definition of prime to above main, things need to be declared in order.
Since you are just starting here are some other helpful flags for the compiler
-g
this will give better debugging when using valgrind or gdb.
-o
lets you define the compiled file name eg: gcc 3.c -o 3
will create ./3
instead of ./a.out
Upvotes: 0
Reputation: 599
3.c:52:26: warning: incompatible implicit declaration of built-in function ‘malloc’ [enabled by default]
Is caused by a missing include, malloc() is defined in stdlib.h so need to include that.
3.c:(.text+0x272): undefined reference to `pow' (and the rest)
Is caused by a missing link to libm. Most (if not all) methods in math.h are not in standard libc that always gets linked but in libm instead.
How to link differs between compiler, but for gcc (and many other unix compilers):
gcc 3.c -o 3 -lm
Where "-lm" tells gcc to link libm.
Upvotes: 1
Reputation: 409432
You need to link with the math library as well, it's not included by default.
Something like the following command:
$ gcc 3.c -lm
Notice the -lm
argument... It tells the linker to add a library (the -l
part) and the name of the library (the m
part).
Upvotes: 5
Reputation: 121427
Math functions are part of libm
. Link them when you compile with -lm
.
Upvotes: 3