Reputation: 12520
I'm trying to implement the following (pseudo-code-python) in C using large numbers:
while i * i < n:
if n % i:
i += 1
I came up with the following using the gmp.h
library:
#include <stdio.h>
#include <gmp.h>
int main () {
mpz_t n;
mpz_t i;
mpz_t o; // Hold constant mpz "1" for incrementing i
mpz_t x; // Holds "i * i" each loop
mpz_set_str(n, "338852330881981183", 10);
mpz_set_str(i, "2", 10);
mpz_set_str(o, "1", 10);
mpz_set_str(x, "4", 10);
while( mpz_cmp(x, n) < 0 ) {
mpz_add(i, i, o);
mpz_pow_ui(x, i, 2);
}
mpz_clear(i);
mpz_clear(n);
return 0;
}
I don't get any errors when I compile with GCC but when I try to run the program I get the following Aborted
. I've never seen this before and don't program much in C let alone using gmp.h
and very large numbers.
*** glibc detected *** ./factor: realloc(): invalid old size: 0x00000000004006d0 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x76d76)[0x7fdc1eb7bd76]
/lib/x86_64-linux-gnu/libc.so.6(+0x7c94c)[0x7fdc1eb8194c]
/lib/x86_64-linux-gnu/libc.so.6(realloc+0xf0)[0x7fdc1eb81c60]
/usr/lib/x86_64-linux-gnu/libgmp.so.10(__gmp_default_reallocate+0x1c)[0x7fdc1ee98a1c]
/usr/lib/x86_64-linux-gnu/libgmp.so.10(__gmpz_realloc+0x3a)[0x7fdc1eeaebba]
/usr/lib/x86_64-linux-gnu/libgmp.so.10(__gmpz_set_str+0x301)[0x7fdc1eeafef1]
./factor[0x400810]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xfd)[0x7fdc1eb23ead]
./factor[0x4006f9]
======= Memory map: ========
00400000-00401000 r-xp 00000000 08:01 1723311 /root/Desktop/factor
00600000-00601000 rw-p 00000000 08:01 1723311 /root/Desktop/factor
01629000-0164a000 rw-p 00000000 00:00 0 [heap]
7fdc18000000-7fdc18021000 rw-p 00000000 00:00 0
7fdc18021000-7fdc1c000000 ---p 00000000 00:00 0
7fdc1e8ef000-7fdc1e904000 r-xp 00000000 08:01 1445725 /lib/x86_64-linux-gnu/libgcc_s.so.1
7fdc1e904000-7fdc1eb04000 ---p 00015000 08:01 1445725 /lib/x86_64-linux-gnu/libgcc_s.so.1
7fdc1eb04000-7fdc1eb05000 rw-p 00015000 08:01 1445725 /lib/x86_64-linux-gnu/libgcc_s.so.1
7fdc1eb05000-7fdc1ec85000 r-xp 00000000 08:01 1445701 /lib/x86_64-linux-gnu/libc-2.13.so
7fdc1ec85000-7fdc1ee85000 ---p 00180000 08:01 1445701 /lib/x86_64-linux-gnu/libc-2.13.so
7fdc1ee85000-7fdc1ee89000 r--p 00180000 08:01 1445701 /lib/x86_64-linux-gnu/libc-2.13.so
7fdc1ee89000-7fdc1ee8a000 rw-p 00184000 08:01 1445701 /lib/x86_64-linux-gnu/libc-2.13.so
7fdc1ee8a000-7fdc1ee8f000 rw-p 00000000 00:00 0
7fdc1ee8f000-7fdc1eef6000 r-xp 00000000 08:01 2240985 /usr/lib/x86_64-linux-gnu/libgmp.so.10.0.5
7fdc1eef6000-7fdc1f0f6000 ---p 00067000 08:01 2240985 /usr/lib/x86_64-linux-gnu/libgmp.so.10.0.5
7fdc1f0f6000-7fdc1f0fe000 rw-p 00067000 08:01 2240985 /usr/lib/x86_64-linux-gnu/libgmp.so.10.0.5
7fdc1f0fe000-7fdc1f11e000 r-xp 00000000 08:01 1445677 /lib/x86_64-linux-gnu/ld-2.13.so
7fdc1f2fb000-7fdc1f2fe000 rw-p 00000000 00:00 0
7fdc1f31b000-7fdc1f31d000 rw-p 00000000 00:00 0
7fdc1f31d000-7fdc1f31e000 r--p 0001f000 08:01 1445677 /lib/x86_64-linux-gnu/ld-2.13.so
7fdc1f31e000-7fdc1f31f000 rw-p 00020000 08:01 1445677 /lib/x86_64-linux-gnu/ld-2.13.so
7fdc1f31f000-7fdc1f320000 rw-p 00000000 00:00 0
7fffa2304000-7fffa2325000 rw-p 00000000 00:00 0 [stack]
7fffa23b2000-7fffa23b4000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
Aborted
Upvotes: 0
Views: 354
Reputation: 1
You should initialize GMP bigintegers using mpz_init
. So your main
function should start with
mpz_t n;
mpz_t i;
mpz_t o; // Hold constant mpz "1" for incrementing i
mpz_t x; // Holds "i * i" each loop
mpz_init(n);
mpz_init(i);
mpz_init(o);
mpz_init(x);
BTW, you probably want to output x
near the end of main
using
mpz_out_str (stdout, 10, x);
before the calls to mpz_clear
Then you should compile with gcc -Wall -Wextra -g yourprog.c -lgmp -o yourprog
. Once the program is correctly debugged, you might add -O2 mtune=native
to optimize your program.
Upvotes: 5