14,690,191 members
Articles » General Programming » Programming Tips » General
Article
Posted 6 Jan 2017

20.3K views
10 bookmarked

# Float Point Numbers as Approximates & Using Errors

Rate me:
1 Apr 2017CPOL
Floating point numbers as approximates and understanding error happened when using single and double data types

CFloat.vb is a class to handle and explain float point numbers in VB.

## What are Floating-point Numbers

In computing, floating point is approximates. Floating point numbers are stored in binary format and converting from decimal number will return not the exact decimal number, but the nearest number to it that float point number can expose, as example: calculating 0.43 + 0.000001 - 0.430001, in C#, VB, VBA, Python, PHP, Java will not return 0!!

## Storage Diagram

Single is stored in 4 bytes = 32 bits as the following binary storage diagram. S is signal bit, E is Exponents bit & F is fraction bit.
Fraction is called mantissa too.

Binary format of Single precision number is as follows:

Please note that the patterns may have some little differ from one compiler to other

S EEEE EEEE FFF FFFF FFFF FFFF FFFF FFFF

 Memory Hexadecimal Signal Bit Exponent Hexadecimal Fraction Hexadecimal Epsilon Smallest positive number 1.4E-45 0000 0001 0 00 000 0001 Zero; +0! 0000 0000 0 00 000 0000 Negative Zero; -0! 8000 0000 1 00 000 0000 1! 3F80 0000 0 7F 000 0000 The smallest number > 1 1.00000012! 3F80 0001 0 7F 000 0001 Not a number; NaN FFC0 0000 1 FF 400 0000 Infinity; ∞ 0F80 0000 0 FF 000 0000 Negative Infinity; -∞ FF80 0000 1 FF 000 0000

Binary format of Double precision number is as given below:

S EEEE EEEE EEE FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF

 Memory Hexadecimal Signal Bit Exponent Hexadecimal Fraction Hexadecimal Epsilon Smallest positive number 5E-324 0000 0000 0000 0001 0 000 0 0000 0000 0001 Zero; +0# 0000 0000 0000 0000 0 000 0 0000 0000 0000 Negative Zero; -0# 8000 0000 0000 0000 1 000 0 0000 0000 0000 1# 3FF0 0000 0000 0000 0 3FF 0 0000 0000 0000 The smallest number > 1 1.0000000000000002# 3FF0 0000 0000 0001 0 3FF 0 0000 0000 0001 Not a number; NaN FFF8 0000 0000 0000 1 7FF 8 0000 0000 0000 Infinity; ∞ FF00 0000 0000 0000 0 7FF 0 0000 0000 0000 Negative Infinity; -∞ FFF0 0000 0000 0000 1 7FF 0 0000 0000 0000

## Unexpected Code Run Caused by Floating Point

Since floating point is approximates, then adding and mathematical operation does not always lead to the exact result.

```//C#
{
double V = 0;
V = 0.43 + 1E-06 - 0.430001;
if (V != 0) {
Interaction.MsgBox("It will go here!");
}
float f = 0;
f = 0.43f + 1E-06f - 0.430001f;
if (f != 0) {
Interaction.MsgBox("It will go here!");
}
}```
```'VB
Dim V As Double
V = 0.43# + 0.000001# - 0.430001#
If V <> 0 Then
MsgBox("It will go here!")
End If
Dim f As Single
f = 0.43! + 0.000001! - 0.430001!
If f <> 0 Then
MsgBox("It will go here!")
End If
End Sub```

Special values:

```'VB
Sub Test(x As Double)
If x > 0 Then
MsgBox("X > 0")
ElseIf x = 0 Then
MsgBox("X = 0")
ElseIf x < 0 Then
MsgBox("X < 0")
Else
MsgBox("This is a possible case! What is the value of X hear?")
Dim R =
(Double.NaN = 0) = False AndAlso
(Double.NaN < 0) = False AndAlso
(Double.NaN > 0) = False
End If
End Sub

Sub Test(x As Single)
If x > 0 Then
MsgBox("X > 0")
ElseIf x = 0 Then
MsgBox("X = 0")
ElseIf x < 0 Then
MsgBox("X < 0")
Else
MsgBox("This is a possible case! What is the value of X hear?")
Dim R =
(Single.NaN = 0) = False AndAlso
(Single.NaN < 0) = False AndAlso
(Single.NaN > 0) = False
End If
End Sub```
```//C#
public void Test(double x)
{
if (x > 0) {
Interaction.MsgBox("X > 0");
} else if (x == 0) {
Interaction.MsgBox("X = 0");
} else if (x < 0) {
Interaction.MsgBox("X < 0");
} else {
Interaction.MsgBox("This is a possible case! What is the value of X hear?");
dynamic R = (double.NaN == 0) == false && (double.NaN < 0) == false &&
(double.NaN > 0) == false;
}
}

public void Test(float x)
{
if (x > 0) {
Interaction.MsgBox("X > 0");
} else if (x == 0) {
Interaction.MsgBox("X = 0");
} else if (x < 0) {
Interaction.MsgBox("X < 0");
} else {
Interaction.MsgBox("This is a possible case! What is the value of X hear?");
dynamic R = (float.NaN == 0) == false &&
(float.NaN < 0) == false && (float.NaN > 0) == false;
}
}    ```

## How to Get Float Point Value from its Exponent and Fraction

The following function will get the `double` value of a float point number. The Exponent Bias and Fraction Base of the float point number is dependant on the type of floating point. See the table.

 Type Total Bits Exponent bias Fraction base Half 16 15 2^10 Single 32 127 2^23 Double 64 1023 2^52 Extended 82 16383 2^64 Quad 128 16383 2^112

The value of number is calculated from the formula:

Exponent <> 0:

Value = ±2^(Exponent - ExponentBias) * (1 + Fraction / FractionBase)

Exponent = 0:

Value = ±2^(1- ExponentBias) * ( Fraction / FractionBase)

```'VB
Function GetDoubleValue(IsNegative As Boolean, Exponent As UInt16,
Fraction As UInt64, ExponentBias As UInt16, FractionBase As UInt64) As Double
If Exponent = 0 Then
If Fraction = 0 Then
Return If(IsNegative, -0#, 0#)
End If
Dim FractionRatio = Fraction / FractionBase
Return If(IsNegative, -1#, 1#) * (2 ^ (1 - ExponentBias)) * FractionRatio
Else
If Exponent = 2 * ExponentBias + 1 Then
If Fraction = 0 Then
Return If(IsNegative, Double.NegativeInfinity, Double.PositiveInfinity)
Else
Return Double.NaN
End If
End If
Dim FractionRatio = Fraction / FractionBase
Return If(IsNegative, -1#, 1#) * (2 ^ (CInt(Exponent) - ExponentBias)) * (1# + FractionRatio)
End If
End Function```
```//C#
public double GetDoubleValue(bool IsNegative, UInt16 Exponent, UInt64 Fraction,
UInt16 ExponentBias, UInt64 FractionBase)
{
if (Exponent == 0) {
if (Fraction == 0) {
return IsNegative ? -0.0 : 0.0;
}
dynamic FractionRatio = Fraction / FractionBase;
return IsNegative ? -1.0 : 1.0 * (Math.Pow(2, (1 - ExponentBias))) * FractionRatio;
} else {
if (Exponent == 2 * ExponentBias + 1) {
if (Fraction == 0) {
return IsNegative ? double.NegativeInfinity : double.PositiveInfinity;
} else {
return double.NaN;
}
}
dynamic FractionRatio = Fraction / FractionBase;
return IsNegative ? -1.0 : 1.0 *
(Math.Pow(2, (Convert.ToInt32(Exponent) - ExponentBias))) * (1 + FractionRatio);
}
}```

### Database primary key and float point

Since float point is approximate number; it is not a good idea to use it as primary key in a database
For example
If we have a table named `Customers` with a field `id` with the data type single then
Referring to a one row may result no record even if record is in the database
When we insert 0.4301 as id the real id will be different a lite and may this result unexpected result in database update or select
The flowing sql may result no record and this is depend on the database drive and how it convert numbers form decimal to float point type

`Select Customer From Customers where id = 0.4301`

## About the Author

 Lebanon
ASP.Net Hosting on Linux server
---------------------------
There is a developer behind every piece of code!
DNA is too complex what about it!
No junk DNA; There is a functional role for noncoding DNA

## Comments and Discussions

 First Prev Next
 Nice article Avitevet28-Mar-17 16:33 Avitevet 28-Mar-17 16:33
 Re: Nice article NewPast28-Mar-17 22:40 NewPast 28-Mar-17 22:40
 Improper referencing Jochen Arndt3-Jan-17 22:45 Jochen Arndt 3-Jan-17 22:45
 Re: Improper referencing NewPast3-Jan-17 23:03 NewPast 3-Jan-17 23:03
 Re: Improper referencing Jochen Arndt3-Jan-17 23:58 Jochen Arndt 3-Jan-17 23:58
 My vote of 5 AntoineKieffer3-Jan-17 22:14 AntoineKieffer 3-Jan-17 22:14
 Last Visit: 24-Nov-20 6:32     Last Update: 24-Nov-20 6:32 Refresh 1

General    News    Suggestion    Question    Bug    Answer    Joke    Praise    Rant    Admin

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.