
Extraído del artículo Q189862 de la KB de Microsoft.
INTRODUCCIÓN
Muchas funciones del API de Windows requieren un valor de 64 bits, bien como un entero de 8 bytes, bien como dos enteros de 4 bytes. Veremos cómo convertir datos entre un entero de 8 bytes y dos enteros de 4 bytes. También veremos cómo hacer operaciones matemáticas simples con ellos, como las que se necesitan para incrementar el puntero a fichero del API SetFilePointer.
MAS INFORMACION
Visual Basic posee un tipo de datos entero de 8 bytes llamado Currency pero está escalado en por un factor de 0,0001 para entrada, salida y operacione matemáticas. Esto no impide que lo usemos como argumento en llamadas al API que requieren un número de 64 bits. En es artículo veremos algunas rutinas de conversión y operaciones matemáticas básicas que tienen en cuenta este factor de escala.
Existen dos maneras de convertir entre dos valores de 32 bits y uno de 64 :
- Podemos usar la instrucción LSet y tipos definidos por el usuario
- Podemos emplear la funcion del API CopyMemory
Veremos cómo usar LSet.
Los ejemplos emplearán los siguiente tipos definidos por el usuario :
Type MungeCurr
Value As Currency
End Type
Type Munge2Long
LoValue As Long
HiValue As Long
End Type
Convertir dos valores de 32 bits en uno de 64.
Dim C As MungeCurr, L As Munge2Long
L.HiValue = Value1
L.LoValue = Value2
LSet C = L
Value3 = C.Value
Convertir un valor de 64 bits en dos de 32.
Dim C As MungeCurr, L As Munge2Long
C.Value = Value1
LSet L = C
Value2 = L.HiValue
Value3 = L.LoValue
Formatear un valor Currency sin posiciones decimales
Esta rutina tiene en cuenta que si el número tiene menos de 4 dígitos se eliminan los ceros de la izquierda dejando el signo intacto.
NOTA : Esta rutina asume que el separador decimal es "." (punto) y el signo menos es "-" y está a la izquierda del número.
Private Function CurrToText(ByVal Value As Currency) As String
Dim Temp As String, L As Long
Temp = Format$(Value, "#.0000")
L = Len(Temp)
Temp = Left$(Temp, L - 5) & Right$(Temp, 4)
Do While Len(Temp) > 1 And Left$(Temp, 1) = "0"
Temp = Mid$(Temp, 2)
Loop
Do While Len(Temp) > 2 And Left$(Temp, 2) = "-0"
Temp = "-" & Mid$(Temp, 3)
Loop
CurrToText = Temp
End Function
Convertir un campo de texto sin decimales en un Currency.
Esta rutina tiene en cuenta que si el número tiene menos de 4 dígitos habrá que rellenarlo y adecuar el signo.
NOTA : Esta rutina asume que el separador decimal es "." (punto) y el signo menos es "-" y está a la izquierda del número.
Private Function TextToCurr(ByVal Value As String) As Currency
Dim L As Long, Negative As Boolean
Value = Trim$(Value)
If Left$(Value, 1) = "-" Then
Negative = True
Value = Mid$(Value, 2)
End If
L = Len(Value)
If L < 4 Then
TextToCurr = CCur(IIf(Negative, "-0.", "0.") & _
Right$("0000" & Value, 4))
Else
TextToCurr = CCur(IIf(Negative, "-", "") & _
Left$(Value, L - 4) & "." & Right$(Value, 4))
End If
End Function
Sumar o restar dos conjuntos de 32 bits.
Este procedimiento no requiere especial consideración. Los pasos a seguir son :
- Convertir los cuatro valores de 32 bits en 2 de 64.
- Sumar los valores de 64 bits.
- Convertir el resultado de 64 bits en dos de 32.
Multiplicar y dividir valores de 64 bits.
Cuando multiplicamos valores de 64 bits necesitamos incluir un factor adicional de 10.000 para compensar el factor de escala del 0,0001.
Multiplicar: C3 = (C1 * 10000) * C2
Dividir: C3 = (C1 / C2) / 10000
NOTA: Los paréntesis están puestos para conservar toda la precisión que sea posible aunque se incrementa la posibilidad de desbordamiento (overflow).
Si estamos usando valores de 32 bits debemos convertirlos a y de 64 bits como se comentó anteriormente.
Multiplicar y dividir por un escalar.
Cuando multiplicamos o divimos por una cantidad escalar (byte, integer, long) no necesitamos hacer el ajuste de escala.
Multiplicar: C2 = C1 * 24
Dividir: C2 = C1 / 3
NOTA: Si estamos usando valores de 32 bits debemos convertirlos a y de 64 bits.
Aplicación de ejemplo.
El siguiente ejemplo mostrará :
- Cómo convertir valores de 32 bits en valores de 64 bits.
- Cómo convertir valores de 64 bits en valores de 32 bits.
- Cómo sumar dos pares de valores de 32 bits obteniendo un par de valores de 32 bits.
Creamos un nuevo proyecto y añadimos un formulario (Form1) y un CommandButton (Command1).
Añadimos el siguiente código en Form1 :
Option Explicit
Private Type MungeCurr
Value As Currency
End Type
Private Type Munge2Long
LoValue As Long
HiValue As Long
End Type
Private Function TextToCurr(ByVal Value As String) As Currency
Dim L As Long, Negative As Boolean
Value = Trim$(Value)
If Left$(Value, 1) = "-" Then
Negative = True
Value = Mid$(Value, 2)
End If
L = Len(Value)
If L < 4 Then
TextToCurr = CCur(IIf(Negative, "-0.", "0.") & _
Right$("0000" & Value, 4))
Else
TextToCurr = CCur(IIf(Negative, "-", "") & _
Left$(Value, L - 4) & "." & Right$(Value, 4))
End If
End Function
Private Function CurrToText(ByVal Value As Currency) As String
Dim Temp As String, L As Long
Temp = Format$(Value, "#.0000")
L = Len(Temp)
Temp = Left$(Temp, L - 5) & Right$(Temp, 4)
Do While Len(Temp) > 1 And Left$(Temp, 1) = "0"
Temp = Mid$(Temp, 2)
Loop
Do While Len(Temp) > 2 And Left$(Temp, 2) = "-0"
Temp = "-" & Mid$(Temp, 3)
Loop
CurrToText = Temp
End Function
Private Sub Command1_Click()
Dim C1 As MungeCurr, C2 As MungeCurr, C3 As MungeCurr
Dim L As Munge2Long
' Convertimos un valor de 64 bits en dos de 32 bits.
C1.Value = TextToCurr("123456789012345678")
LSet L = C1
Debug.Print CurrToText(C1.Value) & " => (" & L.HiValue & "," & _
L.LoValue & ")"
' Convertimos dos valores de 32 bits en uno de 64 bits.
L.HiValue = -1
L.LoValue = -1
LSet C1 = L
Debug.Print "(" & L.HiValue & "," & L.LoValue & ") => " & _
CurrToText(C1.Value)
' Suumamos dos pares de valores de 32 bits para obtener un par de
' valores de 32 bits.
L.HiValue = 33333333
L.LoValue = 44444444
LSet C1 = L
L.HiValue = -22222222
L.LoValue = 11111111
LSet C2 = L
C3.Value = C1.Value + C2.Value
LSet L = C3
Debug.Print "(33333333,44444444) + (-22222222,11111111) => (" & _
L.HiValue & "," & L.LoValue & ")"
End Sub
Ejecutamos el proyecto y pulsamos sobre el CommandButton.
RESULTADO: Debemos obtener los siguientes resultados en la ventana de debug :
123456789012345678 => (28744523,-1506741426)
(-1,-1) => -1
(33333333,44444444) + (-22222222,11111111) => (11111111,55555555)

