Problem mit 80bit Zahlen

Anfängerfragen zum Programmieren mit PureBasic.
- chris -
Beiträge: 195
Registriert: 24.08.2005 19:52
Wohnort: Stadtallendorf

Problem mit 80bit Zahlen

Beitrag von - chris - »

Hallo

Ich brauche für ein Programm 80bit Zahlen (Profilab TCP).

Byte 0-9: TX-Variable (extended float Format 80bit)
Byte 11 : Kanal-Adresse

Dazu wollte ich die Include "Procfpu80.pbi" verwenden.

http://forums.purebasic.com/german/view ... cfpu80.pbi

Jetzt habe ich aber festgestellt das einige Zahlen nicht richtig dargestellt werden:

Hier ein Testprogramm:

Code: Alles auswählen


XIncludeFile "Procfpu80.pbi"

Structure FPU80Bit
  Teil1.l : Teil2.l : Teil3.l
EndStructure

Define.FPU80Bit Var1

Convert$ = Space(255)

For n = 60 To 80
  Teststring1$ = Str(n)
  ValT(@Teststring1$, Var1)
  StrT(@Convert$, Var1)
  Debug Convert$
Next n

Debug ""

Teststring1$ = "42"
ValT(@Teststring1$, Var1)
StrT(@Convert$, Var1)
Debug Convert$

Code: Alles auswählen

60.000000000000000000
61.000000000000000000
62.000000000000000000
63.000000000000000000
6.4000000000000000000
6.5000000000000000000
6.6000000000000000000
6.7000000000000000000
6.8000000000000000000
6.9000000000000000000
70.000000000000000000
71.000000000000000000
72.000000000000000000
73.000000000000000000
74.000000000000000000
75.000000000000000000
76.000000000000000000
77.000000000000000000
78.000000000000000000
79.000000000000000000
80.000000000000000000

42.000000000000000000

PB v5.72 x86/x64
Windows 10 Pro 64bit
Benutzeravatar
Falko
Admin
Beiträge: 3535
Registriert: 29.08.2004 11:27
Computerausstattung: PC: MSI-Z590-GC; 32GB-DDR4, ICore9; 2TB M2 + 2x3TB-SATA2 HDD; Intel ICore9 @ 3600MHZ (Win11 Pro. 64-Bit),
Acer Aspire E15 (Win11 Home X64). Purebasic LTS 6.11b1
HP255G8 Notebook @AMD Ryzen 5 5500U with Radeon Graphics 2.10 GHz 3.4GHz, 32GB_RAM, 3TB_SSD (Win11 Pro 64-Bit)
Kontaktdaten:

Re: Problem mit 80bit Zahlen

Beitrag von Falko »

Komisch,
bei mir unter PB 4.61b1 läuft diese Procfpu80.pbi überhaupt nicht.
Egal, ob ich deinen Code oder die PBI selbst ausführe, wird immer
folgende Fehlermeldung angezeigt.
PB4.61b1-IDE hat geschrieben:Zeile1 - Ungültiger Speicherzugriff. (Schreibfehler an der Adresse 4390338)
Gruß,
Falko
Bild
Win11 Pro 64-Bit, PB_6.11b1
Benutzeravatar
Helle
Beiträge: 566
Registriert: 11.11.2004 16:13
Wohnort: Magdeburg

Re: Problem mit 80bit Zahlen

Beitrag von Helle »

@ - chris - : Leichenschänder :mrgreen: ! Die Komma-Verschiebung hat es zu gut gemeint (führende nicht relevante Stellen). Nimm bitte mal die StrT()-Procedure von unten.
@ Falko: Hmmm, bei mir läufts mit PB 4.60 (x86); in einer VM. Zum testen deshalb hier nochmal der komplette Code:

Code: Alles auswählen

Procedure StrT(Variable1, Variable2)
;- 32-Bit-Windows
;- Dient nur zur Bildschirm-Ausgabe, hat mit Berechnungen nichts zu tun! 
;- Der 10-Byte-Float-Wert von Variable2 wird in einen String konvertiert 
;- Benötigt CPU mit SSE2!
;- Intern:
;- Fall 1: 0.00000000...        bis 0.999999999999999999999999999999
;- Fall 2: 18446744073709551616 bis ...
;- Fall 3: 1.0                  bis 18446744073709551615 (2^64-1)
;- Werte gelten auch für negative Zahlen 
;- Werte-Bereich: 80-Bit      : 2^-16382 ... 2^16384; Zifferngenau bis ca. 1.084x10^-19
;- Zum Vergleich: Single-Float: 2^-126   ... 2^128;      "     "    "   "  1.192x10^-7  
;-                Double-Float: 2^-1022  ... 2^1024;     "     "    "   "  2.220x10^-16 

  !mov eax,[p.v_Variable1]
  !mov edx,[p.v_Variable2]
  !pushad
  !mov ebp,eax
  !xor eax,eax
  !mov ebx,eax
  !mov [StringZ],eax 
!@@:
  !mov dword[String1+ebx],eax
  !add ebx,4
  !cmp ebx,1024
  !jb @b

  !mov edi,edx          ;Zeiger auf umzuwandelnden String
;-------- Vorzeichen und Exponent 
  !mov cx,[edi+8]       ;Vorzeichen und Exponent            
  !and cx,cx            ;Test, ob MSB (Bit15) gesetzt ist
  !jns @f               ;nein, Vorzeichen ist plus

  !mov [StringA],2dh     ;"-"
  !mov [StringZ],1
  !and cx,7fffh         ;Vorzeichen-Bit löschen
!@@:
  !sub cx,16383         ;Bias ("Versatz") subtrahieren, um "echten" Exponenten (auf Zweier-Basis) zu erhalten

;-------- Die 64-Bit-Mantisse einlesen  
  !mov eax,[edi+4]      ;Mantisse High-Anteil
  !mov ebx,[edi]        ;Mantisse Low-Anteil
 
  !mov dword[Mantisse],ebx
  !mov dword[Mantisse+4],eax
  
;-------- Auswertung  
;-------- Test,ob Exponent = -16383, d.h. von FPU als Null zurückgegeben 
  !cmp cx,-16383        ;Exponent
  !jne @f
  !or eax,eax           ;Mantisse High-Anteil  da der Sinn nicht die Exponential-Darstellung ist könnte auch hier abgebrochen werden
  !jnz @f               ;d.h. Wert auch Null  
  !or ebx,ebx
  !jnz @f

  !mov dword[StringA],20302e30h   ;"0.0 "
  !mov edi,ebp          ;Pointer auf String, in den geschrieben werden soll
  !mov ebx,4            ;4 Bytes Ausgabe
  !jmp l_merker_ende
   
;------------------------------------------------
!@@:
  !mov [Trenner],63
  !sub [Trenner],cx
  !and cx,cx
  !jns l_wnnx           ;Exponent nicht negativ

;-------- Exponent < 0 
  !mov esi,[StringZ]
  !mov word[StringA+esi],2e30h    ;"0."
  !add [StringZ],2
  
  !mov [F],5
  !mov [Merker],1
  !jmp l_ziffern_bestimmen 

;-------- Exponent >= 0 
WNNX:  
  !cmp [Trenner],0
  !jge @f
  !neg [Trenner]
  !mov [F],2            ;wenn Trenner kleiner Null wird mit 2 multipliziert!!!
  !mov [Merker],2
  !jmp l_ziffern_bestimmen 

!@@:
  !mov [F],5
  !mov [Merker],3

;-------- "String" erzeugen
Ziffern_bestimmen:
  !movq xmm0,[Mantisse] ;Ursprungswert laden
  !lea esi,[Teiler]     ;Beginn der Zehner-Potenzen
  !lea edi,[String1]    ;zum Abspeichern
  !add edi,1004
  !mov ecx,19           ;noch 19 Bytes, das 1.wird vor der Schleife gesetzt (kann nur 0 oder 1 sein)

  !movmskpd eax,xmm0    ;Test auf MSB
  !test eax,1           ;testet Bit 63!
  !jz l_w11             ;nicht gesetzt, Mantisse kleiner als 9223372036854775808 (8000000000000000h)

;- Test ob Mantisse < 10000000000000000000 
  !movq xmm1,[esi]
  !psubq xmm0,xmm1
  !movmskpd eax,xmm0    ;Test auf MSB
  !test eax,1           ;testet Bit 63!
  !jnz @f               ;kleiner als 10000000000000000000

  !mov byte[edi],1      ;"1" setzen an höchste Stelle 
  !movq [Mantisse],xmm0 ;neuer Mantissen-Wert 
  !jmp l_w11

!@@:
  !movq xmm0,[Mantisse] ;alten Mantissen-Wert wiederherstellen
 
;--------------------------------
W11:
  !inc edi              ;eine Stelle im "String" weiter
  !add esi,8
W1:
  !movq xmm1,[esi]      ;(neue) Zehner-Potenz laden
!@@:
  !psubq xmm0,xmm1      ;Mantisse minus Teiler
  !movmskpd eax,xmm0
  !test eax,1
  !jnz @f

  !movq [Mantisse],xmm0 
  !inc byte[edi]
  !jmp @b

!@@:
  !movq xmm0,[Mantisse] 
  !add esi,8 
  !inc edi
  !dec ecx
  !jnz l_w1

;- Komma ist hier auch Länge Ausgangs-String
  !mov dword[Komma],20
  !mov [Len],20

  !cmp [Trenner],0
  !je l_trenner_0

  !mov ecx,1
Schleife_fuer_4:
;------- wenn F=5 Ausgangswert umkopieren für 5=4+1
  !cmp [F],5
  !jne l_w2_1
   
  !lea edi,[String1]
  !add edi,1020
  !lea esi,[String2]
  !add esi,1020
  !mov ebx,[Len] 
  !shr ebx,2
  !inc ebx              ;genug Reserve!
!@@:
  !mov eax,[edi]
  !mov [esi],eax
  !sub edi,4
  !sub esi,4
  !dec ebx
  !jnz @b
W2_1:

;-------
  !mov edx,2            ;Zähler für x4 
W1_1:                   ;für Schleife x4 
  !lea edi,[String1]
  !add edi,1023         ;Ende des Strings
  !mov ebx,[Len]
  !xor ah,ah
W0_1:                   ;für Schleife x2
  !mov al,[edi]
  !add al,al
  !add al,ah

  !xor ah,ah
  !cmp al,10
  !jb l_nicht_10
  !sub al,10
  !inc ah

  !cmp ebx,1
  !jne @f
  !inc [Len]
  !inc ebx
!@@: 

Nicht_10:
  !mov [edi],al
  !dec edi
  !dec ebx
  !jnz l_w0_1

  !cmp [F],2
  !je l_nur_2           ;nur "Multiplikation" mit 2

  !dec edx
  !jnz l_w1_1           ;zweiter Durchlauf für 2+2

;- hier 4+1 als "Multiplikation" mit 5
  !xor ah,ah
  !mov ebx,[Len]
  !lea edi,[String1]
  !add edi,1023
  !lea esi,[String2]
  !add esi,1023
W3_1:                
  !mov al,[edi]
  !add al,[esi]
  !add al,ah

  !xor ah,ah
  !cmp al,10
  !jb l_nicht_10_1
  !sub al,10
  !inc ah
  
  !cmp ebx,1
  !jne @f
  !inc [Len]
  !inc ebx
!@@: 

Nicht_10_1:
  !mov [edi],al
  !dec edi
  !dec esi
  !dec ebx
  !jnz l_w3_1

Nur_2:
  !cmp byte[edi+1],1
  !ja @f
  !dec [Komma]
!@@:
  !inc ecx
  !cmp cx,[Trenner]
  !jbe l_schleife_fuer_4

  !cmp byte[edi+1],2   ;wenn 2 oder grösser noch eine Stelle mehr  
  !jb @f
  !dec [Komma]
!@@:

;----------------------------------  
Trenner_0:
  !mov edi,ebp          ;Pointer auf String, in den geschrieben werden soll

  !cmp [Merker],1       ;"0."
  !jne l_ob_merker2

;-------- Merker = 1 
  !movzx ecx,[Trenner] 
  !mov ebx,[StringZ]  
  !sub ecx,[Len]
  !jz l_null_1   
 
!@@:
  !mov byte[StringA+ebx],30h
  !inc ebx
  !dec ecx
  !jnz @b     
    
Null_1:
  !lea esi,[String1]
  !add esi,1024
  !mov ecx,20
  !sub esi,[Len]
!@@:
  !mov al,[esi]
  !add al,30h
  !mov [StringA+ebx],al
  !inc esi
  !inc ebx
  !dec ecx
  !jnz @b
   
  !jmp l_merker_ende 

Ob_Merker2:
  !cmp [Merker],2
  !jne l_merker3

;-------- Merker = 2  
Merker2: 
  !mov ebx,[StringZ]    ;Zeiger in StringA
  !lea esi,[String1]       
  !add esi,1024
  !mov ecx,20
  !sub esi,[Len]
!@@:
  !mov al,[esi]
  !add al,30h
  !mov [StringA+ebx],al
  !inc esi
  !inc ebx
  !dec ecx
  !jnz @b

  !mov ecx,[Len]
  !sub ecx,ebx
  !jz l_null_2

!@@:
  !mov byte[StringA+ebx],30h
  !inc ebx
  !dec ecx
  !jnz @b     
 
Null_2: 
  !jmp l_merker_ende 

;-------- Merker = 3
Merker3:
  !mov ebx,[StringZ]
  !lea esi,[String1]
  !add esi,1024
  !sub esi,[Len]
  !mov ecx,[Komma]
!@@:
  !mov al,[esi]
  !add al,30h
  !mov [StringA+ebx],al
  !inc esi
  !inc ebx
  !dec ecx
  !js @f
  !jnz @b
!@@:
  !mov ecx,20
  !sub ecx,[Komma]
  !jz l_merker_ende
  !mov [StringA+ebx],2eh
  !inc ebx
!@@:
  !mov al,[esi]
  !add al,30h
  !mov [StringA+ebx],al
  !inc esi
  !inc ebx
  !dec ecx
  !jnz @b

Merker_Ende:
  !lea esi,[StringA]
  !mov ecx,ebx
  !cld 
  !rep movsb 
  
  !mov byte[edi],0      ;für das String-Ende das Zero-Byte setzen
  !popad
ProcedureReturn  

End 
 
!section '.data' Data readable writeable

!String1   RB 1024      ;eigentlicher Berechnungs-String; für Extrem-Werte ALLE String-Bezüge vergrössern! 
!String2   RB 1024      ;Hilfs-String für die Multiplikation mit 5 = 4 + 1
!StringA   RB 256       ;256 Byte für String-Ausgabe
!Mantisse  DQ 0
!Teiler    DQ 10000000000000000000
!          DQ 1000000000000000000
!          DQ 100000000000000000
!          DQ 10000000000000000
!          DQ 1000000000000000
!          DQ 100000000000000
!          DQ 10000000000000
!          DQ 1000000000000
!          DQ 100000000000
!          DQ 10000000000
!          DQ 1000000000
!          DQ 100000000
!          DQ 10000000
!          DQ 1000000
!          DQ 100000
!          DQ 10000
!          DQ 1000
!          DQ 100
!          DQ 10
!          DQ 1   
 
!F         DD 0
!Komma     DD 0
!Merker    DD 0
!StringZ   DD 0         ;Zeiger in String  StringZähler
!Len       DD 0

!Trenner   DW 0

EndProcedure 
;-------------------------------------------------------------------------

Procedure ValT(Variable1, Variable2)   ;Variable1 = Zeiger auf String, Variable2 = Ausgabe
  !mov eax,[p.v_Variable1]
  !mov edx,[p.v_Variable2]
  !pushad
  !mov esi,eax
  !mov edi,edx 
  !xor eax,eax
  !mov ebx,eax
  !mov ecx,eax
  !mov [ManVorzeichen],eax
  !mov [ExpVorzeichen],eax
  !mov [Dezimalpunkt],eax
        
  !mov al,[esi]
  !cmp al,'-'
  !je l_minus_vorzeichen
  !cmp al,'+'                          ;Test auf pos. Vorzeichen erstmal drinlassen
  !je l_plus_vorzeichen
  !jmp l_vorzeichen_ende
Minus_Vorzeichen:
  !inc [ManVorzeichen]
Plus_Vorzeichen:
  !inc esi
  !mov al,[esi]
Vorzeichen_Ende:
  !fldz
Mantisse_Lesen:
  !cmp al,'E'
  !je l_exponent
  !cmp al,'e'
  !je l_exponent
  !cmp al,'.'
  !je l_dezimal_punkt
  !xor al,'0'
  !cmp al,9
  !ja l_ziffern_ende
  !mov [Temp],eax
  !fmul [Zehner]
  !fiadd word[Temp]
  !inc ebx
  !jmp l_kein_punkt
Dezimal_Punkt:
  !cmp [Dezimalpunkt],0
  !jne l_ziffern_ende
  !mov [Dezimalpunkt],ebx
Kein_Punkt:
  !inc esi
  !mov al,[esi]
  !jmp l_mantisse_lesen
Exponent:
  !inc esi
  !mov al,[esi]
  !cmp al,'-'
  !je l_minus_exponent_vorzeichen
  !cmp al,'+'
  !je l_plus_exponent_vorzeichen
  !jmp l_exponent_lesen
Minus_Exponent_Vorzeichen:
  !inc [ExpVorzeichen]
Plus_Exponent_Vorzeichen:
  !inc esi
  !mov al,[esi]
Exponent_Lesen:
  !xor al,'0'
  !cmp al,9
  !ja l_ziffern_ende
  !lea ecx,[ecx*4+ecx]
  !lea ecx,[ecx*2+eax]
  !inc esi
  !mov al,[esi]
  !jmp l_exponent_lesen
Ziffern_Ende:
  !cmp [ExpVorzeichen],0
  !je l_exponent_fertig
  !neg ecx
Exponent_Fertig:
  !mov eax,[Dezimalpunkt]
  !or eax,eax
  !je l_kein_dezimalpunkt
  !sub ebx,eax
  !sub ecx,ebx
Kein_Dezimalpunkt:
  !or ecx,ecx
  !je l_kein_exponent
  !mov eax,ecx
  !cmp eax,0
  !jge l_exponent_vorzeichen_ok
  !neg eax
Exponent_Vorzeichen_Ok:
  !fld1
  !mov dl,al
  !and edx,0Fh
  !je l_groesserer_exponent
  !lea edx,dword[edx+edx*4]
  !fld tword [edx*2+Zehner_1-10]
  !fmulp st1,st
Groesserer_Exponent:
  !mov dl,al
  !shr dl,4
  !and edx,0Fh
  !je l_noch_groesserer_exponent
  !lea edx,dword[edx+edx*4]
  !fld tword [edx*2+Zehner_16-10]
  !fmulp st1,st
Noch_Groesserer_Exponent:
  !mov dl,ah
  !and edx,1Fh
  !je l_exponent_vorzeichen
  !lea edx,dword[edx+edx*4]
  !fld tword[edx*2+Zehner_256-10]
  !fmulp st1,st
Exponent_Vorzeichen:
  !cmp ecx,0
  !jge l_positiver_exponent
  !fdivp st1,st
  !jmp l_kein_exponent
Positiver_Exponent:
  !fmulp st1,st
Kein_Exponent:
  !cmp [ManVorzeichen],0
  !je l_fertig
  !fchs
Fertig:
  !fstp tword[edi]
  !popad
ProcedureReturn

!section '.data' Data readable writeable

!ManVorzeichen dd 0
!ExpVorzeichen dd 0
!Dezimalpunkt  dd 0
!Temp          dd 0
!Zehner        dq 10.0
!Zehner_1      dt 1.0e1
!              dt 1.0e2
!              dt 1.0e3
!              dt 1.0e4
!              dt 1.0e5
!              dt 1.0e6
!              dt 1.0e7
!              dt 1.0e8
!              dt 1.0e9
!              dt 1.0e10
!              dt 1.0e11
!              dt 1.0e12
!              dt 1.0e13
!              dt 1.0e14
!              dt 1.0e15
!Zehner_16     dt 1.0e16
!              dt 1.0e32
!              dt 1.0e48
!              dt 1.0e64
!              dt 1.0e80
!              dt 1.0e96
!              dt 1.0e112
!              dt 1.0e128
!              dt 1.0e144
!              dt 1.0e160
!              dt 1.0e176
!              dt 1.0e192
!              dt 1.0e208
!              dt 1.0e224
!              dt 1.0e240
!Zehner_256    dt 1.0e256
!              dt 1.0e512
!              dt 1.0e768
!              dt 1.0e1024
!              dt 1.0e1280
!              dt 1.0e1536
!              dt 1.0e1792
!              dt 1.0e2048
!              dt 1.0e2304
!              dt 1.0e2560
!              dt 1.0e2816
!              dt 1.0e3072
!              dt 1.0e3328
!              dt 1.0e3584
!              dt 1.0e3840
!              dt 1.0e4096
!              dt 1.0e4352
!              dt 1.0e4608
!              dt 1.0e4864                                     

EndProcedure           
;-------------------------------------------------------------------------


;-------- ARITHMETISCHE FUNKTIONEN ---------------------------------------
;-------- Addition ---------- Variable3 = Variable1 + Variable2 ----------
Procedure AddT(Variable1, Variable2, Variable3)
  !fninit                       
  !mov esi,[p.v_Variable1]
  !fld tword[esi]           
  !mov esi,[p.v_Variable2] 
  !fld tword[esi] 
  !faddp st1,st0
  !mov esi,[p.v_Variable3]
  !fstp tword[esi]      ;Ergebnis
EndProcedure
;-------------------------------------------------------------------------

;-------- Division ---------- Variable3 = Variable1 / Variable2 ----------
Procedure DivT(Variable1, Variable2, Variable3)
  !fninit                       
  !mov esi,[p.v_Variable1]
  !fld tword[esi]           
  !mov esi,[p.v_Variable2] 
  !fld tword[esi] 
  !fdivp st1,st0
  !mov esi,[p.v_Variable3]
  !fstp tword[esi]      ;Ergebnis
EndProcedure
;-------------------------------------------------------------------------

;-------- Multiplikation ---- Variable3 = Variable1 * Variable2 ----------
Procedure MulT(Variable1, Variable2, Variable3)
  !fninit                       
  !mov esi,[p.v_Variable1]
  !fld tword[esi]           
  !mov esi,[p.v_Variable2]   
  !fld tword[esi] 
  !fmulp st1,st0
  !mov esi,[p.v_Variable3]
  !fstp tword[esi]      ;Ergebnis
EndProcedure
;-------------------------------------------------------------------------

;-------- Quadratwurzel ----- Variable2 = Variable1 ^ 0.5 ----------------
Procedure SqrT(Variable1, Variable2)
  !fninit                       
  !mov esi,[p.v_Variable1] 
  !fld tword[esi] 
  !fsqrt
  !mov esi,[p.v_Variable2]
  !fstp tword[esi]      ;Ergebnis
EndProcedure
;-------------------------------------------------------------------------

;-------- Subtraktion ------- Variable3 = Variable1 - Variable2 ----------
Procedure SubT(Variable1, Variable2, Variable3)
  !fninit                       
  !mov esi,[p.v_Variable1]
  !fld tword[esi]           
  !mov esi,[p.v_Variable2] 
  !fld tword[esi] 
  !fsubp st1,st0
  !mov esi,[p.v_Variable3]
  !fstp tword[esi]      ;Ergebnis
EndProcedure
;-------------------------------------------------------------------------


;-------- WINKELFUNKTIONEN -----------------------------------------------
;-------- ArcusCosinus ------ Variable2 = ACos(Variable1(rad)) -----------
Procedure ACosT(Variable1, Variable2)
  !fninit                       
  !fld1
  !mov esi,[p.v_Variable1] 
  !fld tword[esi] 
  !fst st2
  !fmul st0,st0
  !fsubp
  !fsqrt
  !fxch
  !fpatan
  !mov esi,[p.v_Variable2] 
  !fstp tword[esi]      ;Ergebnis
  !fdecstp
  !ffree st0
EndProcedure

;-------- ArcusCotangens ---- Variable2 = ACot(Variable1(rad)) -----------
Procedure ACotT(Variable1, Variable2)  ;Pi/2 - arctan(x)
  !fninit                       
  !fldpi
  !fld1
  !fld1
  !faddp
  !fdivp
  !mov esi,[p.v_Variable1]   
  !fld tword[esi] 
  !fld1
  !fpatan
  !fsubp
  !mov esi,[p.v_Variable2] 
  !fstp tword[esi]      ;Ergebnis
EndProcedure

;-------- ArcusSinus -------- Variable2 = ASin(Variable1(rad)) -----------
Procedure ASinT(Variable1, Variable2)
  !fninit                       
  !fld1
  !mov esi,[p.v_Variable1]   
  !fld tword[esi] 
  !fst st2
  !fmul st0,st0
  !fsubp
  !fsqrt
  !fpatan
  !mov esi,[p.v_Variable2] 
  !fstp tword[esi]      ;Ergebnis
  !fdecstp              ;Stack-Bereinigung, TOS ist danach ST(0)
  !ffree st0            ;ST(0) als leer deklarieren
EndProcedure

;-------- ArcusTangens ------ Variable2 = ATan(Variable1(rad)) -----------
Procedure ATanT(Variable1, Variable2)
  !fninit                       
  !mov esi,[p.v_Variable1]   
  !fld tword[esi] 
  !fld1
  !fpatan
  !mov esi,[p.v_Variable2] 
  !fstp tword[esi]      ;Ergebnis
EndProcedure

;-------- Cosinus ----------- Variable2 = Cos(Variable1(rad)) ------------
Procedure CosT(Variable1, Variable2)
  !fninit                       
  !mov esi,[p.v_Variable1] 
  !fld tword[esi] 
  !fcos
  !mov esi,[p.v_Variable2] 
  !fstp tword[esi]      ;Ergebnis
EndProcedure
;-------------------------------------------------------------------------

;-------- Cotangens --------- Variable2 = Cot(Variable1(rad)) ------------
Procedure CotT(Variable1, Variable2)
  !fninit                       
  !mov esi,[p.v_Variable1]
  !fld tword[esi] 
  !fptan
  !fdivrp st1,st0
  !mov esi,[p.v_Variable2]
  !fstp tword[esi]      ;Ergebnis
EndProcedure
;-------------------------------------------------------------------------

;-------- Sinus ------------- Variable2 = Sin(Variable1(rad)) ------------
Procedure SinT(Variable1, Variable2)
  !fninit                       
  !mov esi,[p.v_Variable1] 
  !fld tword[esi] 
  !fsin
  !mov esi,[p.v_Variable2]
  !fstp tword[esi]      ;Ergebnis
EndProcedure
;-------------------------------------------------------------------------

;-------- Tangens ----------- Variable2 = Tan(Variable1(rad)) ------------
Procedure TanT(Variable1, Variable2)
  !fninit                       
  !mov esi,[p.v_Variable1] 
  !fld tword[esi] 
  !fptan
  !fdivp st1,st0
  !mov esi,[p.v_Variable2]
  !fstp tword[esi]      ;Ergebnis
EndProcedure
;-------------------------------------------------------------------------


;-------- ERWEITERTE FUNKTIONEN ------------------------------------------
;-------- Pow --------------- Variable3 = Variable1 ^ Variable2 ----------
Procedure PowT(Variable1, Variable2, Variable3)
  !fninit                       
  !mov esi,[p.v_Variable2]
  !fld tword[esi]           
  !mov esi,[p.v_Variable1] 
  !fld tword[esi]
  !fyl2x
  !fld st0
  !frndint
  !fsub st1,st0
  !fxch st1
  !f2xm1
  !fld1
  !faddp st1,st0
  !fscale
  !fstp st1
  !mov esi,[p.v_Variable3]
  !fstp tword[esi]      ;Ergebnis
EndProcedure
;-------------------------------------------------------------------------


;-------- KONSTANTEN -----------------------------------------------------
;-------- L0 ---------------- Variable1 = 0.0 ----------------------------
Procedure L0T(Variable1)
  !fninit                       
  !fldz                 ;00000000000000000000h = 0.0
  !mov esi,[p.v_Variable1]
  !fstp tword[esi]      ;Ergebnis
EndProcedure
;-------------------------------------------------------------------------

;-------- L1 ---------------- Variable1 = 1.0 ----------------------------
Procedure L1T(Variable1)
  !fninit                       
  !fld1                 ;3FFF8000000000000000h = 1.0
  !mov esi,[p.v_Variable1]
  !fstp tword[esi]      ;Ergebnis
EndProcedure
;-------------------------------------------------------------------------

;-------- Ld(10) ------------ Variable1 = Ld(10), 2 ^ Variable1 =10.0 ----
Procedure Ld10T(Variable1)
  !fninit                       
  !fldl2t               ;4000D49A784BCD1B8AFEh = 3.3219280948873623478
  !mov esi,[p.v_Variable1]
  !fstp tword[esi]      ;Ergebnis
EndProcedure
;-------------------------------------------------------------------------

;-------- Ld(e) ------------- Variable1 = Ld(e), 2 ^ Variable1 = e -------
Procedure LdeT(Variable1)
  !fninit                       
  !fldl2e               ;3FFFB8AA3B295C17F0BCh = 1.4426950408889634073
  !mov esi,[p.v_Variable1]
  !fstp tword[esi]      ;Ergebnis
EndProcedure
;-------------------------------------------------------------------------

;-------- Lg(2) ------------- Variable1 = Lg(2), 10 ^ Variable1 = 2.0 ----
Procedure Lg2T(Variable1)
  !fninit                       
  !fldlg2               ;3FFFB17217F7D1CF79ACh = 0.301029995663981195198
  !mov esi,[p.v_Variable1]
  !fstp tword[esi]      ;Ergebnis
EndProcedure
;-------------------------------------------------------------------------

;-------- Ln(2) ------------- Variable1 = Ln(2), e ^ Variable1 = 2.0 -----
Procedure Ln2T(Variable1)
  !fninit                       
  !fldln2               ;3FFD9A209A84FBCFF799h = 0.6931471805599453094
  !mov esi,[p.v_Variable1]
  !fstp tword[esi]      ;Ergebnis
EndProcedure
;-------------------------------------------------------------------------

;-------- Pi ---------------- Variable1 = Pi -----------------------------
Procedure PiT(Variable1)
  !fninit                       
  !fldpi                ;4000C90FDAA22168C335h = 3.1415926535897932385
  !mov esi,[p.v_Variable1]
  !fstp tword[esi]      ;Ergebnis
EndProcedure
;-------------------------------------------------------------------------


;-------- SONSTIGES ------------------------------------------------------
;-------- Change ------------ Vertauscht die Werte der beiden Variablen --
Procedure ChangeT(Variable1, Variable2)
  !fninit
  !mov esi,[p.v_Variable1]
  !fld tword[esi]
  !mov edi,[p.v_Variable2]
  !fld tword[edi]
  !fstp tword[esi]
  !fstp tword[edi]
EndProcedure
;-------------------------------------------------------------------------

;-------- Compare ----------- Vergleicht Variable1 mit Variable2 ---------
Procedure CompT(Variable1, Variable2)
  !fninit
  !mov esi,[p.v_Variable2]
  !fld tword[esi]
  !mov esi,[p.v_Variable1]
  !fld tword[esi]
  !fcompp
  !fstsw ax             ;nicht fnstsw!
  !sahf
  !jne @f               ;nicht gleich
  !xor eax,eax
  ProcedureReturn       ;Rückgabewert=0 für Variable1 gleich Variable2
!@@:
  !jnc @f               ;nicht kleiner 
  !mov eax,1
  ProcedureReturn       ;Rückgabewert=1 für Variable1 kleiner als Variable2
!@@:
  !mov eax,2
  ProcedureReturn       ;Rückgabewert=2 für Variable1 grösser als Variable2
EndProcedure
;-------------------------------------------------------------------------

;-------- Copy -------------- kopiert Variable2 in Variable1 -------------
Procedure CopyT(Variable1, Variable2)
  !fninit
  !mov esi,[p.v_Variable2]
  !fld tword[esi]
  !mov esi,[p.v_Variable1]
  !fstp tword[esi]
EndProcedure
;-------------------------------------------------------------------------




;- Var1, Var2 und Var3 PB als 10-Byte-Variable unterjubeln
Structure FPU80Bit
 Teil1.l : Teil2.l : Teil3.l ;jeweils 12 Byte reservieren, von Teil3 werden nur 2 Bytes genutzt
EndStructure

Define.FPU80Bit Var1, Var2, Var3  ;dem Kind einen Namen geben

;- benötigten String für die Bildschirm-Ausgabe definieren
Global Convert$ = Space(255) ;frei wählbarer Name für die Ausgabe, Grösse je nach Bedarf (was man vor hat)

;- die 80-Bit-Prozeduren laden  SIEHE OBEN!!!
;XIncludeFile "Procfpu80.pbi" ;oder nur benötigte Prozeduren einfügen

;- Var1 und Var2 mit 10-Byte-Floating-Point-Werten belegen
Teststring1$ = "0.75"
ValT(@Teststring1$, Var1)
Teststring2$ = "11"
ValT(@Teststring2$, Var2)

;- Ab hier Beispiele mit den beiden Variablen Var1 und Var2
;-------- Beispiel ArcusCosinus(0.75)
ACosT(Var1, Var3)            ;Var3 = ACos(Var1)
StrT(@Convert$, Var3)        ;liefert für die Bildschirm-Ausgabe das Ergebnis als String (Convert$)
MessageRequester("Berechnungsbeispiel ACos(0.75)","Single-Float:   "+StrF(ACos(0.75),20)+#LFCR$+"Double-Float:  "+StrD(ACos(0.75),20)+#LFCR$+"80-Bit-Float:    "+Convert$+#LFCR$+"Windows-R.:   0.72273424781341561117837735264133")

;-------- Beispiel ArcusCotangens(0.75)
ACotT(Var1, Var3)            ;Var3 = ACot(Var1)
StrT(@Convert$, Var3)        ;liefert für die Bildschirm-Ausgabe das Ergebnis als String (Convert$)
MessageRequester("Berechnungsbeispiel ACot(0.75)","Single-Float:   "+StrF((#PI/2)-ATan(0.75),20)+#LFCR$+"Double-Float:  "+StrD((#PI/2)-ATan(0.75),20)+#LFCR$+"80-Bit-Float:    "+Convert$+#LFCR$+"Windows-R.:   0.92729521800161223242851246292243")
 
;-------- Beispiel Addition 0.75 + 11.0
AddT(Var1, Var2, Var3)       ;Var3 = Var1 + Var2
StrT(@Convert$, Var3)        ;liefert für die Bildschirm-Ausgabe das Ergebnis als String (Convert$)
MessageRequester("Berechnungsbeispiel Addition 0.75+11.0","Single-Float:   "+StrF(0.75+11.0,20)+#LFCR$+"Double-Float:  "+StrD(0.75+11.0,20)+#LFCR$+"80-Bit-Float:    "+Convert$+#LFCR$+"Windows-R.:   11.75")
 
;-------- Beispiel ArcusSinus(0.75)
ASinT(Var1, Var3)            ;Var3 = ASin(Var1)
StrT(@Convert$, Var3)        ;liefert für die Bildschirm-Ausgabe das Ergebnis als String (Convert$)
MessageRequester("Berechnungsbeispiel ASin(0.75)","Single-Float:   "+StrF(ASin(0.75),20)+#LFCR$+"Double-Float:  "+StrD(ASin(0.75),20)+#LFCR$+"80-Bit-Float:    "+Convert$+#LFCR$+"Windows-R.:   0.84806207898148100805294433899842")

;-------- Beispiel ArcusTangens(0.75)
ATanT(Var1, Var3)            ;Var3 = ATan(Var1)
StrT(@Convert$, Var3)        ;liefert für die Bildschirm-Ausgabe das Ergebnis als String (Convert$)
MessageRequester("Berechnungsbeispiel ATan(0.75)","Single-Float:   "+StrF(ATan(0.75),20)+#LFCR$+"Double-Float:  "+StrD(ATan(0.75),20)+#LFCR$+"80-Bit-Float:    "+Convert$+#LFCR$+"Windows-R.:   0.64350110879328438680280922871732")

;-------- Beispiel Cosinus(0.75)
CosT(Var1, Var3)             ;Var3 = Cos(Var1)
StrT(@Convert$, Var3)        ;liefert für die Bildschirm-Ausgabe das Ergebnis als String (Convert$)
MessageRequester("Berechnungsbeispiel Cos(0.75)","Single-Float:   "+StrF(Cos(0.75),20)+#LFCR$+"Double-Float:  "+StrD(Cos(0.75),20)+#LFCR$+"80-Bit-Float:    "+Convert$+#LFCR$+"Windows-R.:   0.73168886887382088631183875300008")

;-------- Beispiel Cotangens(0.75)
CotT(Var1, Var3)             ;Var3 = Cot(Var1)
StrT(@Convert$, Var3)        ;liefert für die Bildschirm-Ausgabe das Ergebnis als String (Convert$)
MessageRequester("Berechnungsbeispiel Cot(0.75)","Single-Float:   "+StrF(1/Tan(0.75),20)+#LFCR$+"Double-Float:  "+StrD(1/Tan(0.75),20)+#LFCR$+"80-Bit-Float:    "+Convert$+#LFCR$+"Windows-R.:   1.0734261485493773587431645424435")

;-------- Beispiel Division 0.75 / 11.0
DivT(Var1, Var2, Var3)       ;Var3 = Var1 / Var2
StrT(@Convert$, Var3)        ;liefert für die Bildschirm-Ausgabe das Ergebnis als String (Convert$)
MessageRequester("Berechnungsbeispiel Division 0.75/11.0","Single-Float:   "+StrF(0.75/11.0,20)+#LFCR$+"Double-Float:  "+StrD(0.75/11.0,20)+#LFCR$+"80-Bit-Float:    "+Convert$+#LFCR$+"Windows-R.:   0.068181818181818181818181818181818")

;-------- Beispiel Multiplikation 0.75 * 11.0
MulT(Var1, Var2, Var3)       ;Var3 = Var1 * Var2
StrT(@Convert$, Var3)        ;liefert für die Bildschirm-Ausgabe das Ergebnis als String (Convert$)
MessageRequester("Berechnungsbeispiel Multiplikation 0.75*11.0","Single-Float:   "+StrF(0.75*11.0,20)+#LFCR$+"Double-Float:  "+StrD(0.75*11.0,20)+#LFCR$+"80-Bit-Float:    "+Convert$+#LFCR$+"Windows-R.:   8.25")

;-------- Beispiel Laden der Konstante Pi als Beispiel für alle Konstanten (s.Procfpu80.pbi)
PiT(Var3)                    ;Var3 = Pi
StrT(@Convert$, Var3)        ;liefert für die Bildschirm-Ausgabe DAS Ergebnis als String (Convert$)
MessageRequester("Beispiel Laden der Konstante Pi","Single-Float:   "+StrF(#PI,20)+#LFCR$+"Double-Float:  "+StrD(#PI,20)+#LFCR$+"80-Bit-Float:    "+Convert$+#LFCR$+"Windows-R.:   3.1415926535897932384626433832795")

;-------- Beispiel Potenzierung 0.75 ^ 11.0
Powt(Var1, Var2, Var3)       ;Var3 = Var1 ^ Var2
StrT(@Convert$, Var3)        ;liefert für die Bildschirm-Ausgabe das Ergebnis als String (Convert$)
MessageRequester("Berechnungsbeispiel Potenzierung 0.75^11.0","Single-Float:   "+StrF(Pow(0.75,11.0),20)+#LFCR$+"Double-Float:  "+StrD(Pow(0.75,11.0),20)+#LFCR$+"80-Bit-Float:    "+Convert$+#LFCR$+"Windows-R.:   0.0422351360321044921875")

;-------- Beispiel Sinus(0.75)
SinT(Var1, Var3)             ;Var3 = Sin(Var1)
StrT(@Convert$, Var3)        ;liefert für die Bildschirm-Ausgabe das Ergebnis als String (Convert$)
MessageRequester("Berechnungsbeispiel Sin(0.75)","Single-Float:   "+StrF(Sin(0.75),20)+#LFCR$+"Double-Float:  "+StrD(Sin(0.75),20)+#LFCR$+"80-Bit-Float:    "+Convert$+#LFCR$+"Windows-R.:   0.68163876002333416673324195277989")

;-------- Beispiel Quadratwurzel(0.75)
SqrT(Var1, Var3)             ;Var3 = Sqr(Var1)
StrT(@Convert$, Var3)        ;liefert für die Bildschirm-Ausgabe das Ergebnis als String (Convert$)
MessageRequester("Berechnungsbeispiel Sqr(0.75)","Single-Float:   "+StrF(Sqr(0.75),20)+#LFCR$+"Double-Float:  "+StrD(Sqr(0.75),20)+#LFCR$+"80-Bit-Float:    "+Convert$+#LFCR$+"Windows-R.:   0.86602540378443864676372317075294")

;-------- Beispiel Subtraktion 0.75 - 11.0
SubT(Var1, Var2, Var3)       ;Var3 = Var1 - Var2
StrT(@Convert$, Var3)        ;liefert für die Bildschirm-Ausgabe das Ergebnis als String (Convert$)
MessageRequester("Berechnungsbeispiel Subtraktion 0.75-11.0","Single-Float:   "+StrF(0.75-11.0,20)+#LFCR$+"Double-Float:  "+StrD(0.75-11.0,20)+#LFCR$+"80-Bit-Float:    "+Convert$+#LFCR$+"Windows-R.:   -10.25")

;-------- Beispiel Tangens(0.75)
TanT(Var1, Var3)             ;Var3 = Tan(Var1)
StrT(@Convert$, Var3)        ;liefert für die Bildschirm-Ausgabe das Ergebnis als String (Convert$)
MessageRequester("Berechnungsbeispiel Tan(0.75)","Single-Float:   "+StrF(Tan(0.75),20)+#LFCR$+"Double-Float:  "+StrD(Tan(0.75),20)+#LFCR$+"80-Bit-Float:    "+Convert$+#LFCR$+"Windows-R.:   0.93159645994407246116520275657394")

;-------- Beispiel Compare
If CompT(Var1, Var2) = 0
      MessageRequester("Compare","Var1 und Var2 sind gleich")
   ElseIf Compt(Var1, Var2) = 1
      MessageRequester("Compare","Var1 ist kleiner als Var2")
   ElseIf Compt(Var1, Var2) = 2
      MessageRequester("Compare","Var1 ist grösser als Var2")
EndIf

;-------- Beispiel Copy
CopyT(Var3, Var1)            ;kopiert Var1 in Var3
StrT(@Convert$, Var3)        ;liefert für die Bildschirm-Ausgabe das Ergebnis als String (Convert$)
MessageRequester("Beispiel für Copy", "Var3 hat jetzt den Wert " + Convert$)

;-------- Beispiel Change
ChangeT(Var1, Var2)          ;vertauscht Var1 und Var2
StrT(@Convert$, Var1)        ;liefert für die Bildschirm-Ausgabe das Ergebnis als String (Convert$)
MessageRequester("Beispiel für Change", "Var1 hat jetzt den Wert " + Convert$)
StrT(@Convert$, Var2)
MessageRequester("Beispiel für Change", "Var2 hat jetzt den Wert " + Convert$)

;-------- Beispiel Val
Teststring1$ = "0.19e4732"
ValT(@Teststring1$, Var1)
Teststring2$ = "0.11e4932"
ValT(@Teststring2$, Var2)
DivT(Var1, Var2, Var3)       ;Var3 = Var1 / Var2
StrT(@Convert$, Var3)        ;liefert für die Bildschirm-Ausgabe das Ergebnis als String (Convert$)
MessageRequester("Beispiel für Val", "Der Quotient der beiden Teststring-Werte beträgt " + Convert$)

End

Viel Spaß!
Helle
Benutzeravatar
Falko
Admin
Beiträge: 3535
Registriert: 29.08.2004 11:27
Computerausstattung: PC: MSI-Z590-GC; 32GB-DDR4, ICore9; 2TB M2 + 2x3TB-SATA2 HDD; Intel ICore9 @ 3600MHZ (Win11 Pro. 64-Bit),
Acer Aspire E15 (Win11 Home X64). Purebasic LTS 6.11b1
HP255G8 Notebook @AMD Ryzen 5 5500U with Radeon Graphics 2.10 GHz 3.4GHz, 32GB_RAM, 3TB_SSD (Win11 Pro 64-Bit)
Kontaktdaten:

Re: Problem mit 80bit Zahlen

Beitrag von Falko »

@Helle,
danke für dein neuen Beispielcode zum Testen.
Ich habe dein neues Beispiel einmal im wirklichen Leben von Win7-64Bit getestet und
nun auch mal unter Windows XP Mode . Letzteres läuft auch bei mir unter der virtuellen Umgebung.
Alle Messageboxen werden ausgegeben.

Unter Windows 7 - 64-Bit mit x86 kompiliert kommt wieder der berühmte Speicherzugriffsfehler ab
der ersten Zeile. Unter 64Bit werden natürlich Polink-Errors ausgegeben.

Gruß,
Falko
Bild
Win11 Pro 64-Bit, PB_6.11b1
- chris -
Beiträge: 195
Registriert: 24.08.2005 19:52
Wohnort: Stadtallendorf

Re: Problem mit 80bit Zahlen

Beitrag von - chris - »

Hallo

Bei mir funktioniert es, mit "PB4.60 x86" und "PB4.61 x86 beta1"
unter Windows 7 64 bit.

Mit "PB4.60 x64" bekomme ich Fehlermeldungen:

PureBasic.asm [1945]:
MP0
PureBasic.asm [145]: MP0 [15]:
pushad
error: illegal instruction.
Zuletzt geändert von - chris - am 17.03.2012 13:39, insgesamt 1-mal geändert.
PB v5.72 x86/x64
Windows 10 Pro 64bit
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: Problem mit 80bit Zahlen

Beitrag von ts-soft »

64-Bit kompiliert kann nicht gehen! 32-Bit kompiliert im ASCII-Modus ist das einzige, was fehlerfrei funktioniert.
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
- chris -
Beiträge: 195
Registriert: 24.08.2005 19:52
Wohnort: Stadtallendorf

Re: Problem mit 80bit Zahlen

Beitrag von - chris - »

Mit ASCII und Unicode kompiliert:

Code: Alles auswählen


EnableExplicit

XIncludeFile "Procfpu80.pbi"

Define *Var1, *Convert, *Teststring1
Define Convert$, Teststring1$, n.i

*Var1 = AllocateMemory(10)
If *Var1 = 0
  End
EndIf  

*Convert = AllocateMemory(1024)
If *Convert = 0
  End
EndIf

*Teststring1 = AllocateMemory(1024)
If *Teststring1 = 0
  End
EndIf  

For n = 60 To 80
  Teststring1$ = Str(n)
  PokeS(*Teststring1, Teststring1$, -1, #PB_Ascii)
  ValT(*Teststring1, *Var1)
  StrT(*Convert, *Var1)
  Convert$ = PeekS(*Convert, -1, #PB_Ascii)
  Debug Convert$
Next n

Debug ""

Teststring1$ = "42"
PokeS(*Teststring1, Teststring1$, -1, #PB_Ascii)

ValT(*Teststring1, *Var1)
StrT(*Convert, *Var1)

Convert$ = PeekS(*Convert, -1, #PB_Ascii)
Debug Convert$

Convert$ = RTrim(Convert$, "0")
Convert$ = RTrim(Convert$, ".")
Debug Convert$

FreeMemory(*Var1)
FreeMemory(*Convert)
FreeMemory(*Teststring1)

PB v5.72 x86/x64
Windows 10 Pro 64bit
Benutzeravatar
Falko
Admin
Beiträge: 3535
Registriert: 29.08.2004 11:27
Computerausstattung: PC: MSI-Z590-GC; 32GB-DDR4, ICore9; 2TB M2 + 2x3TB-SATA2 HDD; Intel ICore9 @ 3600MHZ (Win11 Pro. 64-Bit),
Acer Aspire E15 (Win11 Home X64). Purebasic LTS 6.11b1
HP255G8 Notebook @AMD Ryzen 5 5500U with Radeon Graphics 2.10 GHz 3.4GHz, 32GB_RAM, 3TB_SSD (Win11 Pro 64-Bit)
Kontaktdaten:

Re: Problem mit 80bit Zahlen

Beitrag von Falko »

64 Bit kompiliert hat geschrieben:---------------------------
PureBasic - Linker error
---------------------------
POLINK: error: Relocation type ADDR32 is invalid without /LARGEADDRESSAWARE:NO, for symbol '.data'.

POLINK: error: Relocation type ADDR32 is invalid without /LARGEADDRESSAWARE:NO, for symbol '.data'.

POLINK: error: Relocation type ADDR32 is invalid without /LARGEADDRESSAWARE:NO, for symbol '.data'.

POLINK: error: Relocation type ADDR32 is invalid without /LARGEADDRESSAWARE:NO, for symbol '.data'.

POLINK: error: Relocation type ADDR32 is invalid without /LARGEADDRESSAWARE:NO, for symbol '.data'.

POLINK: error: Relocation type ADDR32 is invalid without /LARGEADDRESSAWARE:NO, for symbol '.data'.

POLINK: error: Relocation type ADDR32 is invalid without /LARGEADDRESSAWARE:NO, for symbol '.data'.

POLINK: error: Relocation type ADDR32 is invalid without /LARGEADDRESSAWARE:NO, for symbol '.data'.

POLINK: error: Relocation type ADDR32 is invalid without /LARGEADDRESSAWARE:NO, for symbol '.data'.

POLINK: error: Relocation type ADDR32 is invalid without /LARGEADDRESSAWARE:NO, for symbol '.data'.

POLINK: error: Relocation type ADDR32 is invalid without /LARGEADDRESSAWARE:NO, for symbol '.data'.

POLINK: error: Relocation type ADDR32 is invalid without /LARGEADDRESSAWARE:NO, for symbol '.data'.


---------------------------
OK
---------------------------
Das kommt bei mir unter 64bit kompiliert aus.
Und beim 32Bit wird eben die Fehlermeldung wegen Speicherzugriff an einer bestimmten Adresse
bemängelt, wenn ich die PBI oder das letzte Testbeispiel lade. Warum das ab der ersten Adresse
so ist, weiß ich nicht. Kann sein, das es ein Bug in PB ist.
Komischerweise geht es unter den XP Mode in Windows 7.

Gruß,
Falko
Bild
Win11 Pro 64-Bit, PB_6.11b1
- chris -
Beiträge: 195
Registriert: 24.08.2005 19:52
Wohnort: Stadtallendorf

Re: Problem mit 80bit Zahlen

Beitrag von - chris - »

Das funktioniert jetzt auch unter 64bit:

Mit Linker-Option "/LARGEADDRESSAWARE:NO"

Code: Alles auswählen


Procedure StrT(Variable1, Variable2)
;- 32-Bit-Windows / 64-Bit-Windows
;- Dient nur zur Bildschirm-Ausgabe, hat mit Berechnungen nichts zu tun!
;- Der 10-Byte-Float-Wert von Variable2 wird in einen String konvertiert
;- Benötigt CPU mit SSE2!
;- Intern:
;- Fall 1: 0.00000000...        bis 0.999999999999999999999999999999
;- Fall 2: 18446744073709551616 bis ...
;- Fall 3: 1.0                  bis 18446744073709551615 (2^64-1)
;- Werte gelten auch für negative Zahlen
;- Werte-Bereich: 80-Bit      : 2^-16382 ... 2^16384; Zifferngenau bis ca. 1.084x10^-19
;- Zum Vergleich: Single-Float: 2^-126   ... 2^128;      "     "    "   "  1.192x10^-7 
;-                Double-Float: 2^-1022  ... 2^1024;     "     "    "   "  2.220x10^-16

  !mov eax,[p.v_Variable1]
  !mov edx,[p.v_Variable2]
  
  ;!pushad
  !push rax
  !push rcx
  !push rdx
  !push rbx
  !push rsp
  !push rbp
  !push rsi
  !push rdi
  
  !mov ebp,eax
  !xor eax,eax
  !mov ebx,eax
  !mov [StringZ],eax
!@@:
  !mov dword[String1+ebx],eax
  !add ebx,4
  !cmp ebx,1024
  !jb @b

  !mov edi,edx          ;Zeiger auf umzuwandelnden String
;-------- Vorzeichen und Exponent
  !mov cx,[edi+8]       ;Vorzeichen und Exponent           
  !and cx,cx            ;Test, ob MSB (Bit15) gesetzt ist
  !jns @f               ;nein, Vorzeichen ist plus

  !mov [StringA],2dh     ;"-"
  !mov [StringZ],1
  !and cx,7fffh         ;Vorzeichen-Bit löschen
!@@:
  !sub cx,16383         ;Bias ("Versatz") subtrahieren, um "echten" Exponenten (auf Zweier-Basis) zu erhalten

;-------- Die 64-Bit-Mantisse einlesen 
  !mov eax,[edi+4]      ;Mantisse High-Anteil
  !mov ebx,[edi]        ;Mantisse Low-Anteil
 
  !mov dword[Mantisse],ebx
  !mov dword[Mantisse+4],eax
 
;-------- Auswertung 
;-------- Test,ob Exponent = -16383, d.h. von FPU als Null zurückgegeben
  !cmp cx,-16383        ;Exponent
  !jne @f
  !or eax,eax           ;Mantisse High-Anteil  da der Sinn nicht die Exponential-Darstellung ist könnte auch hier abgebrochen werden
  !jnz @f               ;d.h. Wert auch Null 
  !or ebx,ebx
  !jnz @f

  !mov dword[StringA],20302e30h   ;"0.0 "
  !mov edi,ebp          ;Pointer auf String, in den geschrieben werden soll
  !mov ebx,4            ;4 Bytes Ausgabe
  !jmp l_merker_ende
   
;------------------------------------------------
!@@:
  !mov [Trenner],63
  !sub [Trenner],cx
  !and cx,cx
  !jns l_wnnx           ;Exponent nicht negativ

;-------- Exponent < 0
  !mov esi,[StringZ]
  !mov word[StringA+esi],2e30h    ;"0."
  !add [StringZ],2
 
  !mov [F],5
  !mov [Merker],1
  !jmp l_ziffern_bestimmen

;-------- Exponent >= 0
WNNX: 
  !cmp [Trenner],0
  !jge @f
  !neg [Trenner]
  !mov [F],2            ;wenn Trenner kleiner Null wird mit 2 multipliziert!!!
  !mov [Merker],2
  !jmp l_ziffern_bestimmen

!@@:
  !mov [F],5
  !mov [Merker],3

;-------- "String" erzeugen
Ziffern_bestimmen:
  !movq xmm0,[Mantisse] ;Ursprungswert laden
  !lea esi,[Teiler]     ;Beginn der Zehner-Potenzen
  !lea edi,[String1]    ;zum Abspeichern
  !add edi,1004
  !mov ecx,19           ;noch 19 Bytes, das 1.wird vor der Schleife gesetzt (kann nur 0 oder 1 sein)

  !movmskpd eax,xmm0    ;Test auf MSB
  !test eax,1           ;testet Bit 63!
  !jz l_w11             ;nicht gesetzt, Mantisse kleiner als 9223372036854775808 (8000000000000000h)

;- Test ob Mantisse < 10000000000000000000
  !movq xmm1,[esi]
  !psubq xmm0,xmm1
  !movmskpd eax,xmm0    ;Test auf MSB
  !test eax,1           ;testet Bit 63!
  !jnz @f               ;kleiner als 10000000000000000000

  !mov byte[edi],1      ;"1" setzen an höchste Stelle
  !movq [Mantisse],xmm0 ;neuer Mantissen-Wert
  !jmp l_w11

!@@:
  !movq xmm0,[Mantisse] ;alten Mantissen-Wert wiederherstellen
 
;--------------------------------
W11:
  !inc edi              ;eine Stelle im "String" weiter
  !add esi,8
W1:
  !movq xmm1,[esi]      ;(neue) Zehner-Potenz laden
!@@:
  !psubq xmm0,xmm1      ;Mantisse minus Teiler
  !movmskpd eax,xmm0
  !test eax,1
  !jnz @f

  !movq [Mantisse],xmm0
  !inc byte[edi]
  !jmp @b

!@@:
  !movq xmm0,[Mantisse]
  !add esi,8
  !inc edi
  !dec ecx
  !jnz l_w1

;- Komma ist hier auch Länge Ausgangs-String
  !mov dword[Komma],20
  !mov [Len],20

  !cmp [Trenner],0
  !je l_trenner_0

  !mov ecx,1
Schleife_fuer_4:
;------- wenn F=5 Ausgangswert umkopieren für 5=4+1
  !cmp [F],5
  !jne l_w2_1
   
  !lea edi,[String1]
  !add edi,1020
  !lea esi,[String2]
  !add esi,1020
  !mov ebx,[Len]
  !shr ebx,2
  !inc ebx              ;genug Reserve!
!@@:
  !mov eax,[edi]
  !mov [esi],eax
  !sub edi,4
  !sub esi,4
  !dec ebx
  !jnz @b
W2_1:

;-------
  !mov edx,2            ;Zähler für x4
W1_1:                   ;für Schleife x4
  !lea edi,[String1]
  !add edi,1023         ;Ende des Strings
  !mov ebx,[Len]
  !xor ah,ah
W0_1:                   ;für Schleife x2
  !mov al,[edi]
  !add al,al
  !add al,ah

  !xor ah,ah
  !cmp al,10
  !jb l_nicht_10
  !sub al,10
  !inc ah

  !cmp ebx,1
  !jne @f
  !inc [Len]
  !inc ebx
!@@:

Nicht_10:
  !mov [edi],al
  !dec edi
  !dec ebx
  !jnz l_w0_1

  !cmp [F],2
  !je l_nur_2           ;nur "Multiplikation" mit 2

  !dec edx
  !jnz l_w1_1           ;zweiter Durchlauf für 2+2

;- hier 4+1 als "Multiplikation" mit 5
  !xor ah,ah
  !mov ebx,[Len]
  !lea edi,[String1]
  !add edi,1023
  !lea esi,[String2]
  !add esi,1023
W3_1:               
  !mov al,[edi]
  !add al,[esi]
  !add al,ah

  !xor ah,ah
  !cmp al,10
  !jb l_nicht_10_1
  !sub al,10
  !inc ah
 
  !cmp ebx,1
  !jne @f
  !inc [Len]
  !inc ebx
!@@:

Nicht_10_1:
  !mov [edi],al
  !dec edi
  !dec esi
  !dec ebx
  !jnz l_w3_1

Nur_2:
  !cmp byte[edi+1],1
  !ja @f
  !dec [Komma]
!@@:
  !inc ecx
  !cmp cx,[Trenner]
  !jbe l_schleife_fuer_4

  !cmp byte[edi+1],2   ;wenn 2 oder grösser noch eine Stelle mehr 
  !jb @f
  !dec [Komma]
!@@:

;---------------------------------- 
Trenner_0:
  !mov edi,ebp          ;Pointer auf String, in den geschrieben werden soll

  !cmp [Merker],1       ;"0."
  !jne l_ob_merker2

;-------- Merker = 1
  !movzx ecx,[Trenner]
  !mov ebx,[StringZ] 
  !sub ecx,[Len]
  !jz l_null_1   
 
!@@:
  !mov byte[StringA+ebx],30h
  !inc ebx
  !dec ecx
  !jnz @b     
   
Null_1:
  !lea esi,[String1]
  !add esi,1024
  !mov ecx,20
  !sub esi,[Len]
!@@:
  !mov al,[esi]
  !add al,30h
  !mov [StringA+ebx],al
  !inc esi
  !inc ebx
  !dec ecx
  !jnz @b
   
  !jmp l_merker_ende

Ob_Merker2:
  !cmp [Merker],2
  !jne l_merker3

;-------- Merker = 2 
Merker2:
  !mov ebx,[StringZ]    ;Zeiger in StringA
  !lea esi,[String1]       
  !add esi,1024
  !mov ecx,20
  !sub esi,[Len]
!@@:
  !mov al,[esi]
  !add al,30h
  !mov [StringA+ebx],al
  !inc esi
  !inc ebx
  !dec ecx
  !jnz @b

  !mov ecx,[Len]
  !sub ecx,ebx
  !jz l_null_2

!@@:
  !mov byte[StringA+ebx],30h
  !inc ebx
  !dec ecx
  !jnz @b     
 
Null_2:
  !jmp l_merker_ende

;-------- Merker = 3
Merker3:
  !mov ebx,[StringZ]
  !lea esi,[String1]
  !add esi,1024
  !sub esi,[Len]
  !mov ecx,[Komma]
!@@:
  !mov al,[esi]
  !add al,30h
  !mov [StringA+ebx],al
  !inc esi
  !inc ebx
  !dec ecx
  !js @f
  !jnz @b
!@@:
  !mov ecx,20
  !sub ecx,[Komma]
  !jz l_merker_ende
  !mov [StringA+ebx],2eh
  !inc ebx
!@@:
  !mov al,[esi]
  !add al,30h
  !mov [StringA+ebx],al
  !inc esi
  !inc ebx
  !dec ecx
  !jnz @b

Merker_Ende:
  !lea esi,[StringA]
  !mov ecx,ebx
  !cld
  !rep movsb
 
  !mov byte[edi],0      ;für das String-Ende das Zero-Byte setzen
  
  ;!popad
    
  !pop rdi
  !pop rsi
  !pop rbp
  !pop rsp
  !pop rbx
  !pop rdx
  !pop rcx
  !pop rax
  
ProcedureReturn 

End

;!section '.data' Data readable writeable
DataSection
!String1   RB 1024      ;eigentlicher Berechnungs-String; für Extrem-Werte ALLE String-Bezüge vergrössern!
!String2   RB 1024      ;Hilfs-String für die Multiplikation mit 5 = 4 + 1
!StringA   RB 256       ;256 Byte für String-Ausgabe
!Mantisse  DQ 0
!Teiler    DQ 10000000000000000000
!          DQ 1000000000000000000
!          DQ 100000000000000000
!          DQ 10000000000000000
!          DQ 1000000000000000
!          DQ 100000000000000
!          DQ 10000000000000
!          DQ 1000000000000
!          DQ 100000000000
!          DQ 10000000000
!          DQ 1000000000
!          DQ 100000000
!          DQ 10000000
!          DQ 1000000
!          DQ 100000
!          DQ 10000
!          DQ 1000
!          DQ 100
!          DQ 10
!          DQ 1   
 
!F         DD 0
!Komma     DD 0
!Merker    DD 0
!StringZ   DD 0         ;Zeiger in String  StringZähler
!Len       DD 0

!Trenner   DW 0

EndDataSection

EndProcedure
;-------------------------------------------------------------------------

Procedure ValT(Variable1, Variable2)   ;Variable1 = Zeiger auf String, Variable2 = Ausgabe
  !mov eax,[p.v_Variable1]
  !mov edx,[p.v_Variable2]
  
  ;!pushad
  !push rax
  !push rcx
  !push rdx
  !push rbx
  !push rsp
  !push rbp
  !push rsi
  !push rdi  
  
  !mov esi,eax
  !mov edi,edx
  !xor eax,eax
  !mov ebx,eax
  !mov ecx,eax
  !mov [ManVorzeichen],eax
  !mov [ExpVorzeichen],eax
  !mov [Dezimalpunkt],eax
       
  !mov al,[esi]
  !cmp al,'-'
  !je l_minus_vorzeichen
  !cmp al,'+'                          ;Test auf pos. Vorzeichen erstmal drinlassen
  !je l_plus_vorzeichen
  !jmp l_vorzeichen_ende
Minus_Vorzeichen:
  !inc [ManVorzeichen]
Plus_Vorzeichen:
  !inc esi
  !mov al,[esi]
Vorzeichen_Ende:
  !fldz
Mantisse_Lesen:
  !cmp al,'E'
  !je l_exponent
  !cmp al,'e'
  !je l_exponent
  !cmp al,'.'
  !je l_dezimal_punkt
  !xor al,'0'
  !cmp al,9
  !ja l_ziffern_ende
  !mov [Temp],eax
  !fmul [Zehner]
  !fiadd word[Temp]
  !inc ebx
  !jmp l_kein_punkt
Dezimal_Punkt:
  !cmp [Dezimalpunkt],0
  !jne l_ziffern_ende
  !mov [Dezimalpunkt],ebx
Kein_Punkt:
  !inc esi
  !mov al,[esi]
  !jmp l_mantisse_lesen
Exponent:
  !inc esi
  !mov al,[esi]
  !cmp al,'-'
  !je l_minus_exponent_vorzeichen
  !cmp al,'+'
  !je l_plus_exponent_vorzeichen
  !jmp l_exponent_lesen
Minus_Exponent_Vorzeichen:
  !inc [ExpVorzeichen]
Plus_Exponent_Vorzeichen:
  !inc esi
  !mov al,[esi]
Exponent_Lesen:
  !xor al,'0'
  !cmp al,9
  !ja l_ziffern_ende
  !lea ecx,[ecx*4+ecx]
  !lea ecx,[ecx*2+eax]
  !inc esi
  !mov al,[esi]
  !jmp l_exponent_lesen
Ziffern_Ende:
  !cmp [ExpVorzeichen],0
  !je l_exponent_fertig
  !neg ecx
Exponent_Fertig:
  !mov eax,[Dezimalpunkt]
  !or eax,eax
  !je l_kein_dezimalpunkt
  !sub ebx,eax
  !sub ecx,ebx
Kein_Dezimalpunkt:
  !or ecx,ecx
  !je l_kein_exponent
  !mov eax,ecx
  !cmp eax,0
  !jge l_exponent_vorzeichen_ok
  !neg eax
Exponent_Vorzeichen_Ok:
  !fld1
  !mov dl,al
  !and edx,0Fh
  !je l_groesserer_exponent
  !lea edx,dword[edx+edx*4]
  !fld tword [edx*2+Zehner_1-10]
  !fmulp st1,st
Groesserer_Exponent:
  !mov dl,al
  !shr dl,4
  !and edx,0Fh
  !je l_noch_groesserer_exponent
  !lea edx,dword[edx+edx*4]
  !fld tword [edx*2+Zehner_16-10]
  !fmulp st1,st
Noch_Groesserer_Exponent:
  !mov dl,ah
  !and edx,1Fh
  !je l_exponent_vorzeichen
  !lea edx,dword[edx+edx*4]
  !fld tword[edx*2+Zehner_256-10]
  !fmulp st1,st
Exponent_Vorzeichen:
  !cmp ecx,0
  !jge l_positiver_exponent
  !fdivp st1,st
  !jmp l_kein_exponent
Positiver_Exponent:
  !fmulp st1,st
Kein_Exponent:
  !cmp [ManVorzeichen],0
  !je l_fertig
  !fchs
Fertig:
!fstp tword[edi]

;!popad
  
  !pop rdi
  !pop rsi
  !pop rbp
  !pop rsp
  !pop rbx
  !pop rdx
  !pop rcx
  !pop rax  
  
ProcedureReturn

;!section '.data' Data readable writeable

DataSection
!ManVorzeichen dd 0
!ExpVorzeichen dd 0
!Dezimalpunkt  dd 0
!Temp          dd 0
!Zehner        dq 10.0
!Zehner_1      dt 1.0e1
!              dt 1.0e2
!              dt 1.0e3
!              dt 1.0e4
!              dt 1.0e5
!              dt 1.0e6
!              dt 1.0e7
!              dt 1.0e8
!              dt 1.0e9
!              dt 1.0e10
!              dt 1.0e11
!              dt 1.0e12
!              dt 1.0e13
!              dt 1.0e14
!              dt 1.0e15
!Zehner_16     dt 1.0e16
!              dt 1.0e32
!              dt 1.0e48
!              dt 1.0e64
!              dt 1.0e80
!              dt 1.0e96
!              dt 1.0e112
!              dt 1.0e128
!              dt 1.0e144
!              dt 1.0e160
!              dt 1.0e176
!              dt 1.0e192
!              dt 1.0e208
!              dt 1.0e224
!              dt 1.0e240
!Zehner_256    dt 1.0e256
!              dt 1.0e512
!              dt 1.0e768
!              dt 1.0e1024
!              dt 1.0e1280
!              dt 1.0e1536
!              dt 1.0e1792
!              dt 1.0e2048
!              dt 1.0e2304
!              dt 1.0e2560
!              dt 1.0e2816
!              dt 1.0e3072
!              dt 1.0e3328
!              dt 1.0e3584
!              dt 1.0e3840
!              dt 1.0e4096
!              dt 1.0e4352
!              dt 1.0e4608
!              dt 1.0e4864                                     
EndDataSection

EndProcedure           
;-------------------------------------------------------------------------


;-------- ARITHMETISCHE FUNKTIONEN ---------------------------------------
;-------- Addition ---------- Variable3 = Variable1 + Variable2 ----------
Procedure AddT(Variable1, Variable2, Variable3)
  !fninit                       
  !mov esi,[p.v_Variable1]
  !fld tword[esi]           
  !mov esi,[p.v_Variable2]
  !fld tword[esi]
  !faddp st1,st0
  !mov esi,[p.v_Variable3]
  !fstp tword[esi]      ;Ergebnis
EndProcedure
;-------------------------------------------------------------------------

;-------- Division ---------- Variable3 = Variable1 / Variable2 ----------
Procedure DivT(Variable1, Variable2, Variable3)
  !fninit                       
  !mov esi,[p.v_Variable1]
  !fld tword[esi]           
  !mov esi,[p.v_Variable2]
  !fld tword[esi]
  !fdivp st1,st0
  !mov esi,[p.v_Variable3]
  !fstp tword[esi]      ;Ergebnis
EndProcedure
;-------------------------------------------------------------------------

;-------- Multiplikation ---- Variable3 = Variable1 * Variable2 ----------
Procedure MulT(Variable1, Variable2, Variable3)
  !fninit                       
  !mov esi,[p.v_Variable1]
  !fld tword[esi]           
  !mov esi,[p.v_Variable2]   
  !fld tword[esi]
  !fmulp st1,st0
  !mov esi,[p.v_Variable3]
  !fstp tword[esi]      ;Ergebnis
EndProcedure
;-------------------------------------------------------------------------

;-------- Quadratwurzel ----- Variable2 = Variable1 ^ 0.5 ----------------
Procedure SqrT(Variable1, Variable2)
  !fninit                       
  !mov esi,[p.v_Variable1]
  !fld tword[esi]
  !fsqrt
  !mov esi,[p.v_Variable2]
  !fstp tword[esi]      ;Ergebnis
EndProcedure
;-------------------------------------------------------------------------

;-------- Subtraktion ------- Variable3 = Variable1 - Variable2 ----------
Procedure SubT(Variable1, Variable2, Variable3)
  !fninit                       
  !mov esi,[p.v_Variable1]
  !fld tword[esi]           
  !mov esi,[p.v_Variable2]
  !fld tword[esi]
  !fsubp st1,st0
  !mov esi,[p.v_Variable3]
  !fstp tword[esi]      ;Ergebnis
EndProcedure
;-------------------------------------------------------------------------


;-------- WINKELFUNKTIONEN -----------------------------------------------
;-------- ArcusCosinus ------ Variable2 = ACos(Variable1(rad)) -----------
Procedure ACosT(Variable1, Variable2)
  !fninit                       
  !fld1
  !mov esi,[p.v_Variable1]
  !fld tword[esi]
  !fst st2
  !fmul st0,st0
  !fsubp
  !fsqrt
  !fxch
  !fpatan
  !mov esi,[p.v_Variable2]
  !fstp tword[esi]      ;Ergebnis
  !fdecstp
  !ffree st0
EndProcedure

;-------- ArcusCotangens ---- Variable2 = ACot(Variable1(rad)) -----------
Procedure ACotT(Variable1, Variable2)  ;Pi/2 - arctan(x)
  !fninit                       
  !fldpi
  !fld1
  !fld1
  !faddp
  !fdivp
  !mov esi,[p.v_Variable1]   
  !fld tword[esi]
  !fld1
  !fpatan
  !fsubp
  !mov esi,[p.v_Variable2]
  !fstp tword[esi]      ;Ergebnis
EndProcedure

;-------- ArcusSinus -------- Variable2 = ASin(Variable1(rad)) -----------
Procedure ASinT(Variable1, Variable2)
  !fninit                       
  !fld1
  !mov esi,[p.v_Variable1]   
  !fld tword[esi]
  !fst st2
  !fmul st0,st0
  !fsubp
  !fsqrt
  !fpatan
  !mov esi,[p.v_Variable2]
  !fstp tword[esi]      ;Ergebnis
  !fdecstp              ;Stack-Bereinigung, TOS ist danach ST(0)
  !ffree st0            ;ST(0) als leer deklarieren
EndProcedure

;-------- ArcusTangens ------ Variable2 = ATan(Variable1(rad)) -----------
Procedure ATanT(Variable1, Variable2)
  !fninit                       
  !mov esi,[p.v_Variable1]   
  !fld tword[esi]
  !fld1
  !fpatan
  !mov esi,[p.v_Variable2]
  !fstp tword[esi]      ;Ergebnis
EndProcedure

;-------- Cosinus ----------- Variable2 = Cos(Variable1(rad)) ------------
Procedure CosT(Variable1, Variable2)
  !fninit                       
  !mov esi,[p.v_Variable1]
  !fld tword[esi]
  !fcos
  !mov esi,[p.v_Variable2]
  !fstp tword[esi]      ;Ergebnis
EndProcedure
;-------------------------------------------------------------------------

;-------- Cotangens --------- Variable2 = Cot(Variable1(rad)) ------------
Procedure CotT(Variable1, Variable2)
  !fninit                       
  !mov esi,[p.v_Variable1]
  !fld tword[esi]
  !fptan
  !fdivrp st1,st0
  !mov esi,[p.v_Variable2]
  !fstp tword[esi]      ;Ergebnis
EndProcedure
;-------------------------------------------------------------------------

;-------- Sinus ------------- Variable2 = Sin(Variable1(rad)) ------------
Procedure SinT(Variable1, Variable2)
  !fninit                       
  !mov esi,[p.v_Variable1]
  !fld tword[esi]
  !fsin
  !mov esi,[p.v_Variable2]
  !fstp tword[esi]      ;Ergebnis
EndProcedure
;-------------------------------------------------------------------------

;-------- Tangens ----------- Variable2 = Tan(Variable1(rad)) ------------
Procedure TanT(Variable1, Variable2)
  !fninit                       
  !mov esi,[p.v_Variable1]
  !fld tword[esi]
  !fptan
  !fdivp st1,st0
  !mov esi,[p.v_Variable2]
  !fstp tword[esi]      ;Ergebnis
EndProcedure
;-------------------------------------------------------------------------


;-------- ERWEITERTE FUNKTIONEN ------------------------------------------
;-------- Pow --------------- Variable3 = Variable1 ^ Variable2 ----------
Procedure PowT(Variable1, Variable2, Variable3)
  !fninit                       
  !mov esi,[p.v_Variable2]
  !fld tword[esi]           
  !mov esi,[p.v_Variable1]
  !fld tword[esi]
  !fyl2x
  !fld st0
  !frndint
  !fsub st1,st0
  !fxch st1
  !f2xm1
  !fld1
  !faddp st1,st0
  !fscale
  !fstp st1
  !mov esi,[p.v_Variable3]
  !fstp tword[esi]      ;Ergebnis
EndProcedure
;-------------------------------------------------------------------------


;-------- KONSTANTEN -----------------------------------------------------
;-------- L0 ---------------- Variable1 = 0.0 ----------------------------
Procedure L0T(Variable1)
  !fninit                       
  !fldz                 ;00000000000000000000h = 0.0
  !mov esi,[p.v_Variable1]
  !fstp tword[esi]      ;Ergebnis
EndProcedure
;-------------------------------------------------------------------------

;-------- L1 ---------------- Variable1 = 1.0 ----------------------------
Procedure L1T(Variable1)
  !fninit                       
  !fld1                 ;3FFF8000000000000000h = 1.0
  !mov esi,[p.v_Variable1]
  !fstp tword[esi]      ;Ergebnis
EndProcedure
;-------------------------------------------------------------------------

;-------- Ld(10) ------------ Variable1 = Ld(10), 2 ^ Variable1 =10.0 ----
Procedure Ld10T(Variable1)
  !fninit                       
  !fldl2t               ;4000D49A784BCD1B8AFEh = 3.3219280948873623478
  !mov esi,[p.v_Variable1]
  !fstp tword[esi]      ;Ergebnis
EndProcedure
;-------------------------------------------------------------------------

;-------- Ld(e) ------------- Variable1 = Ld(e), 2 ^ Variable1 = e -------
Procedure LdeT(Variable1)
  !fninit                       
  !fldl2e               ;3FFFB8AA3B295C17F0BCh = 1.4426950408889634073
  !mov esi,[p.v_Variable1]
  !fstp tword[esi]      ;Ergebnis
EndProcedure
;-------------------------------------------------------------------------

;-------- Lg(2) ------------- Variable1 = Lg(2), 10 ^ Variable1 = 2.0 ----
Procedure Lg2T(Variable1)
  !fninit                       
  !fldlg2               ;3FFFB17217F7D1CF79ACh = 0.301029995663981195198
  !mov esi,[p.v_Variable1]
  !fstp tword[esi]      ;Ergebnis
EndProcedure
;-------------------------------------------------------------------------

;-------- Ln(2) ------------- Variable1 = Ln(2), e ^ Variable1 = 2.0 -----
Procedure Ln2T(Variable1)
  !fninit                       
  !fldln2               ;3FFD9A209A84FBCFF799h = 0.6931471805599453094
  !mov esi,[p.v_Variable1]
  !fstp tword[esi]      ;Ergebnis
EndProcedure
;-------------------------------------------------------------------------

;-------- Pi ---------------- Variable1 = Pi -----------------------------
Procedure PiT(Variable1)
  !fninit                       
  !fldpi                ;4000C90FDAA22168C335h = 3.1415926535897932385
  !mov esi,[p.v_Variable1]
  !fstp tword[esi]      ;Ergebnis
EndProcedure
;-------------------------------------------------------------------------


;-------- SONSTIGES ------------------------------------------------------
;-------- Change ------------ Vertauscht die Werte der beiden Variablen --
Procedure ChangeT(Variable1, Variable2)
  !fninit
  !mov esi,[p.v_Variable1]
  !fld tword[esi]
  !mov edi,[p.v_Variable2]
  !fld tword[edi]
  !fstp tword[esi]
  !fstp tword[edi]
EndProcedure
;-------------------------------------------------------------------------

;-------- Compare ----------- Vergleicht Variable1 mit Variable2 ---------
Procedure CompT(Variable1, Variable2)
  !fninit
  !mov esi,[p.v_Variable2]
  !fld tword[esi]
  !mov esi,[p.v_Variable1]
  !fld tword[esi]
  !fcompp
  !fstsw ax             ;nicht fnstsw!
  !sahf
  !jne @f               ;nicht gleich
  !xor eax,eax
  ProcedureReturn       ;Rückgabewert=0 für Variable1 gleich Variable2
!@@:
  !jnc @f               ;nicht kleiner
  !mov eax,1
  ProcedureReturn       ;Rückgabewert=1 für Variable1 kleiner als Variable2
!@@:
  !mov eax,2
  ProcedureReturn       ;Rückgabewert=2 für Variable1 grösser als Variable2
EndProcedure
;-------------------------------------------------------------------------

;-------- Copy -------------- kopiert Variable2 in Variable1 -------------
Procedure CopyT(Variable1, Variable2)
  !fninit
  !mov esi,[p.v_Variable2]
  !fld tword[esi]
  !mov esi,[p.v_Variable1]
  !fstp tword[esi]
EndProcedure
;-------------------------------------------------------------------------

Code: Alles auswählen


;00:00:00:00:00:00:00:A8:04:40 = 42

EnableExplicit

IncludeFile "Procfpu80.pbi"

Define *variable1.i, *variable2.i, variable1$, variable2$, b$, n.i

*variable1 = AllocateMemory(1024)
If *variable1 = 0
  End
EndIf

*variable2 = AllocateMemory(10)
If *variable2 = 0
  End
EndIf  

variable2$ = "00:00:00:00:00:00:00:A8:04:40"
Debug variable2$

For n = 0 To 9
  b$ = "$" + StringField(variable2$, n + 1, ":")
  PokeA(*variable2 + n, Val(b$))
Next n  

StrT(*variable1, *variable2)

variable1$ = PeekS(*variable1, -1, #PB_Ascii)

Debug variable1$

variable1$ = RTrim(variable1$, "0")
variable1$ = RTrim(variable1$, ".")

Debug variable1$

FreeMemory(*variable1)
FreeMemory(*variable2)

Code: Alles auswählen


00:00:00:00:00:00:00:A8:04:40
42.000000000000000000
42

PB v5.72 x86/x64
Windows 10 Pro 64bit
Benutzeravatar
Helle
Beiträge: 566
Registriert: 11.11.2004 16:13
Wohnort: Magdeburg

Re: Problem mit 80bit Zahlen

Beitrag von Helle »

Eine "anständige" Windows-64-Bit-Version müsste komplett neu geschrieben werden (64-Bit-Adressierung usw.). Wenn es aber nicht auf die 80-Bit-Float-Genauigkeit ankommt sondern eben nur ein 80-Bit-Wert "umgewandelt" werden soll reicht folgendes:

Code: Alles auswählen


Buffer.q = AllocateMemory(10)
Value.d

variable2$ = "00:00:00:00:00:00:00:A8:04:40"
Debug variable2$

For n = 0 To 9
  b$ = "$" + StringField(variable2$, n + 1, ":")
  PokeA(Buffer + n, Val(b$))
Next n  

!lea rax,[v_Value]
!mov rdx,[v_Buffer]
!fld tword[rdx]
!fstp qword[rax]

Debug StrD(Value)
Gruß
Helle
Antworten