Search code examples
vb.netdoubletype-conversionfloating-point-conversion

Converting a Single To a Double


I am having an issue when converting Single values to Double values.

The singles provided by a BitStream are simple 2 to 6 place decimal numbers, in many cases, as simple as 0.4, 0.94, 0.6, etc. (I should note, the documentation I received states they are Floats(in Java), which from my understanding is the same as a Single in .NET.

I ultimately need these values as doubles as they will be used as coordinates for a Point3D Object (X, Y and Z), and ultimately used in the API of other applications where a Double is required also.

However, when I perform the conversion using CDbl(valueAsSingle) or Ctype(valueAsSingle, Double) the number has extra decimal places added to the Double, out in the 9th and later decimal place. This is causing issues in the applications that finally need to work with these values.

First, I'm curious why this is happening? Secondly, could issues arise if I simply convert the Single to a String, and then perform a Double.TryParse(valueAsString)

For reference, here is a very simple example.

Sub Main()
    Dim SingleX As Single = 0.4
    Dim SingleY As Single = 0.94
    Dim SingleZ As Single = 0.6

    Console.WriteLine(String.Concat("SX: ", SingleX, ControlChars.NewLine, "SY: ", SingleY, ControlChars.NewLine, "SZ: ", SingleZ, ControlChars.NewLine))

    Dim DoubleX As Double = CDbl(SingleX)
    Dim DoubleY As Double = CDbl(SingleY)
    Dim DoubleZ As Double = CDbl(SingleZ)

    Console.WriteLine(String.Concat("DX: ", DoubleX, ControlChars.NewLine, "DY: ", DoubleY, ControlChars.NewLine, "DZ: ", DoubleZ))

    Console.ReadLine()
End Sub

The results of which are

SX: 0.4
SY: 0.94
SZ: 0.6

DX: 0.400000005960464
DY: 0.939999997615814
DZ: 0.600000023841858

Solution

  • Ok, so with a pointer from a colleague, I've found this Wikipedia article that talks about Accuracy issues with Single Precision. I've got to admit my eyes glaze when reading it, but perhaps you will have a better time of it.

    I can't talk to your specific scenario, but ToStringing/Converting shouldn't have much of an issue. Alternatively you could round it as per Imrans answer.