Find Jobs
Hire Freelancers

Double to Borland pascal real

$30-250 USD

In Progress
Posted over 14 years ago

$30-250 USD

Paid on delivery
This is a very small project, and probably can be done very fast. I came a long way but i can figure the last problem out. I have an old Borland pacal datafile wich uses the bp real (48 bits). I can convert it to a double (see function) but i also need to convert it back into a 48bit real (written out as bytes). It will probably take a expert to do it in 30 minutes but i cant get it done. Added some additional info for you: ----- Real48 to VBA double function Public Function RealToDouble(Byte6Arr() As Byte) As Double Dim dMantissa As Double Dim i As Integer Dim j As Long Dim k As Long Dim temp As Single Dim Data As String ' BP real48 Byte example [151, 0, 0, 208, 61, 113] will give 7905000 as double result 'accumulate the mantissa dMantissa = 1 For i = 6 To 2 Step -1 For j = IIf(i = 6, 6, 7) To 0 Step -1 k = k + 1 If (Byte6Arr(i) And (2 ^ j)) <> 0 Then dMantissa = dMantissa + 2 ^ -k End If Next j Next i 'finally, assemble all the pieces into a number If (Byte6Arr(6) And &H80) = &H80 Then RealToDouble = -dMantissa * 2 ^ (Byte6Arr(1) - 129) Else RealToDouble = dMantissa * 2 ^ (Byte6Arr(1) - 129) End If ' round the value to the 11 digit compatible pascal48 real RealToDouble = RoundIt(RealToDouble, 11) End Function ----- The function Double to BP real48, this is the function you have to make Public Function DoubleToReal(Byte8Arr() As Byte) As Byte() Dim dMantissa As Double Dim i As Integer Dim j As Long Dim k As Long Dim Real(0 To 4) As Byte Dim positive As Boolean ' Byte example [0, 0, 0, 0, 186, 39, 94, 65] should give 7905000 as Borland pascal real result ' determine the signbit positive or negative If (Byte8Arr(8) And &H80) = &H80 Then positive = False Else positive = True End If End Function ------ Some additional info on BP real48 and doubles The Real and Double Formats The real and double formats comprise three fields: a sign bit, a significand field, and an exponent field. For the real type, the fields can be visualized as arranged like this, with the most significant bit at the left end of each field: Field: Sign Significand(f) Exponent Width (bits): 1 39 8 __________________________ | s | f | e | |__ lsb_________msb_lsb_msb| 1 bit sign (s) 39 bits float (f) starting with the msb to the lsb 8 bits exponent (e) starting with msb to lsb The value is defined as if 0 < e <= 255 then v = (-1)^s * 2^(e-129) * (1.f). if e=0 then V = 0 The fields of the IEEE double type are arranged like this: Field: Sign Exponent Significand(f) Width (bits): 1 11 52 1 11 52 __________________________ | s | e | f | |__ msb_________lsb_msb_lsb| if 0<e< 2047 then v = v = (-1)^s * 2^(e-1023) * (1.f). if e=0 and f<>0 then v = (-1)^s * 2^(e-1022) * (0.f). if e=0 and f = 0 then v = (-1)^s * 0. if e=2047 and f=0 then v = (-1)^s * Inf. if e=2047 and f<>0 then v is a NaN. In a PC's memory, these values are stored with the right-most 8- bit bytes at the lowest address (or first on a disk), so that the real's exponent would be stored as the first byte and its sign bit would be the most significant (leftmost) bit of the sixth byte. The sign bit is set when the value is less than 0.0 (negative). The exponent field (8 bits for real, 11 bits for double) represents the integer part of the base-2 logarithm of the value, indicating the value's absolute magnitude. The exponent is biased by some value (129 for real, 1023 for double), so although the binary value of the field is positive, it can signify a negative value when the bias is subtracted from it. The significand field (39 bits for real, 52 bits for double) is the fractional part by which the value indicated by the exponent is increased. Thus, for both types, the represented value is generally Sign Significand (Exponent - Bias) (-1) (1 -------------------) 2 SignificandWidth 2 There are a few special cases. The value of a real is 0.0 when the exponent field is 0, i.e., when no bit in the exponent field is set. The IEEE double has a value of 0.0 when both the exponent field and the significand field have values of 0, but the double's sign bit can be set to represent -0.0 as well as 0.0. When all 11 bits are set in the double's exponent field, so that it has its highest possible value (2047), and none of the bits in the significand field is set, so that its value is 0, the double's value is Inf (infinity) or -Inf, depending on the sign bit. If the double's exponent field is 2047 and its significand is not equal to 0, the value is NaN (not a number). The real's format permits an absolute range of approximately 2.9e-39 to 1.7e38 (decimal) and a precision of 11-12 significant decimal digits. The double's wider format offers an absolute range of approximately 5.0e-324 to 1.7e308 and a precision of 15- 16 significant digits. (The tiniest values represented by doubles sacrifice precision for their very low magnitude.) Conversion Functions Conversion between a real and a double mainly involves transferring the bit fields from the source to the target. Because there is no high-level access to the bits in a double, and C has no real type, both double and real must be treated as arrays, the elements of which can be manipulated individually at the bit level. Instead of treating doubles and reals as arrays of bytes, it is more efficient to treat them as arrays of 16-bit unsigned ints. A typedef statement in BPREAL.C declares the "real" type as an array of 3 unsigned ints, and a "doublearray" union so that doubles can be handled as arrays of 4 unsigned ints. The bits contained in each of the arrays' elements are listed below. For each element, its contents are listed from left to right (most significant bit to least significant), and bit 1 of each field is the field's most significant bit: real[2] Sign 1, Significand 1-15 real[1] Significand 16-31 real[0] Significand 32-39, Exponent 1-8 doublearray.a[3] Sign 1, Exponent 1-11, Significand 1-4 doublearray.a[2] Significand 5-20 doublearray.a[1] Significand 21-36 doublearray.a[0] Significand 37-52 Conversion from real to double is straightforward, because any value that can be represented by a real can be represented by a double. The real_to_double function first checks whether the exponent is 0. If so, it returns the double 0.0. Otherwise, it adds 894 to the exponent because the double's exponent bias (1023) is 894 greater than the real's bias (129), and it places the exponent in the correct location in the double (element 3, shifted 4 bits to the left). It then moves the sign bit and the 39-bit significand to their proper locations. Conversion from double to real is trickier, because the IEEE type has greater range and precision and more special cases than the real. Since error-free conversion is not assured, the double_to_real function returns an error code of an enumerated type called prconverr (for Pascal Real Conversion Error). The error codes range in increasing seriousness from prOK, which means no error, to prNaN, which means that the double value was NaN (not a number), which cannot be represented by a real. The double_to_real function first checks whether the double value is 0.0 or -0.0, either of which is converted to a real representation of 0.0 before returning prOK. Next, the function checks whether all the bits in the double's exponent are set. If they are, the double's value is either Inf or NaN (or one of their negations). If the value is Inf, the real's exponent and significand fields are filled so as to represent the largest value possible, the sign bit is transferred, and the code prInf is returned. If the value is NaN, a real value of 0.0 and a code of prNaN are returned. After these tests, the significand is rounded. The real's 39-bit significand does not allow as much precision as the double's 52-bit significand. To keep as much precision as possible, the 40th bit of the double's significand is tested. If the 40th bit is set, the significand's 39th bit is incremented. If all of the first 40 bits of the double's significand are set, bits 1 to 39 are cleared and the exponent is incremented. The exponent field is guaranteed not to be filled, so incrementing the exponent will succeed, because the function has already tested the exponent for its maximum value in checking whether the double's value was Inf or NaN. After rounding, the function places the value of the double's exponent in a variable and checks whether it fits within the range of valid real exponents. Real exponents range from 1 to 255 biased, or -128 to 126. To fit in this range, the double's biased exponent must range from 895 to 1149. If the double's exponent is less then 895, a real value of 0.0 and a code of prPosUnderflow or prNegUnderflow (depending on the double's sign) are returned. If the double's exponent is greater than 1149, the real is set to its maximum value, the double's sign bit is transferred to the real, and a code of prOverflow is returned. After these checks, the function is assured of a valid conversion. The exponent is re-biased for the real range, and it is transferred to the real along with the sign bit and the first 39 bits of the double's significand (which may have been rounded). A code of prOK is then returned.
Project ID: 564104

About the project

3 proposals
Remote project
Active 14 yrs ago

Looking to make some money?

Benefits of bidding on Freelancer

Set your budget and timeframe
Get paid for your work
Outline your proposal
It's free to sign up and bid on jobs

About the client

Flag of NETHERLANDS
nootdorp, Netherlands
5.0
2
Member since Jun 5, 2008

Client Verification

Thanks! We’ve emailed you a link to claim your free credit.
Something went wrong while sending your email. Please try again.
Registered Users Total Jobs Posted
Freelancer ® is a registered Trademark of Freelancer Technology Pty Limited (ACN 142 189 759)
Copyright © 2024 Freelancer Technology Pty Limited (ACN 142 189 759)
Loading preview
Permission granted for Geolocation.
Your login session has expired and you have been logged out. Please log in again.