Segmentation Errors
Chris Osborne
chris.osborne at gmx.com
Wed Mar 14 15:32:13 CET 2012
Good day to all,
I believe that these irritatiing little buggers (segmentation errors) have something to do with memory problems. I have a program, (the one that I was discussing with regards to speed), of which I will attach the source code to the bottom of the program. This program works when we input reasonably small numbers. However we need to test some numbers with a minimum of 2 million digits and by the computer throws a segmentation error when it goes round the loop that increases b the second time (just after bb=b + 1).
Any ideas or help would be very useful. (Like possibly a better way to import the numbers from the files, or maybe we just need to learn to handle memory stacks).
Thanks in advance
Chris
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <gmpxx.h>
#include <ctime>
double diffclock(clock_t clock1,clock_t clock2)
{
double diffticks=clock1-clock2;
double diffms=(diffticks*1000)/CLOCKS_PER_SEC;
return diffms;
}
int main (int argc, char *argv[])
{
//set up vars as ints in Z
mpz_t x, xmax, b, d, sqd, sqdsq, c, ab, bb, bx, b_squared;
//init vars
mpz_init(x);
mpz_init(xmax);
mpz_init(b);
mpz_init(d);
mpz_init(sqd);
mpz_init(sqdsq);
mpz_init(c);
mpz_init(ab);
mpz_init(bb);
mpz_init(bx);
mpz_init(b_squared);
//FILE *file1 = fopen("min.txt", "rb");
char *minname = "min.txt";
std::ifstream minfile(minname);
char temp0[2000001];
minfile.getline(temp0, 2000001);
mpz_set_str (x, temp0, 10);
char *maxname = "max1.txt";
std::ifstream maxfile(maxname);
char temp1[2000010];
maxfile.getline(temp1, 2000010);
mpz_set_str (xmax, temp1, 10);
//setting up x's extrema (string(var, where?, base)
//mpz_set_str (x, argv[1], 10);
//mpz_set_str (xmax, argv[2], 10);
//print Testing from: To:
gmp_printf ("Testing from: %Zd\n\n", x);
gmp_printf ("To: %Zd\n\n", xmax);
//start the timer!
clock_t begin=clock();
//create output file
FILE *file = fopen("output.txt", "w");
FILE *file1 = fopen("notwork.txt", "w");
//main sub-routine, While x<=xmax
for( ;mpz_cmp(x, xmax)<0; mpz_add_ui(x,x,1))
{
gmp_printf ("Current x: %Zd\n", x);
//make sure b and the counter are equal to 0
mpz_set_ui (b,0);
do
{
//add 1 to b on each loop
mpz_add_ui (b,b,1); //acheived with for
//gmp_printf("current b: %Zd\n", b);
//work up to d=(b+1)²-4(41b²-bx)
//creation of (b+1)²
mpz_add_ui(bb,b,1);
mpz_pow_ui(bb,bb,2);
//creation of 4(41b²-bx)
mpz_pow_ui(b_squared,b,2);
//ab=41b²
mpz_mul_ui(ab,b_squared,41);
mpz_clear(b_squared);
//bx=...b*x!!!!
mpz_mul(bx,b,x);
/* Not correctly assembling*
//assembly using submul (rop=op2*(rop-op1))
//ab=4(41b²-bx)
mpz_submul_ui(ab,bx,4); */
//Let's do it the old-fashioned slow assembly way then ^^
mpz_sub(ab,ab,bx);
mpz_mul_ui(ab,ab,4);
mpz_clear(bx);
//=> d=bb-ab
mpz_sub(d,bb,ab);
mpz_clear(bb);
mpz_clear(ab);
// iff d is negative and c is equal to zero (counter unused), this counter shouldn't be needed but is a decent safeguard, then print this value of x to the output file
//This needs to be before the sqrt you stupid bugger!
if(mpz_sgn(d)<0)
{
gmp_fprintf(file, "%Zd,", x);
break;
};
//check if d is a perfect square
//calculate d's square root
mpz_sqrt(sqd,d);
//db gmp_printf("sqd: %Zd \n\n", sqd);
//and then sqaure the sqaure root
mpz_mul(sqdsq,sqd,sqd);
//check if ((floor(d)^1/2)^2)==d and a conditional sub-routine to break our loop and add 1 to a counter
if(mpz_cmp(sqdsq,d)==0)
{
gmp_fprintf(file1, "%Zd,", x);
break;
};
}while(mpz_sgn(d)>=0);
}
clock_t end=clock();
std::cout << "Time elapsed: " << double(diffclock(end,begin)) << " ms"<< std::endl;
}
More information about the gmp-discuss
mailing list