| Autor |
Nachricht |
SpR
Unregistrierter
|
SpR Unregistrierter
14:31:42 22.05.2012 Titel: |
Schnelle Rechenoperationen mit großen zahlen |
Zitieren |
Ich suche eine Möglichkeit mit großen Zahlen zuverlässig zu rechnen, am wichtigsten wären die Rechenoperationen mit denen man die Zahl um 1 verringert (dekrement) außerdem der Vergleich mit 0. Bei dem Vegleich mit 0 habe ich schon eine Idee das umzusetzen, allerdings nicht bei dem dekrement. Das Programm ist nicht für ein Studium, sondern für ein eigenes Programm. Ich benutze ein 32-bit Windows System ( Windows 7 ) |
|
|
|
 |
masm
Unregistrierter
|
masm Unregistrierter
16:02:31 22.05.2012 Titel: |
|
Zitieren |
- Was sind denn für dich große Zahlen?
- integer oder floating point?
- Welchen Assembler? |
|
|
|
 |
SpR
Unregistrierter
|
SpR Unregistrierter
21:25:57 22.05.2012 Titel: |
|
Zitieren |
Sorry hat länger gedauert war am Nachmitag nicht da, für mich sind große Zahlen bis zu 20-30 Stellen. Es sind Ganze Zahlen, also sowas wie BigInteger. Mich würde insgesamt interessieren, wie man mit solchen Zahlen rechnet also die Theorie, obwohl ich eingentlich nicht alle Rechenoperationen brauche sondern nur +,- sowie dekrement. |
|
|
|
 |
Spr
Unregistrierter
|
Spr Unregistrierter
21:26:56 22.05.2012 Titel: |
|
Zitieren |
Ich benutze inline Assembler von Visual C++, da ich es irgendwie net hinbekomme mit nasm ein Windows 7 lauffähiges Programm zu schreiben. |
|
|
|
 |
masm
Unregistrierter
|
masm Unregistrierter
23:33:52 22.05.2012 Titel: |
|
Zitieren |
Die Theorie ist sehr einfach: Addieren mit Übertrag. Dafür gibt es die Befehle Add with carry ADC und Subtract with borrow SBB.
Dekrementieren ist ja nichts weiter, als subtrahieren von 1 bzw. addieren von (-1).
Bsp.:
| Code: | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | ; 30 Dezimalstellen =>
; benötigte DWORDs = (ceil(log(1E30)/log(2))+31) and -32 = 3 = 96Bit
@dec:
lea edx,srcA
add DWORD ptr [edx+0],-1
adc DWORD ptr [edx+4],-1
adc DWORD ptr [edx+8],-1
@inc:
lea edx,srcA
add DWORD ptr [edx+0],1
adc DWORD ptr [edx+4],0
adc DWORD ptr [edx+8],0
@add:
lea edx,srcA
lea ecx,srcB
mov eax,[ecx]
add [edx],eax
mov eax,[ecx+4]
adc [edx+4],eax
mov eax,[ecx+8]
adc [edx+8],eax
@sub:
lea edx,srcA
lea ecx,srcB
mov eax,[ecx]
sub [edx],eax
mov eax,[ecx+4]
sbb [edx+4],eax
mov eax,[ecx+8]
sbb [edx+8],eax | |
Der Datentype müsste irgendwie so aussehen:
| Code: | typedef {
DWORD a1;
DWORD a2;
DWORD a3;
}INT96,*PINT96; | | |
|
|
|
 |
SpR
Unregistrierter
|
SpR Unregistrierter
14:57:59 23.05.2012 Titel: |
|
Zitieren |
Vielen Dank für die schnellen Antworten. Werde es sofort einmal versuchen.
Mfg SpR |
|
|
|
 |
SpR
Unregistrierter
|
SpR Unregistrierter
15:03:11 23.05.2012 Titel: |
|
Zitieren |
Ich hätte noch eine Frage wie kann ich dieser Struktur jetzt eine große Zahl zuweisen? Theoretisch könnte man ja jeden DWORD manuell zuweisen aber ich bin mir nicht sicher wie ich 200000000000000000 auf 4 DWORD aufteilen soll. |
|
|
|
 |
rkhb
Mitglied
Benutzerprofil
Anmeldungsdatum: 19.09.2010
Beiträge: 208
|
rkhb Mitglied
17:54:19 23.05.2012 Titel: |
|
Zitieren |
| SpR schrieb: | | Ich hätte noch eine Frage wie kann ich dieser Struktur jetzt eine große Zahl zuweisen? Theoretisch könnte man ja jeden DWORD manuell zuweisen aber ich bin mir nicht sicher wie ich 200000000000000000 auf 4 DWORD aufteilen soll. |
Aufteilung: Little Endian, also höchstwertiges DWORD hinten. Da Deine Zahl in ein LongLong hineingeht, statt vieler Worte:
| C++: | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | #include <stdio.h>
typedef union
{
struct
{
long long ll;
int biggest;
} ll;
struct
{
int a1;
int a2;
int a3;
} bigint;
} big_union;
int main(void)
{
big_union uni;
uni.ll.ll = 200000000000000000LL;
printf ("I64i: %I64i\n",uni.ll.ll);
printf ("I64u: %I64u\n",uni.ll.ll);
printf ("I64X: 0x%I64X\n",uni.ll.ll);
puts ("");
uni.bigint.a1 = 0xBB140000;
uni.bigint.a2 = 0x02C68AF0;
uni.bigint.a3 = 0x00000000;
printf ("I64i: %I64i\n",uni.ll.ll);
printf ("I64u: %I64u\n",uni.ll.ll);
printf ("I64X: 0x%I64X\n",uni.ll.ll);
return 0;
} | |
Man möge mich korrigieren, aber ich meine mich erinnern zu können, dass die Elemente in einer C-Struktur im Speicher nicht direkt aufeinander folgen müssen, was aber bei einem C-Array der Fall wäre. In diesem Fall wäre es sicherer mit einem Array zu arbeiten.
viele grüße
ralph |
Zuletzt bearbeitet von rkhb am 18:10:08 23.05.2012, insgesamt 2-mal bearbeitet |
|
 |
SpR
Unregistrierter
|
SpR Unregistrierter
20:39:11 24.05.2012 Titel: |
|
Zitieren |
Vielen Dank für die Antwort ich werde es sofort versuchen,
tut mir leid ,dasss ich nicht früher antworten konnte war aber leider heute ein stressiger Tag.
MfG SpR |
|
|
|
 |
SpR
Unregistrierter
|
SpR Unregistrierter
21:47:32 24.05.2012 Titel: |
|
Zitieren |
Vielen Dank für die Antworten hat alles sehr gut geklappt allerdings stehe ich jetzt wieder vor einem Problem,es handelt sich in diesem Fall um das abfangen von einem Überlauf. Mein Code sieht so aus.
| Assembler: | 1 2 3 4 5 6 7 8 | mov eax,addr ; in addr steht die Addresse des Speicherbereiches,welcher für die Speicherung der Zahlen vorgesehen ist
; also in diesem Falle 96 bits Speicherplatz (16 Bytes)
mov dword ptr[eax],0xFFFFFFFF ; Die Bereiche mit den Zahlen füllen
mov dword ptr[eax+4],0x00000000
mov dword ptr[eax+8],0xFFFFFFFF
mov dword ptr[eax+12],0xFFFFFFFF
adc dword ptr[eax],64h ;Hier passiert der Überlauf, das Problem ist das der gesamte Inhalt von dword ptr[eax] gelöscht wird
;ich hatte überlegt ob diese 4 DWORDs als ein großer Speicherbereich gesehen werden kann, damit der CPU diesen Überlauf ausgleicht indem er das nächste DWORD verändert und nicht das andere löscht | | |
|
|
|
 |
|
Nächstes Thema anzeigen
Vorheriges Thema anzeigen
Sie können Beiträge in dieses Forum schreiben. Sie können auf Beiträge in diesem Forum antworten. Sie können Ihre Beiträge in diesem Forum nicht bearbeiten. Sie können Ihre Beiträge in diesem Forum nicht löschen. Sie können an Umfragen in diesem Forum nicht mitmachen.
|
|
|
|
|