RosettaCodeData/Task/Arithmetic-geometric-mean/Visual-Basic-.NET/arithmetic-geometric-mean.v...

40 lines
1.6 KiB
Plaintext

Imports System
Imports System.Numerics
Module Module1
Function BIP(ByVal leadDig As Char, ByVal numDigs As Integer) As BigInteger
Return BigInteger.Parse(leadDig & New String("0", numDigs))
End Function
Function IntSqRoot(ByVal v As BigInteger) As BigInteger
Dim digs As Integer = Math.Max(0, v.ToString().Length / 2)
Dim term As BigInteger : IntSqRoot = BIP("3", digs)
While True
term = v / IntSqRoot
If Math.Abs(CDbl((term - IntSqRoot))) < 2 Then Exit While
IntSqRoot = (IntSqRoot + term) / 2
End While
End Function
Function CalcByAGM(ByVal digits As Integer) As BigInteger
Dim digs As Integer = digits + CInt((Math.Log(digits) / 2)), c As BigInteger,
d2 As Integer = digs * 2,
a As BigInteger = BIP("1", digs) ' initial value = 1
CalcByAGM = IntSqRoot(BIP("5", d2 - 1)) ' initial value = square root of 0.5
While True
c = a : a = ((a + CalcByAGM) / 2) : CalcByAGM = IntSqRoot(c * CalcByAGM)
If Math.Abs(CDbl((a - CalcByAGM))) <= 1 Then Exit While
End While
End Function
Sub Main(ByVal args As String())
Dim digits As Integer = 25000
If args.Length > 0 Then
Integer.TryParse(args(0), digits)
If digits < 1 OrElse digits > 999999 Then digits = 25000
End If
Console.WriteLine("0.{0}", CalcByAGM(digits).ToString())
If System.Diagnostics.Debugger.IsAttached Then Console.ReadKey()
End Sub
End Module