Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
Converting a String to a Double
Message
General information
Forum:
Visual FoxPro
Category:
Windows API functions
Miscellaneous
Thread ID:
00148663
Message ID:
00149978
Views:
14
>I am converting a VB interface to a DLL to a VFP interface.
>
>I have a VB type def:
>
>Type AL_GRAIN
> grain_id As Integer
> grain_name As String * 32
> lbs_per_bu As Integer
> dry_mc As Double
> spare(0 To 15) As Byte
>End Type
>
>and a function declaration:
>
>Declare Function get_al_grain Lib "aglead32.dll" (ByVal c As Long, _
> ByVal n As Long, _
> ByRef g As AL_GRAIN) As Long
>
>I can get AL_GRAIN into a string but,
>
>Can anyone tell me how to convert the dry_mc to a Double in VFP?
>
>Thanks.


I solved the problem myself. In case anyone is interested, take a look at the following functions.

*******************************************************************
FUNCTION StringToDouble
* Converts an 8 character string in IEEE Double-precision Floating-point number format (A VB Double data type)
* The standard defines the encoding for the double-precision floating- point data type "double" (64 bits or 8 bytes).
* The encoding used is the IEEE standard for normalized double-precision floating-point numbers.
* The standard encodes the following three fields, which describe the double-precision floating-point number:

* S: The sign of the number. Values 0 and 1 represent positive and negative, respectively. One bit.
* E: The exponent of the number, base 2. 11 bits are devoted to this field. The exponent is biased by 1023.
* F: The fractional part of the number's mantissa, base 2. 52 bits are devoted to this field.

* Therefore, the floating-point number is described by:
* (-1)^S * 2^(E-Bias) * 1.F

* +-------+------+-------+-------+-------+-------+-------+------+
* |byte 0|byte 1|byte 2|byte 3|byte 4|byte 5|byte 6|byte 7|
* S| E | F |
* +-------+------+-------+-------+-------+-------+-------+------+
* 1 | <--11--> |<---------------------52 bits-------------------->|
* <------------------------- 64 bits ---------------------------->
* DOUBLE-PRECISION FLOATING-POINT

* Just as the most and least significant bytes of a number are 0 and 3, the most and least significant bits
* of a double-precision floating- point number are 0 and 63. The beginning bit (and most significant bit)
* offsets of S, E , and F are 0, 1, and 12, respectively. Note that these numbers refer to the mathematical
* positions of the bits, and NOT to their actual physical locations (which vary from medium to medium).

LPARAMETER tcString
LOCAL lnSign, lnExponent, lnFraction, lnResult, i, e

*!* ? " "
*!* ? "Input String >" + tcString + "<"
*!* ? "ASCII Codes: " + LTRIM(STR(ASC(SUBSTR(tcString, 1, 1)))) + " " + ;
*!* LTRIM(STR(ASC(SUBSTR(tcString, 2, 1)))) + " " + ;
*!* LTRIM(STR(ASC(SUBSTR(tcString, 3, 1)))) + " " + ;
*!* LTRIM(STR(ASC(SUBSTR(tcString, 4, 1)))) + " " + ;
*!* LTRIM(STR(ASC(SUBSTR(tcString, 5, 1)))) + " " + ;
*!* LTRIM(STR(ASC(SUBSTR(tcString, 6, 1)))) + " " + ;
*!* LTRIM(STR(ASC(SUBSTR(tcString, 7, 1)))) + " " + ;
*!* LTRIM(STR(ASC(SUBSTR(tcString, 8, 1))))
*!* ? "Binary: " + StringToBinary(SUBSTR(tcString, 1, 1)) + " " + ;
*!* StringToBinary(SUBSTR(tcString, 2, 1)) + " " + ;
*!* StringToBinary(SUBSTR(tcString, 3, 1)) + " " + ;
*!* StringToBinary(SUBSTR(tcString, 4, 1)) + " " + ;
*!* StringToBinary(SUBSTR(tcString, 5, 1)) + " " + ;
*!* StringToBinary(SUBSTR(tcString, 6, 1)) + " " + ;
*!* StringToBinary(SUBSTR(tcString, 7, 1)) + " " + ;
*!* StringToBinary(SUBSTR(tcString, 8, 1))

* Bytes are stored in reverse order
lcSign = SUBSTR(StringToBinary(SUBSTR(tcString, 8, 1)), 1, 1)
lcExponent = SUBSTR(StringToBinary(SUBSTR(tcString, 8, 1)), 2, 7) + ;
SUBSTR(StringToBinary(SUBSTR(tcString, 7, 1)), 1, 4)
lcFraction = SUBSTR(StringToBinary(SUBSTR(tcString, 7, 1)), 5, 4) + ;
StringToBinary(SUBSTR(tcString, 6, 1)) + ;
StringToBinary(SUBSTR(tcString, 5, 1)) + ;
StringToBinary(SUBSTR(tcString, 4, 1)) + ;
StringToBinary(SUBSTR(tcString, 3, 1)) + ;
StringToBinary(SUBSTR(tcString, 2, 1)) + ;
StringToBinary(SUBSTR(tcString, 1, 1))

* Output in 1, 11, 52 format
* ? lcSign + " " + lcExponent + " " + lcFraction

lnSign = VAL(lcSign)
lnExponent = 0
e = 0
FOR i = 11 TO 1 STEP -1
IF SUBSTR(lcExponent, i, 1) = "1"
lnExponent = lnExponent + 2 ** e
ENDIF
e = e + 1
ENDFOR

lnFraction = 0
FOR i = 1 TO 52
IF SUBSTR(lcFraction, i, 1) = "1"
lnFraction = lnFraction + 1 / 2 ** i
ENDIF
ENDFOR

IF lnExponent > 0
lnFraction = 1 + lnFraction
lnResult = (-1) ** lnSign * 2**(lnExponent - 1023) * lnFraction
ELSE
IF lnFraction > 0
lnResult = (-1) ** lnSign * 2**(-1022) * lnFraction
ELSE
IF lnSign > 0
lnResult = -0
ELSE
lnResult = 0
ENDIF
ENDIF
ENDIF

* ? "Sign = " + LTRIM(STR(lnSign)) + ", Exp = " + LTRIM(STR(lnExponent)) + ", Fraction = " + STR(lnFraction, 20, 18)
* ? "Result = " + LTRIM(STR(lnResult, 20, 18))

RETURN lnResult

*******************************************************************
FUNCTION StringToBinary
LPARAMETER tcString
RETURN IIF(BITTEST(ASC(tcString), 7), "1", "0") + ;
IIF(BITTEST(ASC(tcString), 6), "1", "0") + ;
IIF(BITTEST(ASC(tcString), 5), "1", "0") + ;
IIF(BITTEST(ASC(tcString), 4), "1", "0") + ;
IIF(BITTEST(ASC(tcString), 3), "1", "0") + ;
IIF(BITTEST(ASC(tcString), 2), "1", "0") + ;
IIF(BITTEST(ASC(tcString), 1), "1", "0") + ;
IIF(BITTEST(ASC(tcString), 0), "1", "0")
Dennis Lindeman
Previous
Reply
Map
View

Click here to load this message in the networking platform