Seite 2 von 2
Re: Problem mit 80bit Zahlen
Verfasst: 17.03.2012 21:39
von - chris -
Hier das ganze für 32Bit und 64bit (80bit Umwandeln nach Double).
@Helle, Ist das so korrekt?
Wie sieht dann der umgedrehte Fall aus (Double Umwandeln nach 80bit)?
Code: Alles auswählen
EnableExplicit
Procedure.d ExtendedFloat2Double(buffer.i)
Protected value.d
If buffer
CompilerSelect #PB_Compiler_Processor
CompilerCase #PB_Processor_x86
!lea eax,[p.v_value]
!mov edx,[p.v_buffer]
!fld tword[edx]
!fstp qword[eax]
CompilerCase #PB_Processor_x64
!lea rax,[p.v_value]
!mov rdx,[p.v_buffer]
!fld tword[rdx]
!fstp qword[rax]
CompilerEndSelect
EndIf
ProcedureReturn value
EndProcedure
Define *buffer, value.d, buffer$, n.i, b$
*buffer = AllocateMemory(10)
If *buffer = 0
End
EndIf
buffer$ = "00:00:00:00:00:00:00:A8:04:40"
Debug buffer$
For n = 0 To 9
b$ = "$" + StringField(buffer$, n + 1, ":")
PokeA(*buffer + n, Val(b$))
Next n
value = ExtendedFloat2Double(*buffer)
Debug value
Re: Problem mit 80bit Zahlen
Verfasst: 18.03.2012 12:13
von Helle
Ist oK. Umwandeln in ExtDouble ist natürlich auch möglich; je nach Ausgangswert tritt aber (natürlich) ein Genauigkeitsverlust auf:
Code: Alles auswählen
;Beispiele für 64-Bit-Windows, für 32-Bit: rax zu eax und rdx zu edx ändern
Buffer.i = AllocateMemory(10)
ValueF.f = 42.0
ValueD.d = 42.0
!jmp @f ;sonst wird ValueT als Code interpretiert
ValueT:
!ValueT dt 42.0
!@@:
Debug "Byte-weise Hex von Float 42.0 (4 Bytes) :"
For n = 0 To 2
ValueF$ + RSet(Hex(PeekA(@ValueF + n)), 2, "0") + ":"
Next n
ValueF$ + Hex(PeekA(@ValueF + n))
Debug ValueF$
Debug "============================================================"
Debug "Byte-weise Hex von Double 42.0 (8 Bytes) :"
For n = 0 To 6
ValueD$ + RSet(Hex(PeekA(@ValueD + n)), 2, "0") + ":"
Next n
ValueD$ + Hex(PeekA(@ValueD + n))
Debug ValueD$
Debug "============================================================"
Debug "Byte-weise Hex von ExtDouble 42.0 (10 Bytes) :"
For n = 0 To 8
ValueT$ + RSet(Hex(PeekA(?ValueT + n)), 2, "0") + ":"
Next n
ValueT$ + Hex(PeekA(?ValueT + n))
Debug ValueT$
Debug "============================================================"
;Konvertierung von Float in ExtDouble
!lea rax,[v_ValueF]
!mov rdx,[v_Buffer]
!fld dword[rax]
!fstp tword[rdx]
Debug "Byte-weise Hex von ExtDouble 42.0 (10 Bytes), konvertiert von Float :"
For n = 0 To 8
ValueTKF$ + RSet(Hex(PeekA(Buffer + n)), 2, "0") + ":"
Next n
ValueTKF$ + Hex(PeekA(Buffer + n))
Debug ValueTKF$
Debug "============================================================"
;Konvertierung von Double in ExtDouble
!lea rax,[v_ValueD]
!mov rdx,[v_Buffer]
!fld qword[rax]
!fstp tword[rdx]
Debug "Byte-weise Hex von ExtDouble 42.0 (10 Bytes), konvertiert von Double :"
For n = 0 To 8
ValueTKD$ + RSet(Hex(PeekA(Buffer + n)), 2, "0") + ":"
Next n
ValueTKD$ + Hex(PeekA(Buffer + n))
Debug ValueTKD$
Debug "================================================================"
Debug "Bis hierher gab es noch keinen Genauigkeitsverlust, aber jetzt :"
Debug "================================================================"
ValueF1.f = 42.123456789012345678
ValueD1.d = 42.123456789012345678
!jmp @f ;sonst wird ValueT1 als Code interpretiert
ValueT1:
!ValueT1 dt 42.123456789012345678
!@@:
Debug "Byte-weise Hex von Float 42.123456789012345678 (4 Bytes) :"
For n = 0 To 2
ValueF1$ + RSet(Hex(PeekA(@ValueF1 + n)), 2, "0") + ":"
Next n
ValueF1$ + Hex(PeekA(@ValueF1 + n))
Debug ValueF1$
Debug "============================================================"
Debug "Byte-weise Hex von Double 42.123456789012345678 (8 Bytes) :"
For n = 0 To 6
ValueD1$ + RSet(Hex(PeekA(@ValueD1 + n)), 2, "0") + ":"
Next n
ValueD1$ + Hex(PeekA(@ValueD1 + n))
Debug ValueD1$
Debug "============================================================"
Debug "Byte-weise Hex von ExtDouble 42.123456789012345678 (10 Bytes) :"
For n = 0 To 8
ValueT1$ + RSet(Hex(PeekA(?ValueT1 + n)), 2, "0") + ":"
Next n
ValueT1$ + Hex(PeekA(?ValueT1 + n))
Debug ValueT1$
Debug "============================================================================"
;Konvertierung von Float in ExtDouble
!lea rax,[v_ValueF1]
!mov rdx,[v_Buffer]
!fld dword[rax]
!fstp tword[rdx]
Debug "Byte-weise Hex von ExtDouble 42.123456789012345678 (10 Bytes), konvertiert von Float :"
For n = 0 To 8
ValueTKF1$ + RSet(Hex(PeekA(Buffer + n)), 2, "0") + ":"
Next n
ValueTKF1$ + Hex(PeekA(Buffer + n))
Debug ValueTKF1$
Debug "============================================================================"
;Konvertierung von Double in ExtDouble
!lea rax,[v_ValueD1]
!mov rdx,[v_Buffer]
!fld qword[rax]
!fstp tword[rdx]
Debug "Byte-weise Hex von ExtDouble 42.123456789012345678 (10 Bytes), konvertiert von Double :"
For n = 0 To 8
ValueTKD1$ + RSet(Hex(PeekA(Buffer + n)), 2, "0") + ":"
Next n
ValueTKD1$ + Hex(PeekA(Buffer + n))
Debug ValueTKD1$
Gruß
Helle
Re: Problem mit 80bit Zahlen
Verfasst: 18.03.2012 15:01
von - chris -
Hier wieder das ganze für 32Bit und 64bit (80bit nach Double und Double nach 80bit)
Code: Alles auswählen
EnableExplicit
;Konvertierung von ExtDouble in Double (80bit -> 64bit)
Procedure.d ExtDouble2Double(buffer.i)
Protected value.d
If buffer
CompilerSelect #PB_Compiler_Processor
CompilerCase #PB_Processor_x86
!lea eax,[p.v_value]
!mov edx,[p.v_buffer]
!fld tword[edx]
!fstp qword[eax]
CompilerCase #PB_Processor_x64
!lea rax,[p.v_value]
!mov rdx,[p.v_buffer]
!fld tword[rdx]
!fstp qword[rax]
CompilerEndSelect
EndIf
ProcedureReturn value
EndProcedure
;Konvertierung von Double in ExtDouble (64bit -> 80bit)
Procedure Double2ExtDouble(buffer.i, value.d)
If buffer
CompilerSelect #PB_Compiler_Processor
CompilerCase #PB_Processor_x86
!lea eax, [p.v_value]
!mov edx, [p.v_buffer]
!fld qword[eax]
!fstp tword[edx]
CompilerCase #PB_Processor_x64
!lea rax,[p.v_value]
!mov rdx,[p.v_buffer]
!fld qword[rax]
!fstp tword[rdx]
CompilerEndSelect
EndIf
EndProcedure
Define *buffer, value.d, buffer$, n.i, b$
*buffer = AllocateMemory(10)
If *buffer = 0
End
EndIf
value = 42.0
Double2ExtDouble(*buffer, value)
buffer$ = ""
For n = 0 To 9
b$ = RSet(Hex(PeekA(*buffer + n)), 2, "0")
buffer$ = buffer$ + b$
If n < 9
buffer$ = buffer$ + ":"
EndIf
Next n
Debug buffer$
value = ExtDouble2Double(*buffer)
Debug value