使用 Stack 机使用 Brouncker 公式逼近 PI
Approximation of PI with Brouncker's formula using a Stack machine
我正在研究如何将此公式转换为堆栈计算机以获得 PI 的近似值(基于 Brouncker's)。
我正在使用的公式是 4/(1 + 1^2/(2 + 3^2/(2 + 5^2/(2 + 7^2/(2 + 9^2/2)))))
,大约是 2.97。我如何将其翻译成堆栈机器代码?
这是我目前所知道的,但它是错误的:
DIV
PUSH 4
DIV
ADD
PUSH 1
POW
PUSH 1
PUSH 2
DIV
ADD
POW
PUSH 3
PUSH 2
PUSH 2
DIV
ADD
POW
PUSH 5
PUSH 2
PUSH 2
DIV
ADD
POW
PUSH 7
PUSH 2
PUSH 2
ADD
DIV
POW
PUSH 9
PUSH 2
PUSH 2
PUSH 2
(说明是从下往上读的)
4 除以 4.0909 结束,但 4 除以 1.344 应该结束。
那里有一些数学语法是错误的,但我试过了但还没有弄清楚我错在哪里...
如果需要,这是我为阅读说明而构建的class,它是用 C# 编写的,但应该被广泛理解:
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
namespace Máquinas
{
/**
* @author toyomitsu
*
* @date - 2020.05.17
*/
public class StackMachine
{
private Stack<string> _Stack;
private string[] _Instructions;
public StackMachine(string[] Instructions)
{
Array.Reverse(Instructions);
_Stack = new Stack<string>();
_Instructions = Instructions;
}
public void PerformInstructions()
{
Console.WriteLine();
Console.WriteLine("*** Stack machine ***");
foreach (string Instruction in _Instructions)
{
string[] InstData = Instruction.Split(' ');
switch (InstData[0])
{
case "PUSH":
Push(InstData[1]);
break;
case "POP":
Pop();
break;
case "ADD":
Add();
break;
case "SUB":
Sub();
break;
case "MOD":
Mod();
break;
case "MUL":
Mul();
break;
case "DIV":
Div();
break;
case "POW":
Pow();
break;
case "SQR":
Sqr();
break;
case "EXP":
Exp();
break;
default:
continue;
}
List<string> Registry = _Stack.ToList<string>();
Console.WriteLine();
Console.WriteLine(string.Format("** Instruction: {0} **", Instruction));
for (int i = 0; i < Registry.Count; i++)
{
Console.WriteLine(string.Format("Registry {0}: {1}", i + 1, Registry[i]));
}
Console.WriteLine("**********************");
}
}
#region Functions
private void Push(string Data)
{
_Stack.Push(Data);
}
private string Pop()
{
return _Stack.Pop();
}
private void Add()
{
string Data1 = Pop();
string Data2 = Pop();
double Num1 = double.Parse(Data1, CultureInfo.InvariantCulture);
double Num2 = double.Parse(Data2, CultureInfo.InvariantCulture);
double Result = Num1 + Num2;
Push(Result.ToString(CultureInfo.InvariantCulture));
}
private void Sub()
{
string Data1 = Pop();
string Data2 = Pop();
double Num1 = double.Parse(Data1, CultureInfo.InvariantCulture);
double Num2 = double.Parse(Data2, CultureInfo.InvariantCulture);
double Result = Num1 - Num2;
Push(Result.ToString(CultureInfo.InvariantCulture));
}
private void Mul()
{
string Data1 = Pop();
string Data2 = Pop();
double Num1 = double.Parse(Data1, CultureInfo.InvariantCulture);
double Num2 = double.Parse(Data2, CultureInfo.InvariantCulture);
double Result = Num1 * Num2;
Push(Result.ToString(CultureInfo.InvariantCulture));
}
private void Mod()
{
string Data1 = Pop();
string Data2 = Pop();
double Num1 = double.Parse(Data1, CultureInfo.InvariantCulture);
double Num2 = double.Parse(Data2, CultureInfo.InvariantCulture);
double Result = Num1 % Num2;
Push(Result.ToString(CultureInfo.InvariantCulture));
}
private void Div()
{
string Data1 = Pop();
string Data2 = Pop();
double Num1 = double.Parse(Data1, CultureInfo.InvariantCulture);
double Num2 = double.Parse(Data2, CultureInfo.InvariantCulture);
double Result = Num1 / Num2;
Push(Result.ToString(CultureInfo.InvariantCulture));
}
private void Pow()
{
string Data1 = Pop();
string Data2 = Pop();
double Num1 = double.Parse(Data1, CultureInfo.InvariantCulture);
double Num2 = double.Parse(Data2, CultureInfo.InvariantCulture);
double Result = Math.Pow(Num1, Num2);
Push(Result.ToString(CultureInfo.InvariantCulture));
}
private void Sqr()
{
string Data1 = Pop();
double Num1 = double.Parse(Data1, CultureInfo.InvariantCulture);
double Result = Math.Sqrt(Num1);
Push(Result.ToString(CultureInfo.InvariantCulture));
}
private void Exp()
{
string Data1 = Pop();
double Num1 = double.Parse(Data1, CultureInfo.InvariantCulture);
double Result = Math.Exp(Num1);
Push(Result.ToString(CultureInfo.InvariantCulture));
}
#endregion
}
}
编辑:
我解决了这个。我的数学语法一团糟。
正确的叠机是:
DIV
PUSH 4
ADD
PUSH 1
DIV
POW
PUSH 1
PUSH 2
ADD
PUSH 2
DIV
POW
PUSH 3
PUSH 2
ADD
PUSH 2
DIV
POW
PUSH 5
PUSH 2
ADD
PUSH 2
DIV
POW
PUSH 7
PUSH 2
ADD
PUSH 2
DIV
POW
PUSH 9
PUSH 2
PUSH 2
您已将 2 + 7^2/(..x..)
翻译成 x, 2, 2, 7, ^, +, /
(其中 x 是临时堆栈结果)?
这不会导致 (2 + 7^2)/x
吗?你不想x, 2, 7, ^, /, 2, +
吗?
我正在研究如何将此公式转换为堆栈计算机以获得 PI 的近似值(基于 Brouncker's)。
我正在使用的公式是 4/(1 + 1^2/(2 + 3^2/(2 + 5^2/(2 + 7^2/(2 + 9^2/2)))))
,大约是 2.97。我如何将其翻译成堆栈机器代码?
这是我目前所知道的,但它是错误的:
DIV
PUSH 4
DIV
ADD
PUSH 1
POW
PUSH 1
PUSH 2
DIV
ADD
POW
PUSH 3
PUSH 2
PUSH 2
DIV
ADD
POW
PUSH 5
PUSH 2
PUSH 2
DIV
ADD
POW
PUSH 7
PUSH 2
PUSH 2
ADD
DIV
POW
PUSH 9
PUSH 2
PUSH 2
PUSH 2
(说明是从下往上读的)
4 除以 4.0909 结束,但 4 除以 1.344 应该结束。 那里有一些数学语法是错误的,但我试过了但还没有弄清楚我错在哪里...
如果需要,这是我为阅读说明而构建的class,它是用 C# 编写的,但应该被广泛理解:
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
namespace Máquinas
{
/**
* @author toyomitsu
*
* @date - 2020.05.17
*/
public class StackMachine
{
private Stack<string> _Stack;
private string[] _Instructions;
public StackMachine(string[] Instructions)
{
Array.Reverse(Instructions);
_Stack = new Stack<string>();
_Instructions = Instructions;
}
public void PerformInstructions()
{
Console.WriteLine();
Console.WriteLine("*** Stack machine ***");
foreach (string Instruction in _Instructions)
{
string[] InstData = Instruction.Split(' ');
switch (InstData[0])
{
case "PUSH":
Push(InstData[1]);
break;
case "POP":
Pop();
break;
case "ADD":
Add();
break;
case "SUB":
Sub();
break;
case "MOD":
Mod();
break;
case "MUL":
Mul();
break;
case "DIV":
Div();
break;
case "POW":
Pow();
break;
case "SQR":
Sqr();
break;
case "EXP":
Exp();
break;
default:
continue;
}
List<string> Registry = _Stack.ToList<string>();
Console.WriteLine();
Console.WriteLine(string.Format("** Instruction: {0} **", Instruction));
for (int i = 0; i < Registry.Count; i++)
{
Console.WriteLine(string.Format("Registry {0}: {1}", i + 1, Registry[i]));
}
Console.WriteLine("**********************");
}
}
#region Functions
private void Push(string Data)
{
_Stack.Push(Data);
}
private string Pop()
{
return _Stack.Pop();
}
private void Add()
{
string Data1 = Pop();
string Data2 = Pop();
double Num1 = double.Parse(Data1, CultureInfo.InvariantCulture);
double Num2 = double.Parse(Data2, CultureInfo.InvariantCulture);
double Result = Num1 + Num2;
Push(Result.ToString(CultureInfo.InvariantCulture));
}
private void Sub()
{
string Data1 = Pop();
string Data2 = Pop();
double Num1 = double.Parse(Data1, CultureInfo.InvariantCulture);
double Num2 = double.Parse(Data2, CultureInfo.InvariantCulture);
double Result = Num1 - Num2;
Push(Result.ToString(CultureInfo.InvariantCulture));
}
private void Mul()
{
string Data1 = Pop();
string Data2 = Pop();
double Num1 = double.Parse(Data1, CultureInfo.InvariantCulture);
double Num2 = double.Parse(Data2, CultureInfo.InvariantCulture);
double Result = Num1 * Num2;
Push(Result.ToString(CultureInfo.InvariantCulture));
}
private void Mod()
{
string Data1 = Pop();
string Data2 = Pop();
double Num1 = double.Parse(Data1, CultureInfo.InvariantCulture);
double Num2 = double.Parse(Data2, CultureInfo.InvariantCulture);
double Result = Num1 % Num2;
Push(Result.ToString(CultureInfo.InvariantCulture));
}
private void Div()
{
string Data1 = Pop();
string Data2 = Pop();
double Num1 = double.Parse(Data1, CultureInfo.InvariantCulture);
double Num2 = double.Parse(Data2, CultureInfo.InvariantCulture);
double Result = Num1 / Num2;
Push(Result.ToString(CultureInfo.InvariantCulture));
}
private void Pow()
{
string Data1 = Pop();
string Data2 = Pop();
double Num1 = double.Parse(Data1, CultureInfo.InvariantCulture);
double Num2 = double.Parse(Data2, CultureInfo.InvariantCulture);
double Result = Math.Pow(Num1, Num2);
Push(Result.ToString(CultureInfo.InvariantCulture));
}
private void Sqr()
{
string Data1 = Pop();
double Num1 = double.Parse(Data1, CultureInfo.InvariantCulture);
double Result = Math.Sqrt(Num1);
Push(Result.ToString(CultureInfo.InvariantCulture));
}
private void Exp()
{
string Data1 = Pop();
double Num1 = double.Parse(Data1, CultureInfo.InvariantCulture);
double Result = Math.Exp(Num1);
Push(Result.ToString(CultureInfo.InvariantCulture));
}
#endregion
}
}
编辑: 我解决了这个。我的数学语法一团糟。 正确的叠机是:
DIV
PUSH 4
ADD
PUSH 1
DIV
POW
PUSH 1
PUSH 2
ADD
PUSH 2
DIV
POW
PUSH 3
PUSH 2
ADD
PUSH 2
DIV
POW
PUSH 5
PUSH 2
ADD
PUSH 2
DIV
POW
PUSH 7
PUSH 2
ADD
PUSH 2
DIV
POW
PUSH 9
PUSH 2
PUSH 2
您已将 2 + 7^2/(..x..)
翻译成 x, 2, 2, 7, ^, +, /
(其中 x 是临时堆栈结果)?
这不会导致 (2 + 7^2)/x
吗?你不想x, 2, 7, ^, /, 2, +
吗?