# Precision of Double Number Type

• ### Question

• I am trying to emulate the Nilakantha algorithm to calculate Pi. The formula is:
3 +  4/2×3×4 − 4/4×5×6 +  4/6×7×8 − 4/8×9×10, on and om as long as you can.

The issue I am having is that the value stops increasing after not too many iterations and there seems to a discrepancy between how Doubles are handled. below is a console app and a button click sub for a forms app. Any ideas as to why the results are different ?

```Console App Code:
Module Program
Sub Main(args As String())
Dim S As Double = CDbl("21,798,337,296,137,393")
Dim DT As Double
Dim div As Double = S * (S + 1) * (S + 2)
DT = 4D / div
Console.WriteLine(div.ToString("F"))
Console.WriteLine(DT.ToString("N92"))
End Sub
End Module
Results:
10357861630648208103056607550533164991842751610880.00
0.00000000000000000000000000000000000000000000000038618009610828085951635166931754374121291552

Forms Code Button Click:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim S As Double = CDbl("21,798,337,296,137,393")
Dim DT As Double
Dim div As Double = S * (S + 1) * (S + 2)
DT = 4D / div
TxtResults.AppendText(div.ToString("F") & vbNewLine)
TxtResults.AppendText(DT.ToString("N92"))
End Sub
Results:
10357861630648200000000000000000000000000000000000.00
0.00000000000000000000000000000000000000000000000038618009610828100000000000000000000000000000```

The code that does the work is here (in a Background Worker)

```    Private Sub BGWCalcPi_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BGWCalcPi.DoWork
Dim ModVal As Long = Iterations \ 100
Dim Pi As Decimal = 3D
Dim Numerator As Decimal = 4D
Dim Denominator As Decimal = 2D
'Dim Denom As Decimal
Dim Result As Decimal
For Count As Long = 1 To Iterations
Result = Numerator / Denominator ' three lines below are
Result /= Denominator + 1        ' to avoid overflows
Result /= Denominator + 2

If Count Mod 2 = 1 Then
Pi += Result
Else
Pi -= Result
End If
Denominator += 2D
If Count Mod ModVal = 0 Then
BGWCalcPi.ReportProgress(CInt((Count * 100) / Iterations))
End If
Next
PiString = Pi.ToString("N64")
End Sub```

The result does not change from using 100 million iterations and 100 billion iterations. Using Decimal type gives overflows.

Sunday, July 26, 2020 11:53 PM

• Hi,
double-precision binary floating-point format has 52 bit for fraction, see here. The conversion of 10 bits into a decimal representation results in 3 decimal places. 52 bits gives approximately 16 decimal places. With double precision you cannot get a better result.

Decimal data type allows 28 decimal places, the largest value is +/-7.9228162514264337593543950335, see here.

--
Best Regards / Viele Grüße
Peter Fleischer (former MVP for Developer Technologies)
Homepage, Tipps, Tricks

Monday, July 27, 2020 2:58 AM

### All replies

• Hi,
double-precision binary floating-point format has 52 bit for fraction, see here. The conversion of 10 bits into a decimal representation results in 3 decimal places. 52 bits gives approximately 16 decimal places. With double precision you cannot get a better result.

Decimal data type allows 28 decimal places, the largest value is +/-7.9228162514264337593543950335, see here.

--
Best Regards / Viele Grüße
Peter Fleischer (former MVP for Developer Technologies)
Homepage, Tipps, Tricks

Monday, July 27, 2020 2:58 AM
• Did you try your first Console code separately in a .NET Framework and .NET Core applications?
Monday, July 27, 2020 8:10 AM
• I get different results in Framework 4.8 an Core 3.1. This is a old known "feature" :-(

Core 3.1

10357861630648208103056607550533164991842751610880.00
0.00000000000000000000000000000000000000000000000038618009610828085951635166931754374121291552

Framework 4.8

10357861630648200000000000000000000000000000000000.00
0.00000000000000000000000000000000000000000000000038618009610828100000000000000000000000000000

--
Best Regards / Viele Grüße
Peter Fleischer (former MVP for Developer Technologies)
Homepage, Tipps, Tricks

Monday, July 27, 2020 9:52 AM
• The Forms snippet is .NET framework and the Console App is.NET Core

Monday, July 27, 2020 2:31 PM
• Hi Devon_Nullman,

The following blog shows the cause of this problem:

Floating-Point Parsing and Formatting improvements in .NET Core 3.0

If you test with versions prior to .NET Core 3.0, you will get the same results as in .NET framework.

Best Regards,

Xingyu Zhao

MSDN Community Support
Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

Tuesday, July 28, 2020 6:46 AM
• Here is the complete Console App code, using .NET core 3.1.0 {
```Imports System
Module Program
Sub Main(args As String())
Dim SW As New Stopwatch
Dim Iterations As Long = 10000000000
Dim ModVal As Integer = Iterations \ 100
Dim Pi As Decimal = 3D
Dim Numerator As Decimal = 4D
Dim Denominator As Decimal = 2D
Dim Result As Decimal
Console.WriteLine("Press Enter to start using " & Iterations.ToString("N0") & " Iterations")
SW.Reset()
SW.Start()

For Count As Long = 1 To Iterations
Result = Decimal.Divide(Numerator, Denominator)
Result = Decimal.Divide(Result, Denominator + 1D)
Result = Decimal.Divide(Result, Denominator + 2D)
If Count Mod 2 = 1 Then
Pi += Result
Else
Pi -= Result
End If
Denominator += 2D
If Count Mod ModVal = 0 Then
Console.SetCursorPosition(0, 1)
Console.Write((Count * 100) / Iterations & "% - " & Result.ToString("F64"))
End If
Next
SW.Stop()
Console.SetCursorPosition(0, 2)
Console.WriteLine("Done - took " & SW.Elapsed.ToString)
Console.WriteLine(Pi.ToString("F64"))
Console.WriteLine("3.14159265358979323846264338327") ' "Real" Pi
End Sub
End Module
```
Some results:
Using 10,000,000 Iterations
Done - took 00:00:04.3837711
3.14159265358979323846239327770
3.14159265358979323846264338327  (Real Value of Pi)

Using 100,000,000 Iterations
Done - took 00:00:41.8777270
3.14159265358979323846264303070
3.14159265358979323846264338327  (Real Value of Pi)

Using 1,000,000,000 Iterations
Done - took 00:07:07.61
3.14159265358979323846264328470
3.14159265358979323846264338327 (Real Value of Pi)

Using 10,000,000,000 Iterations
Done - took 01:09:26.57
3.14159265358979323846264328510
3.14159265358979323846264338327 (Real Value of Pi)

To me it seems like (and makes sense) that it would need an absurd number of Iterations just to get one more significant digit match.
Tuesday, July 28, 2020 2:36 PM