I'm working on how to translate this formula to obtain an approximation of PI (based on Brouncker's) to a stack machine.
The formula I'm working with is 4/(1 + 1^2/(2 + 3^2/(2 + 5^2/(2 + 7^2/(2 + 9^2/2)))))
which is roughly 2.97. How can I translate this to stack machine code?
This is what I have so far, but it's wrong:
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
(instructions are read from bottom to top)
It ends dividing 4 by 4.0909, but it should divide 4 by 1.344. There's some mathematical syntax that's wrong there, but I tried and haven't figured out where I'm wrong...
If needed, this is the class I've built for reading the instructions, it's in C# but it should be widely understood:
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
}
}
Edit: I solved this. My math syntax was a mess. The correct stack machine is:
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
You've translated
2 + 7^2/(..x..)
intox, 2, 2, 7, ^, +, /
(where x is the temporary stack result)?Wouldn't that result in
(2 + 7^2)/x
? Don't you wantx, 2, 7, ^, /, 2, +
?