PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : C - Hilfe! Problem mit Zahlen!!!



B4n4n4
12.03.2010, 23:36
Hallo!

Bin ein C Einsteiger und versuche mich an meinen ersten Programmen. Habe nun über Happy-Security ein Hackit gefunden bei dem ich mit Zahlen rechnen muss die größer sind als 4294967296. Allerdings ist die Variablen Zuweisung ja nicht so groß. Wie kann ich es anstellen das sich Zahlen die größer sind in Variablen abspeichern lassen?

MfG
B4n4n4

PHRoZeNCReW
13.03.2010, 00:16
Hallo,
Anstatt den Datentyp int zu verwenden könntest du auf __int64 oder auch double umsteigen.

inout
13.03.2010, 00:28
Dann brauchst du einen Datentyp, der größer ist als 32-bit.
Das ist natürlich systemabhängig, aber du kannst auch mal sowas wie unsigned long long ausprobieren.

Einen Blick dazu in die limits.h schadet auch nicht.

Wenn es noch größer sein muss, kannst du - wie bereits gesagt - auch floats/doubles nehmen oder dir eine bigint Implementierung erstellen/suchen.

B4n4n4
13.03.2010, 01:16
Habe es bis unsigned long int versucht, hat nicht gereicht. Werde mir mal die Sache mit der bigint Implementierung genauer anschauen..

MfG
B4n4n4

GregorSamsa
13.03.2010, 03:03
unsigned long sollte eig. reichen... Das geht ewig weit...

Ansonsten poste mal den Source, dann ist es definitiv einfacher dir zu helfem.... ;)

Sry für Rechtschreibfehler o.ä. bin besoffen...

blackberry
13.03.2010, 08:30
unsigned long = unsigned int = 32bit Zahl, ohne Vorzeichen; max Val: 0xFFFFFFFF (dies sollte auf den meißten 32bit Systemen der Fall sein)

unsigned long long = 64bit Zahl, ohne Vorzeichen; max Val: 0xFFFFFFFFFFFFFFFF (auch wieder nur auf 32bit Systemen; auf 64bit Systemen wäre das dann meines Wissens doppelt so groß)

Ihr müsst den Post von inout schon richtig lesen.

B4n4n4
13.03.2010, 13:07
unsigned long int geht von 0 bis 4294967296 auf einem 32bit System und das habe ich. Ich muss eigentlich nur die ungeraden, natürlichen Zahlen von 1 bis 489511 zusammen rechnen. Gäbe vermutlich einfachere Wege habe mich aber für den folgenden entschieden:


#include <stdio.h>

int a = 1, b = 3, i;
int main()
{
for (i = 1; i <= 4; i++)
{
a += b;
b += 2;
printf ("%d", a);
}
printf ("\n%d", a);
return 0;
}

Hier ist die Schleifen Bedingung 4, daher werden alle ungeraden natürlichen Zahlen von 1-10 addiert. Was aber wenn ich jetzt sehr große Zahlen brauche um eben die ungeraden Zahlen von 1 - 489511 zusammen zurechnen? Dann muss die 4 gegen 244755 ersetzt werden und könnt euch ja mal selbst ansehen was dabei raus kommt :confused:

BITTE KEINE FERTIGE LÖSUNG POSTEN!!!

Da das ganze wie gesagt ein Hackit ist.

MfG
B4n4n4

0x30
13.03.2010, 13:50
Division mit Rest – Wikipedia


1 % 2 = 1
2 % 2 = 0
3 % 2 = 1
4 % 2 = 0

Sollte eigentlich genügen.

blackberry
13.03.2010, 14:33
Man kann es auch unnötig kompliziert machen...
Wieso nicht einfach mit 1 anfangen und dann immer in Zweierschritten weiter?
Ergebnis:
1, 3, 5, 7, 9, 11, ...

B4n4n4
13.03.2010, 14:37
@ 0x30:
Was bringt mir eine Division mit Rest wenn ich eine große Addition habe?


Man kann es auch unnötig kompliziert machen...
Wieso nicht einfach mit 1 anfangen und dann immer in Zweierschritten weiter?
Ergebnis:
1, 3, 5, 7, 9, 11, ...

Weil das Programm nicht in 2er Schritten zählen sondern in 2er Schritten Addieren soll!

MfG
B4n4n4

blackberry
13.03.2010, 14:41
Weil das Programm nicht in 2er Schritten zählen sondern in 2er Schritten Addieren soll!

Und es ist also völlig unmöglich die so generierten Zahlen zu einer anderen dazuzuaddieren.
Mal ehrlich: misverstehen wir uns gerade, oder willst du mich einfach nur verarschen?

B4n4n4
13.03.2010, 14:44
Nein.. genau das tut das Programm oben doch!
a += b
b += 2
(a wird um den Wert b erhöht, b wird um 2 erhöht, Vorgang wiederholt sich durch die Schleife)

Das Problem besteht doch nur darin das sich so hohe Zahlen wie ich sie brauche nicht in einer Variable abspeichern lassen!

MfG
B4n4n4

blackberry
13.03.2010, 14:47
Und wieso nicht?
Hatten wir nicht auch schon geklärt, dass ein unsigned long long (<-- zwei mal long hintereinander - NICHT NUR EINMAL!) maximal 0xFFFFFFFFFFFFFFFF werden kann?

DoS
13.03.2010, 14:49
Also mit deiner Erklärung hört es sich schon fast an, als ob BlackBerry zu dumm wäre das selbst zu sehen (und das ist er garantiert nicht!).

Und die Antwort wurde dir schon gegeben. Benutze einen "unsigned long long" als Datentyp.

Edit: BB war schneller....

Mit freundlichen Grüßen
DoS

B4n4n4
13.03.2010, 14:56
Damit ergäbe sich also folgender Quellcode:


#include <stdio.h>

unsigned long long a = 1, b = 3, i;
int main()
{
for (i = 1; i <= 244755; i++)
{
a += b;
b += 2;
printf ("%d", a);
}
printf ("\a\n%d", a);
return 0;
}
Wobei -224042608 heraus kommt, was ja wohl kaum richtig sein kann! Mit niedrigen Zahlen dagegen funktioniert das Programm einwandfrei, es muss an den großen Zahlen liegen, oder findet jemand noch andere Fehler?

//EDIT
Ich möchte hier niemanden als Dumm bezeichnen, gerade da ich derjenige bin der hier die Frage stellt. Wenn jemand allerdings eine Lösung vorschlägt, und auf die richtigkeit seiner Lösung behaart (die in diesem Fall nicht richtig ist) dann finde ich das kaum gerechtfertigt wenn dann noch Sätze wie "willst du mich einfach nur verarschen?" kommen :(

MfG
B4n4n4

Keksdose
13.03.2010, 14:58
@B4n4n4:
die meinen nicht unsigned long long INT vary; sondern ohne INT
also:
unsigned long long vary;

vielleicht ist das hier das Problem...
es geht auch der Vorschlag mit __int64:

__int64 vary;

beide dürften gleich "groß" sein, nämlich 64bit ;)


edit: Hat sich geklärt sry..

blackberry
13.03.2010, 14:59
Die Ausgabe liegt an printf und nicht an den Zahlen.
printf ist darauf konzepiert bei %d normale Integer zu bearbeiten.
Dabei ist das höchstwertige Bit der 32bit für das Vorzeichen zuständig.
Bei einer vorzeichenlosen 64bit-Zahl wird dieses Bit (bit 31; wenn man von 0 anfängt zu zählen) ein ganz normales Bit wie jedes andere.

An deiner Stelle würde ich mir eine eigene unsigned long long to string Funktion schreiben.

EDIT:
@Keksdose
unsigned long long int ist das selbe wie unsigned long long.
Um genau zu sein ist long eher eine Art prefix. Wird kein int angegeben (könnte auch ein double sein; long double existiert...), so wird automatisch von einem int ausgegangen.
Selbiges gilt für short.

short := short int (16bit)
int := long int (32bit)
long := long int (32bit)
long long := long long int (64bit)
(Angaben für ein 32bit System und GCC; die Implementierung von der genauen größe von int wird vom Standart nicht vorgeschrieben und ist Compilerherstellern überlassen)

B4n4n4
13.03.2010, 15:01
Das klingt für einen Anfänger kompliziert...
Naja setze mich mal daran. Vielen Dank!

MfG
B4n4n4

0x30
13.03.2010, 15:19
Gut, dann habe ich dich einfach missverstanden. Um ehrlich zu sein, habe ich es auch nur kurz überflogen, weil ich bei jemandem zu Besuch bin.
Sorry :D

blackberry
13.03.2010, 15:42
Das klingt für einen Anfänger kompliziert...

Ein unsigned long long int auszugeben ist als rekursive Funktion ein 3-Zeiler!

#include <stdio.h>

// macht alles übersichtlicher
typedef unsigned long long int ulli;

void print_ulli(ulli i)
{
if (i > 10)
print_ulli(i / 10);
putchar(i % 10 + '0');
}

int main(void)
{
ulli i = 0x12345678FF;

print_ulli(i);
putchar('\n');
return 0;
}Erklärung:
Wenn i größer ist als 10 (also mehr als eine Ziffer enthält) wird die Funktion rekursiv mit (i / 10) aufgerufen; Stellen nach dem Komma werden dabei automatisch abgeschnitten.
Anschließend wird i modulo 10 berechnet - dies gibt uns die letzte Ziffer von i.
Das wird dann zu '0' (dem ASCII-Code für eine Null) addiert.
Somit erhalten wir das ASCII-Zeichen der letzten Ziffer.
Dieses wird mit putchar in STDIO ausgegeben.

EDIT:
und damit mein Ansatz zur Lösung deines Problems:
(wenn du es nicht sehen willst; schau es dir nicht an!)

#include <stdio.h>

// macht alles übersichtlicher
typedef unsigned long long int ulli;

void print_ulli(ulli i)
{
if (i > 10)
print_ulli(i / 10);
putchar(i % 10 + '0');
}

int main(void)
{
ulli a, b, i;

// deine Methode...
for (a = b = i = 1; i <= 244755; i++)
{
a += b;
b += 2;
}
print_ulli(a);

putchar('\n');

// ich denke eher, dass es so gemeint ist...
for (a = b = 1; b <= 244755; b += 2)
{
a += b;
}
print_ulli(a);
return 0;
}

PHRoZeNCReW
13.03.2010, 16:19
#include <stdio.h>

double dRes = 0;
int i;

int main()
{
for(i = 1; i < 489511; i+=2)
dRes += i;
printf("Ergebnis: %.0f\n", dRes);

return 0;
}

Edit: Sry, hab nicht über die erste Seite hinausgelesen. Einfach vergessen, was hier steht^^

sp1nny
13.03.2010, 18:15
Man sollte es vermeiden globale Variablen zu verwenden, denn es kann zu ungewollten Veränderungen etc. kommen wodurch Fehler entstehen. Wenn es möglich ist also immer lokale Variablen verwenden. Bei dem Fall kann man das int i auch in der Schleife deklarieren - i ist in dem Fall dann also nur in der Schleife gültig. Das würde dann so aussehen:



#include <stdio.h>

int main()
{
double dRes = 0;

for( int i = 1; i < 489511; i += 2)
{
dRes += i;
}

printf("Ergebnis: %.0f\n", dRes);

return 0;
}