floating point exception

Schnelle objektorientierte, kompilierende Programmiersprache.
Antworten
ttmgot
Beiträge: 3
Registriert: Mi Nov 28, 2012 1:46 pm

floating point exception

Beitrag von ttmgot » Mi Nov 28, 2012 1:54 pm

Hi,

ich programmiere gerade in C ein Programm, das herausfinden soll, ob eine Zahl eine Primzahl ist oder nicht. Die entsprechende Funktion sieht so aus:

Code: Alles auswählen


int isprime(int p){

	omp_set_num_threads(4);
	int d;
	int ergebnis = 1;

	#pragma omp parallel
	{


		#pragma omp for schedule(static, 5)
		for(d=2; d < p; d=d+1){

			if(p % d ==0){
				ergebnis = 0;
			}
		}

	}
	return ergebnis;


}


Das Kompilieren funktioniert einwandfrei, aber beim ausführen kriege ich immer eine Fehlermeldung. Die meldung ist eine zahl (jedesmal eine andere) gefolgt von

floating point exception (core dumped) ./a.out
Beim googeln hab ich allerdings als möglichen Fehler nur gekriegt, das das Programm möglicherweise versucht durch 0 zu teilen, aber das macht es ja nicht.

Weiß vielleicht jemand rat?

nufan
Wiki-Moderator
Beiträge: 2558
Registriert: Sa Jul 05, 2008 3:21 pm

Re: floating point exception

Beitrag von nufan » Mi Nov 28, 2012 4:19 pm

Hallo :)

Kannst du feststellen in welcher Zeile der Fehler auftritt? Noch besser wäre ein möglichst kleines, aber kompilierbares Beispiel inklusive den Anweisungen zum Kompilieren.

Benutzeravatar
cloidnerux
Moderator
Beiträge: 3125
Registriert: Fr Sep 26, 2008 4:37 pm
Wohnort: Ram (Gibts wirklich)

Re: floating point exception

Beitrag von cloidnerux » Do Nov 29, 2012 10:13 am

Hi:

Code: Alles auswählen

int isprime(int n)
{
	for(int d = 2; d < n; d++)
	{
		if((n % d) == 0) return 0;
	}
	return 1;
}
Dieser Code macht bei mir keine Probleme.
Was aber sein kann, ist dass dein rechter Prameter von Modulo 0 ist:

Code: Alles auswählen

x % 0 => Error
Prüfe bitte deinen Code auf sowas.
Warum verwendest du so viel Multithreading gedöns? Was erhoffst du dir davon?
Man kann den Algorithmus Mathematisch sehr viel schneller machen, ohne Threads und so.
Redundanz macht wiederholen unnötig.
quod erat expectandum

ttmgot
Beiträge: 3
Registriert: Mi Nov 28, 2012 1:46 pm

Re: floating point exception

Beitrag von ttmgot » Fr Nov 30, 2012 11:20 am

erstmal sorry, das ich länger nicht geantwortet hab, mein Internet war down.

Scheint allerdings einfach so zu sein dass die Primzahl zu lang war, mit longs gehts (klassischer Anfängerfehler eben)

Warum verwendest du so viel Multithreading gedöns? Was erhoffst du dir davon?
Ich mach deswegen so viel parallel, weils eine Übungsaufgabe von der Uni ist, (ich fands auch ein bisschen blöd)

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: floating point exception

Beitrag von Xin » Fr Nov 30, 2012 11:50 am

ttmgot hat geschrieben:Scheint allerdings einfach so zu sein dass die Primzahl zu lang war, mit longs gehts (klassischer Anfängerfehler eben)
*lach* Ich programmiere seit über 25 Jahren, habe nur über den Quelltext geguckt und es auch nicht erkannt, bzw. auch nicht dran gedacht, dass es für einen solchen Quelltext eigentlich nach Überlauf schreit.
Von daher...
ttmgot hat geschrieben:Ich mach deswegen so viel parallel, weils eine Übungsaufgabe von der Uni ist, (ich fands auch ein bisschen blöd)
Magst Du OpenMP hier mal in einem Artikel vorstellen? So in der Form Installation, Compilereinstellung, ein, zwei Anwendungsbeispiele? Ich habe OpenMP auf der Todo-Liste für Proggen.org aber soweit unten, dass ich vermutlich erst in Jahren dazu komme. Vielleicht kannst Du da schon etwas vorgreifen, wenn Du Lust hast?
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

nufan
Wiki-Moderator
Beiträge: 2558
Registriert: Sa Jul 05, 2008 3:21 pm

Re: floating point exception

Beitrag von nufan » Fr Nov 30, 2012 1:37 pm

ttmgot hat geschrieben:Scheint allerdings einfach so zu sein dass die Primzahl zu lang war, mit longs gehts (klassischer Anfängerfehler eben)
Vielleicht eine blöde Frage... aber wie kann dieser Code einen Überlauf verursachen?!

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: floating point exception

Beitrag von Xin » Fr Nov 30, 2012 2:21 pm

dani93 hat geschrieben:
ttmgot hat geschrieben:Scheint allerdings einfach so zu sein dass die Primzahl zu lang war, mit longs gehts (klassischer Anfängerfehler eben)
Vielleicht eine blöde Frage... aber wie kann dieser Code einen Überlauf verursachen?!
Narf... mit meiner Erinnerung an den Code und der Aussage von eben erschien mit das logisch... jetzt, wo ich den Code erneut angucke, finde ich die Frage gar nicht so blöd.

Wieso waren dann die Primzahlen zu groß? Und warum sollte eine %-Anweisung überhaupt eine Floating-Point-Exception werfen. (Tuts aber, habe ich gerade extra mal getestet)

Womit die Frage bleibt, wann kann d == 0 werden? Wenn p < 0 ist, startet die For-Schleife nie. Ist p > 2, läuft sie, aber endet, bevor d den Überlauf schafft... ist p=0 oder p=1, startet die Schleife nicht.

Kannst den Quellcode mal mit Aufruf so posten, wie er den Fehler geworfen hat!?
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

ttmgot
Beiträge: 3
Registriert: Mi Nov 28, 2012 1:46 pm

Re: floating point exception

Beitrag von ttmgot » Fr Nov 30, 2012 4:53 pm

Xin hat geschrieben: Magst Du OpenMP hier mal in einem Artikel vorstellen? So in der Form Installation, Compilereinstellung, ein, zwei Anwendungsbeispiele? Ich habe OpenMP auf der Todo-Liste für Proggen.org aber soweit unten, dass ich vermutlich erst in Jahren dazu komme. Vielleicht kannst Du da schon etwas vorgreifen, wenn Du Lust hast?
Ich kanns mal um Weihnachten rum versuchen, wenn ich ein bisserl mehr Zeit hab, allerdings arbeite ich mich selbst erst in das Thema rein (und in normales C, hatte bisher nur Java), deswegen kann ich von der Qualität her nichts versprechen.
Xin hat geschrieben:
Wieso waren dann die Primzahlen zu groß? Und warum sollte eine %-Anweisung überhaupt eine Floating-Point-Exception werfen. (Tuts aber, habe ich gerade extra mal getestet)

Womit die Frage bleibt, wann kann d == 0 werden? Wenn p < 0 ist, startet die For-Schleife nie. Ist p > 2, läuft sie, aber endet, bevor d den Überlauf schafft... ist p=0 oder p=1, startet die Schleife nicht.

Kannst den Quellcode mal mit Aufruf so posten, wie er den Fehler geworfen hat!?
Sicher hier:

Code: Alles auswählen

#include <stdio.h>
#include <omp.h>
#include <time.h>
#include <unistd.h>
#include <math.h>


int isprime(int p){

	omp_set_num_threads(4);
	int d = 2;
	int ergebnis = 1;

	#pragma omp parallel
	{


		#pragma omp for schedule(static, 5)
		for(d=2; d < p; d=d+1){

			if((p % d) ==0){
				ergebnis = 0;
			}
		}

	}
	return ergebnis;


}

int main(){

time_t start, end;

time (&start);



if(isprime(2147483647)){
printf("%d ist eine Primzahl\n", 2147483647);
}else{
}

time(&end);


printf("Das programm dauerte %f Sekunden\n", difftime(end,start)); 


return 0;
}
Ich dachte eben meine Primzahl wäre einfach zu groß, und wenn ich longs nehme scheints zu klappen

nufan
Wiki-Moderator
Beiträge: 2558
Registriert: Sa Jul 05, 2008 3:21 pm

Re: floating point exception

Beitrag von nufan » Sa Dez 01, 2012 2:56 pm

Mir ist dieses Verhalten noch immer schleierhaft ^^
valgrind sagt aber explizit:
valgrind hat geschrieben:==28429== Process terminating with default action of signal 8 (SIGFPE)
==28429== Integer divide by zero at address 0x402C80A14
==28429== at 0x400985: isprime._omp_fn.0 (main.c:21)
Zeile 21 ist wie zu erwarten die Modulo-Berechnung.

Jetzt hab ich aber was anderes versucht:

Code: Alles auswählen

#pragma omp for schedule(dynamic)
for(d=2; d < p; d=d+1){
Funktioniert ebenfalls und das mit int als Datentyp. Diese Berechnung dauert bei mir 62 Sekunden.
Was bedeutet dieses static?
Wikipedia hat geschrieben: schedule(type, chunk): This is useful if the work sharing construct is a do-loop or for-loop. The iteration(s) in the work sharing construct are assigned to threads according to the scheduling method defined by this clause. The three types of scheduling are:

* static: Here, all the threads are allocated iterations before they execute the loop iterations. The iterations are divided among threads equally by default. However, specifying an integer for the parameter chunk will allocate chunk number of contiguous iterations to a particular thread.
* dynamic: Here, some of the iterations are allocated to a smaller number of threads. Once a particular thread finishes its allocated iteration, it returns to get another one from the iterations that are left. The parameter chunk defines the number of contiguous iterations that are allocated to a thread at a time.
* guided: A large chunk of contiguous iterations are allocated to each thread dynamically (as above). The chunk size decreases exponentially with each successive allocation to a minimum size specified in the parameter chunk
Was aber ebenfalls funktioniert ist folgendes:

Code: Alles auswählen

#pragma omp for schedule(static)
for(d=2; d < p; d=d+1){
Diese Berechnung braucht nur 3 Sekunden.
Ohne mich genauer mit OpenMP auszukennen, behaupte ich jetzt dein Parameter für schedule (5) ist falsch ^^

Benutzeravatar
cloidnerux
Moderator
Beiträge: 3125
Registriert: Fr Sep 26, 2008 4:37 pm
Wohnort: Ram (Gibts wirklich)

Re: floating point exception

Beitrag von cloidnerux » Sa Dez 01, 2012 5:34 pm

Mal am Rande. Ich habe mir etwas Gedanken über die Optimierung gemacht und habe mal meinen Algorithmus gegen den hier gezeigten laufen lassen.
Code:

Code: Alles auswählen

#include <stdio.h>
#include <windows.h>
 
int isprime(int n)
{
	for(int d = 2; d < n; d++)
	{
		if((n % d) == 0) return 0;
	}
	return 1;
}

int isprime2(int n)
{
	if(!(n & 1)) return 0;
	for(int d = 3; d*d <= n; d += 2)
	{
		if((n % d) == 0) return 0;
	}
	return 1;
}

int main()
{
	int a=0, b=10;
	int c = a % b;
	double elapsed = 0, elapsed2 = 0;
	double total1 = 0, total2 = 0;
	LARGE_INTEGER start, end, frequency;
	int e1, e2;
	if(!QueryPerformanceFrequency(&frequency))
	{
		printf("Error with timer");
		return 0;
	}
	printf("Start\n");
	for(int i = 2147483547; i < 2147483647; i++)
	{
		start.QuadPart = 0;
		end.QuadPart = 0;
		QueryPerformanceCounter(&start);
		e1 = isprime(i);
		QueryPerformanceCounter(&end);
		elapsed = (double)(end.QuadPart  - start.QuadPart) / (double)(frequency.QuadPart);
		QueryPerformanceCounter(&start);
		e2 = isprime2(i);
		QueryPerformanceCounter(&end);
		elapsed2 = (double)(end.QuadPart  - start.QuadPart) / (double)(frequency.QuadPart);
		printf("%d: alg1: %f, alg2: %f, %d\n", i, elapsed, elapsed2, e1-e2);
		total1 += elapsed;
		total2 += elapsed2;
	}
	printf("Alg1: %f, Alg2: %f", total1/100, total2/100);
	return 0;
}
Output auf meinen System:

Code: Alles auswählen

Start
2147483547: alg1: 0.000001, alg2: 0.000001, 0
2147483548: alg1: 0.000001, alg2: 0.000001, 0
2147483549: alg1: 41.730378, alg2: 1.847140, 0
2147483550: alg1: 0.000001, alg2: 0.000001, 0
2147483551: alg1: 0.000599, alg2: 0.000297, 0
2147483552: alg1: 0.000001, alg2: 0.000001, 0
2147483553: alg1: 0.000001, alg2: 0.000001, 0
2147483554: alg1: 0.000001, alg2: 0.000001, 0
2147483555: alg1: 0.000001, alg2: 0.000001, 0
2147483556: alg1: 0.000001, alg2: 0.000001, 0
2147483557: alg1: 0.000072, alg2: 0.000030, 0
2147483558: alg1: 0.000001, alg2: 0.000001, 0
2147483559: alg1: 0.000002, alg2: 0.000002, 0
2147483560: alg1: 0.000001, alg2: 0.000001, 0
2147483561: alg1: 0.000004, alg2: 0.000002, 0
2147483562: alg1: 0.000001, alg2: 0.000001, 0
2147483563: alg1: 41.714660, alg2: 1.839688, 0
2147483564: alg1: 0.000001, alg2: 0.000001, 0
2147483565: alg1: 0.000001, alg2: 0.000001, 0
2147483566: alg1: 0.000001, alg2: 0.000001, 0
2147483567: alg1: 0.000221, alg2: 0.000107, 0
2147483568: alg1: 0.000001, alg2: 0.000001, 0
2147483569: alg1: 0.000001, alg2: 0.000001, 0
2147483570: alg1: 0.000001, alg2: 0.000002, 0
2147483571: alg1: 0.000001, alg2: 0.000009, 0
2147483572: alg1: 0.000001, alg2: 0.000001, 0
2147483573: alg1: 0.000001, alg2: 0.000001, 0
2147483574: alg1: 0.000001, alg2: 0.000001, 0
2147483575: alg1: 0.000001, alg2: 0.000001, 0
2147483576: alg1: 0.000001, alg2: 0.000001, 0
2147483577: alg1: 0.000001, alg2: 0.000001, 0
2147483578: alg1: 0.000001, alg2: 0.000001, 0
2147483579: alg1: 41.887388, alg2: 1.842863, 0
2147483580: alg1: 0.000001, alg2: 0.000001, 0
2147483581: alg1: 0.000003, alg2: 0.000002, 0
2147483582: alg1: 0.000001, alg2: 0.000001, 0
2147483583: alg1: 0.000001, alg2: 0.000001, 0
2147483584: alg1: 0.000001, alg2: 0.000001, 0
2147483585: alg1: 0.000001, alg2: 0.000001, 0
2147483586: alg1: 0.000001, alg2: 0.000001, 0
2147483587: alg1: 41.633890, alg2: 1.819885, 0
2147483588: alg1: 0.000001, alg2: 0.000001, 0
2147483589: alg1: 0.000001, alg2: 0.000001, 0
2147483590: alg1: 0.000001, alg2: 0.000001, 0
2147483591: alg1: 0.000001, alg2: 0.000001, 0
2147483592: alg1: 0.000001, alg2: 0.000001, 0
2147483593: alg1: 0.000002, alg2: 0.000001, 0
2147483594: alg1: 0.000001, alg2: 0.000001, 0
2147483595: alg1: 0.000001, alg2: 0.000001, 0
2147483596: alg1: 0.000002, alg2: 0.000002, 0
2147483597: alg1: 0.000001, alg2: 0.000001, 0
2147483598: alg1: 0.000001, alg2: 0.000001, 0
2147483599: alg1: 0.000032, alg2: 0.000016, 0
2147483600: alg1: 0.000001, alg2: 0.000001, 0
2147483601: alg1: 0.000001, alg2: 0.000001, 0
2147483602: alg1: 0.000001, alg2: 0.000001, 0
2147483603: alg1: 0.000023, alg2: 0.000012, 0
2147483604: alg1: 0.000001, alg2: 0.000001, 0
2147483605: alg1: 0.000001, alg2: 0.000001, 0
2147483606: alg1: 0.000001, alg2: 0.000001, 0
2147483607: alg1: 0.000001, alg2: 0.000001, 0
2147483608: alg1: 0.000001, alg2: 0.000001, 0
2147483609: alg1: 0.000002, alg2: 0.000001, 0
2147483610: alg1: 0.000001, alg2: 0.000001, 0
2147483611: alg1: 0.000001, alg2: 0.000001, 0
2147483612: alg1: 0.000001, alg2: 0.000001, 0
2147483613: alg1: 0.000001, alg2: 0.000001, 0
2147483614: alg1: 0.000003, alg2: 0.000001, 0
2147483615: alg1: 0.000001, alg2: 0.000001, 0
2147483616: alg1: 0.000001, alg2: 0.000001, 0
2147483617: alg1: 0.000147, alg2: 0.000063, 0
2147483618: alg1: 0.000001, alg2: 0.000001, 0
2147483619: alg1: 0.000001, alg2: 0.000001, 0
2147483620: alg1: 0.000001, alg2: 0.000001, 0
2147483621: alg1: 0.000294, alg2: 0.000137, 0
2147483622: alg1: 0.000001, alg2: 0.000001, 0
2147483623: alg1: 0.000002, alg2: 0.000001, 0
2147483624: alg1: 0.000001, alg2: 0.000001, 0
2147483625: alg1: 0.000001, alg2: 0.000001, 0
2147483626: alg1: 0.000002, alg2: 0.000001, 0
2147483627: alg1: 0.000002, alg2: 0.000001, 0
2147483628: alg1: 0.000001, alg2: 0.000001, 0
2147483629: alg1: 41.135518, alg2: 5.702943, 0
2147483630: alg1: 0.000001, alg2: 0.000001, 0
2147483631: alg1: 0.000001, alg2: 0.000001, 0
2147483632: alg1: 0.000001, alg2: 0.000001, 0
2147483633: alg1: 0.000109, alg2: 0.000055, 0
2147483634: alg1: 0.000001, alg2: 0.000001, 0
2147483635: alg1: 0.000001, alg2: 0.000001, 0
2147483636: alg1: 0.000001, alg2: 0.000001, 0
2147483637: alg1: 0.000001, alg2: 0.000001, 0
2147483638: alg1: 0.000001, alg2: 0.000001, 0
2147483639: alg1: 0.000001, alg2: 0.000001, 0
2147483640: alg1: 0.000001, alg2: 0.000001, 0
2147483641: alg1: 0.000051, alg2: 0.000026, 0
2147483642: alg1: 0.000001, alg2: 0.000001, 0
2147483643: alg1: 0.000001, alg2: 0.000001, 0
2147483644: alg1: 0.000001, alg2: 0.000001, 0
2147483645: alg1: 0.000001, alg2: 0.000001, 0
2147483646: alg1: 0.000001, alg2: 0.000001, 0
Alg1: 2.081035, Alg2: 0.130534
Redundanz macht wiederholen unnötig.
quod erat expectandum

Antworten