Re: Singles to Doubles



I'm not going to dispute what anyone has said in this thread. I think a
number of people truly understand what's happening here

However, my contribution is simply to show what's happening at the bit level
using one of Karl's own values. Hopefully, anyone who still feels uneasy at
the explanations can play with this and compare it with my commentary in the
code

Tony Proctor

'========== Form1 ============
Private Declare Sub GetMem4 Lib "msvbvm60" (ByVal Addr As Long, ByVal
RetAddr As Long)
Private Declare Sub GetMem8 Lib "msvbvm60" (ByVal Addr As Long, ByVal
RetAddr As Long)

Private Function sHex(lVal As Long) As String
sHex = Right$("0000000" & Hex(lVal), 8)
End Function

Private Sub Form_Load()
Dim f4 As Single
Dim f8a As Double, f8b As Double
Dim sFlt As String
Dim lVal(0 To 1) As Long

' Store single-precision 0.564. This cannot be represented with 100%
accuracy
' since decimal 0.564 cannot be represented as a finite sum of binary
fractions
' such as 1/2, 1/4, 1/8, etc
f4 = 0.564!
Debug.Print "f4="; f4

' Show the binary digits as hex string
GetMem4 VarPtr(f4), VarPtr(lVal(0))
Debug.Print "Hex f4="; sHex(lVal(0))

' Use IEEE conversion from Single to Double. This basically means just
appending
' extra binary zeros on the end. However, the exponent is a different
size in
' Double (11 bits as opposed to 8) and so the bit pattern moves
slightly, and
' 3 mantissa bits are shifted into the 2nd Long word. Note that the
displayed
' value is no longer just "0.564". Since it was inaccurate to start
with, appending
' zero bits now magnifies that inaccuracy.
f8a = CDbl(f4)
Debug.Print "f8a="; f8a

' Show the binary digits as hex string. Although it looks different to
the
' bits in 'f4', they're just shifted slightly. Only zero bits have been
appended.
' The semantics of the IEEE conversions are defined to do this as there
is no
' direct correspondence between the binary bits and a specific decimal
value
' in all cases
GetMem8 VarPtr(f8a), VarPtr(lVal(0))
Debug.Print "Hex f8a="; sHex(lVal(0)); " "; sHex(lVal(1))

' Let VB format the Single precision value. This comes back as "0.564"
as expected.
' Then convert that String value to Double. Now, the conversion can more
accurately
' represesent the intended value of 0.564
sFlt = CStr(f4)
Debug.Print "sFlt="; sFlt
f8b = CDbl(sFlt)
Debug.Print "f8b="; f8b

' Finally, show the binary bits in the new Double representation. Note
that the
' 2nd Long word has a lot more bits in it now rather than just the zeros
used
' in the first conversion
GetMem8 VarPtr(f8b), VarPtr(lVal(0))
Debug.Print "Hex f8b="; sHex(lVal(0)); " "; sHex(lVal(1))
End Sub
'============================

"Karl E. Peterson" <karl@xxxxxxxx> wrote in message
news:%23s3UXA%23xHHA.3328@xxxxxxxxxxxxxxxxxxxxxxx
Hi Folks --

Not sure I ever noticed this before, as I really haven't used Singles
"forever"
(thinking back to DOS days) now. But when I needed to convert a whole
boatload of
Single values to Doubles this morning, I noted some really funky
conversions. For
example, try this in the Immediate window, with virtually any random
number you care
to:

s=0.564!:?cdbl(s),cdbl(cstr(s))
0.564000010490417 0.564
s=0.3026!:?cdbl(s),cdbl(cstr(s))
0.302599996328354 0.3026

What the heck? Seems silly to have to convert it to a String first, then
to a
Double. But, it is more accurate. Anyone know of a less ugly way to
accurately
replicate a Single with a Double, or this the best it gets?

Thanks... Karl
--
.NET: It's About Trust!
http://vfred.mvps.org




.



Relevant Pages

  • Re: Sql Server Datetime
    ... the way it is stored in the database is a date. ... it is just some predefined conversion to a ... You need to use 'M' instead (or 'MM' for month with leading zeros). ... > but when I store that in a string variable it gets converted into real ...
    (microsoft.public.dotnet.framework.aspnet)
  • Proposal: String::Format::General
    ... It provides format string parsing and output assembly, you provide the code that implements the individual conversion characters. ... Format syntax is kind of a cross between sprintf and strftime, but how close it is to each of these depends on the semantics implemented by the user. ... Note that the following is pre-alpha documentation; the interface to the output conversion code has changed since yesterday, ... conversion character, and contain a number of optional fields which may ...
    (comp.lang.perl.modules)
  • Re: what if (f)printf returns EINTR ?
    ... vsnprintf - formatted output conversion ... int fprintf; ... write to the character string str. ...
    (comp.unix.programmer)
  • Re: Sets and portability (was) Re: Is ISO Pascal compatible with J&W (original) Pascal ?
    ... > So library code would be better if it could handle huge sets. ... widestring, in the future maybe also string). ... Note that ansi->wide conversion is codepage sensitive. ... compiler links in correct conversion code or table). ...
    (comp.lang.pascal.misc)
  • Re: Wrong data format?
    ... "K Dales" wrote: ... > easy conversion formula: ... > Public Function ConvertEBCDIC(ASCIIText As String) As ... > and you don't have to do anything but use the SendKeys ...
    (microsoft.public.excel.programming)

Loading