Osnovne računske operacije 2



Program "Basic arithmetic operations 2" sa povećanom preciznošću

Da li ste se ikad zapitali: "Kako da s Vašim ultra modernim kompjuterom, s višejezgarnim procesorom koji je sposoban da odradi više milijardi prostih matematičkih operacija u sekundi, izračunate kvadratni koren broja dva s preciznošću na stotinu decimalnih mesta ?".

SQRT ( 2 ) = 1,4142135623730950488016887242096980785696718753769480731766797379907324784621070388503875343276415727

Ili: "Kako da podelite dva broja koji sadrže više hiljada cifara kako u svom celobrojnom tako i u razlomljenom delu, s preciznošću na, recimo , tridesethiljada decimalnih mesta ?".

Iako problemi koji se tiču visoke preciznosti matematičkih proračuna, ili proračuna s izuzetno velikim ili ekstremno malim brojevima ne spadaju u svakidašnje, vrlo je realna mogućnost za programera da se u svojoj karijeri susretne i s njima. Program "Basic arithmetic operations 2" omogućava izvršavanje četiri proste matematičke operacije nad skupom realnih brojeva ( + , - , * , / ). Veličina (opseg) realnih brojeva i preciznost rezultata zavise isključivo od kapaciteta memorije i brzine Vašeg kompjutera. U programu je broj cifara koje realan broj unet od strane korisnika može da sadrži ograničen na hiljadu, a preciznost rezultata do hiljadu decimalnih mesta. Ukoliko raspolažete sporijim kompjuterom preporuka je da preciznost rezultata ne prelazi stotinu decimalnih mesta za operaciju korenovanja. Opseg brojeva koje korisnik programa može da unese je (-1E+1000 , -1E-1000) za negativne, i (+1E-1000 , +1E+1000) za pozitivne realne brojeve. Opseg rezultata je drugačiji. Reprogramiranjem, ove vrednosti mogu da se promene. U osnovi algoritama za sve četiri matematičke operacije je elementarna algebra, za čije razumevanje je dovoljno proučiti dole priloženi programski kod.

Napomena o preciznosti programa :

Poređenjem s nekim drugim kalkulatorima, kod kojih je rezultat najčešće zaokružen na poslednjoj cifri, SVE CIFRE unutar rezultata prikazanog korisniku programa, u skladu s odabranom preciznošću rezultata, su VIDLJIVE i TAČNE.

Ako se izabere opcija "Izračunaj sa povećanom‎ ‎preciznošću", ako je to moguće, preciznost rezultata‎ ‎funkcija SQRT i DIV se povećava analizom malih promena poslednje cifre rezultata i generisane vrednosti greške, imajući u vidu izabranu preciznost. ‎‎Rezultat sa najmanjom greškom u izračunavanju je prihvaćen kao konačan rezultat.‎

Program možete preuzeti klikom na sliku ispod ili na linku na dnu strane, gde se nalazi i link za preuzimanje dokumenata s otvorenim kodom programa.Za ispravan rad programa neophodan je Majkrosoftov .Net frejmvork 4.0 ( ^ ) !

/************************************************************************************************

* Program name : Basic arithmetic operations 2 ( Long real numbers / High result precision ) *

* Program ver. : 3.1 *

* Created by : SharpDevelop *

* Code author : Perić Željko *

* Code language : C# *

* Date created : 05.10.2013 *

* Time created : 19:00 *

* *

* *

* Program Description : *

* *

* Windows form application for high precision, basic arithmetic operations with real numbers. *

* Long real number therm describes real number that consists of thousands of digits, *

* integral part as well as fractional part. Lenght of numbers, and precision of calculations, *

* are limited only with quantity of RAM inside computer. Since personal computers are too *

* slow for such calculations, it is recomended to limit the lenght of entered numbers *

* up to 1000 digits, and result precision up to maximum 1000 decimal places. *

* *

* Accuracy Notice: *

* Comparing with some other calculators, where results are usually rounded at last digit, *

* ALL DIGITS inside result, considering selected precision, are VISIBLE and CORRECT. *

* *

* If option 'Calculate with increased precision' is checked, if it is possible, *

* precision of result of SQRT and DIV function is increased by analyzing small changes of *

* last digit in result and value of error generated, considering selected precision. *

* Result with smallest error in calculation is accepted as final result. *

* *

* All the best, *

* Author. *

************************************************************************************************/

using System;

using System.Numerics;

using System.Windows.Forms;


namespace Basic_arithmetic_operations_2

{

public partial class MainForm : Form

{

//

// Begining of MainForm class

//

#region- Declaration of Global variables -

//

// Declaration of global variables

//

// Notice:

//

// Result_Precision have different meaning from Function_Precision.

//

// Result_Precision refers to final Result precision that is going to be shown to user,

// for this is written SetResultPrecision(string A) function,

// that simply cuts of all decimals from Result that exceeds Result_Precision limit.

// There is no rounding.

//

// Function_Precision, limits the precision of Math functions,

// and also prevents that program becomes too slow.

// Value of this variable shall be the condition

// to stop calculation loop inside Math functions,

// if result can be calculated at more decimal places than the specified precision.

//

// Values of these two variables can be different, but speed of program depends only

// from value of Function_Precision.

//

// Function_Precision value can't be smaller or equal to Result_Precision value.

//

// Recomended : Function_Precision = Result_Precision + 1;

//

// Quantity of RAM needed for calculations

// depends on value of Max_Lenght_Of_Entered_Numbers.

//

int Max_Lenght_Of_Entered_Number = 100002;

int Result_Precision = 100;

string Number_Decimal_Separator = String.Empty;

const string Zero = "0";

const string One = "1";

const string Three = "3";

const string Ten = "10";

#endregion

#region- Main form inicialization -

public MainForm()

{

//

// The InitializeComponent() call is required for Windows Forms designer support.

//

InitializeComponent();

//

// Set max lenght of entered number

//

textBox1.MaxLength = Max_Lenght_Of_Entered_Number;

textBox2.MaxLength = Max_Lenght_Of_Entered_Number;

//

// Set Number Decimal Separator upon local regional settings

//

Number_Decimal_Separator =

Application.CurrentCulture.NumberFormat.NumberDecimalSeparator;


// Set initial textbox values

textBox1.Text = "0" + Number_Decimal_Separator + "0";

textBox2.Text = "0" + Number_Decimal_Separator + "0";

}

#endregion

#region - Button click events -

//

// Add button clicked event

// It raises when user clicks on Add button

// Takes values from textBox1 and textBox2 and calls ADD function

// After getting result from ADD function,

// calls function ClearZerosFromNumber & SetResultPrecision

// for formating result and shows result in textBox3

//

void AddButton(object sender, EventArgs e)

{

string Number_X;

string Number_Y;

string Result;

string Error;


Number_X = textBox1.Text;

Number_Y = textBox2.Text;

Result = String.Empty;

Error = String.Empty;

Result = ADD( Number_X , Number_Y );

Result = SetResultPrecision( Result );

Result = ClearZerosFromNumber( Result );

textBox3.Text = Result;

textBox4.Text = Error;

}


//

// Sub button clicked event

// It Raises when user clicks on Sub button

// Takes values from textBox1 and textBox2 and calls SUB function

// After getting result from SUB function,

// calls function ClearZerosFromNumber & SetResultPrecision

// for formating result and shows result in textBox3

//

void SubButton(object sender, EventArgs e)

{

string Number_X;

string Number_Y;

string Result;

string Error;

Number_X = textBox1.Text;

Number_Y = textBox2.Text;

Result = String.Empty;

Error = String.Empty;

Result = SUB( Number_X , Number_Y );

Result = SetResultPrecision( Result );

Result = ClearZerosFromNumber( Result );

textBox3.Text = Result;

textBox4.Text = Error;

}


//

// Mul button clicked event

// It Raises when user click on Mul button

// Takes values from textBox1 and textBox2 and calls MUL function

// After getting result from MUL function,

// calls function ClearZerosFromNumber & SetResultPrecision

// for formating result and shows result in textBox3

//

void MulButton(object sender, EventArgs e)

{

string Number_X;

string Number_Y;

string Result;

string Error;

Number_X = textBox1.Text;

Number_Y = textBox2.Text;

Result = String.Empty;

Error = String.Empty;

Result = MUL( Number_X , Number_Y );

Result = SetResultPrecision( Result );

Result = ClearZerosFromNumber( Result );

textBox3.Text = Result;

textBox4.Text = Error;

}

//

// Div button clicked event

// It Raises when user click on Div button

// Takes values from textBox1 and textBox2 and calls DIV function

// After getting result from DIV function,

// calls function ClearZerosFromNumber & SetResultPrecision

// for formating result and shows result in textBox3

// Finds and shows error of DIV function

//

//

void DivButton(object sender, EventArgs e)

{

string Comma = Number_Decimal_Separator;

string Number_X;

string Number_Y;

string Result;

string Error;


int Function_Precision;

Number_X = textBox1.Text;

Number_Y = textBox2.Text;

Result = String.Empty;

Error = String.Empty;

Function_Precision = Result_Precision + 1;

if ( Number_Y != (Zero + Comma + Zero) )

{

Result = DIV( Number_X , Number_Y , Function_Precision );

Result = SetResultPrecision( Result );

if(Increase_Precision_Check.Checked)

{

Result = Improve_DIV_Precision(Number_X, Number_Y, Result);

Result = SetResultPrecision( Result );

}

Result = ClearZerosFromNumber( Result );

textBox3.Text = Result;

Error = MUL( Number_Y, Result );

Error = SetResultPrecision( Error );

Error = ClearZerosFromNumber( Error );

Error = SUB( Error, Number_X);

Error = SetResultPrecision( Error );

Error = ClearZerosFromNumber( Error );

textBox4.Text = Error.ToString();

}

else

{

MessageBox.Show( "Attempt of dividing by zero ! " , " Entry error",

MessageBoxButtons.OK,MessageBoxIcon.Error );

}

}

//

// SQRT button clicked event

// It Raises when user click on SQRT button

// Takes value from textBox1 and calls SQRT function

// After getting result from SQRT function,

// calls function ClearZerosFromNumber & SetResultPrecision

// for formating result and shows result in textBox3

// Finds and shows error of SQRT function

//

void SQRTButton(object sender, EventArgs e)

{

//

// Value of number must be positive

//

if(!textBox1.Text.Contains("-"))

{

string Number_X;

string Result;

string Error;

int Function_Precision;

Number_X = textBox1.Text;

Result = String.Empty;

Error = String.Empty;

Function_Precision = Result_Precision + 1;

Result = SQRT( Number_X , Function_Precision );

Result = SetResultPrecision( Result );


if(Increase_Precision_Check.Checked)

Result = Improve_SQRT_Precision(Number_X, Result);

Result = SetResultPrecision( Result );

Result = ClearZerosFromNumber( Result );

textBox3.Text = Result;

Error = MUL( Result, Result );

Error = SetResultPrecision( Error );


Error = SUB( Error, Number_X);

Error = SetResultPrecision( Error );

Error = ClearZerosFromNumber( Error );

textBox4.Text = Error;

}

else

{

MessageBox.Show( "Number must be positive ! " , " Entry error",

MessageBoxButtons.OK,MessageBoxIcon.Error );

}

}

#endregion

#region - Math functions -

//

// ADD function

// Takes two arguments type of string,

// that represents real numbers for Add ( + ) operation

// Returns result as type of string

//

string ADD(string A , string B)

{

BigInteger X;

BigInteger Y;

BigInteger Z;


string Comma = Number_Decimal_Separator;

string Sign;

string [] Decimal_Float_X = new string[2];

string [] Decimal_Float_Y = new string[2];

string Number_X;

string Number_Y;

string Result;

int X_Lenght;

int Y_Lenght;

int Comma_Position;

int Comma_Counter;

X = 0;

Y = 0;

Z = 0;

Sign = String.Empty;

Number_X = String.Empty;

Number_Y = String.Empty;

Result = String.Empty;

X_Lenght = 0;

Y_Lenght = 0;

Comma_Position = 0;

Comma_Counter = 0;

Decimal_Float_X = A.Split( Comma[0] );

Decimal_Float_Y = B.Split( Comma[0] );

Number_X = Decimal_Float_X[1];

Number_Y = Decimal_Float_Y[1];

X_Lenght = Number_X.Length;

Y_Lenght = Number_Y.Length;

if ( X_Lenght > Y_Lenght )

{

Comma_Position = X_Lenght;

while ( Y_Lenght < X_Lenght )

{

Number_Y = Number_Y + Zero;

Y_Lenght++;

}

}

else

{

Comma_Position = Y_Lenght;

while ( X_Lenght < Y_Lenght )

{

Number_X = Number_X + "0";

X_Lenght++;

}

}

Comma_Counter = Comma_Position;

Number_X = Decimal_Float_X[0] + Number_X;

Number_Y = Decimal_Float_Y[0] + Number_Y;

X = BigInteger.Parse( Number_X );

Y = BigInteger.Parse( Number_Y );

Z = BigInteger.Add( X , Y );

Result = Z.ToString();

if( Result.Contains( "-" ) )

{

Sign = "-";

Result = Result.Remove(0,1);

}

if ( Result == Zero )

{

Result = Zero + Comma + Zero;

Comma_Position = 1;

}

else if ( Comma_Position == Result.Length )

{

Result = Result.Insert( 0 , Zero );

}

else if ( Comma_Position > Result.Length )

{

while ( Comma_Counter > 0 )

{

Result = Result.Insert( 0 , Zero );

Comma_Counter = Comma_Counter - 1;

}

}

Result = Result.Insert( Result.Length - Comma_Position , Comma );

Result = Result.Insert( 0,Sign );

Result = ClearZerosFromNumber( Result );

return Result;

}

//

// SUB function

// Takes two arguments type of string,

// that represents real numbers for Sub ( - ) operation

// Returns result as type of string

//

string SUB(string A , string B)

{

BigInteger X;

BigInteger Y;

BigInteger Z;


string Comma = Number_Decimal_Separator;

string Sign;

string [] Decimal_Float_X = new string[2];

string [] Decimal_Float_Y = new string[2];

string Number_X;

string Number_Y;

string Result;

int X_Lenght;

int Y_Lenght;

int Comma_Position;

int Comma_Counter;

X = 0;

Y = 0;

Z = 0;

Sign = String.Empty;

Number_X = String.Empty;

Number_Y = String.Empty;

Result = String.Empty;

X_Lenght = 0;

Y_Lenght = 0;

Comma_Position = 0;

Comma_Counter = 0;

Decimal_Float_X = A.Split( Comma[0] );

Decimal_Float_Y = B.Split( Comma[0] );

Number_X = Decimal_Float_X[1];

Number_Y = Decimal_Float_Y[1];

X_Lenght = Number_X.Length;

Y_Lenght = Number_Y.Length;

if ( X_Lenght > Y_Lenght )

{

Comma_Position = X_Lenght;

while ( Y_Lenght < X_Lenght )

{

Number_Y = Number_Y + Zero;

Y_Lenght++;

}

}

else

{

Comma_Position = Y_Lenght;

while ( X_Lenght < Y_Lenght )

{

Number_X = Number_X + Zero;

X_Lenght++;

}


}

Comma_Counter = Comma_Position;

Number_X = Decimal_Float_X[0] + Number_X;

Number_Y = Decimal_Float_Y[0] + Number_Y;

X = BigInteger.Parse( Number_X );

Y = BigInteger.Parse( Number_Y );

Z = BigInteger.Subtract( X , Y );

Result = Z.ToString();

if( Result.Contains( "-" ) )

{

Sign = "-";

Result = Result.Remove(0,1);

}

if ( Result == Zero )

{

Result = Zero + Comma + Zero;

Comma_Position = 1;

}

else if ( Comma_Position == Result.Length )

{

Result = Result.Insert( 0 , Zero );

}

else if ( Comma_Position > Result.Length )

{

while ( Comma_Counter > 0 )

{

Result = Result.Insert( 0 , Zero );

Comma_Counter = Comma_Counter - 1;

}

}

Result = Result.Insert( Result.Length - Comma_Position , Comma );

Result = Result.Insert( 0 , Sign );

Result = ClearZerosFromNumber( Result );

return Result;

}


//

// MUL function

// Takes two arguments type of string,

// that represents real numbers for Mul ( x ) operation

// Returns result as type of string

//

string MUL(string A , string B)

{


BigInteger X;

BigInteger Y;

BigInteger Z;


string Comma = Number_Decimal_Separator;

string Sign;

string [] Decimal_Float_X = new string[2];

string [] Decimal_Float_Y = new string[2];

string Number_X;

string Number_Y;

string Result;

int X_Lenght;

int Y_Lenght;

int Comma_Position;

int Comma_Counter;

X = 0;

Y = 0;

Z = 0;

Sign = String.Empty;

Number_X = String.Empty;

Number_Y = String.Empty;

Result = String.Empty;

X_Lenght = 0;

Y_Lenght = 0;

Comma_Position = 0;

Comma_Counter = 0;

Decimal_Float_X = A.Split( Comma[0] );

Decimal_Float_Y = B.Split( Comma[0] );

Number_X = Decimal_Float_X[1];

Number_Y = Decimal_Float_Y[1];

X_Lenght = Number_X.Length;

Y_Lenght = Number_Y.Length;

if ( X_Lenght > Y_Lenght )

{

while ( Y_Lenght < X_Lenght )

{

Number_Y = Number_Y + Zero;

Y_Lenght++;

}

}

else

{

while ( X_Lenght < Y_Lenght )

{

Number_X = Number_X + Zero;

X_Lenght++;

}


}

Comma_Position = X_Lenght + Y_Lenght;

Comma_Counter = Comma_Position;

Number_X = Decimal_Float_X[0] + Number_X;

Number_Y = Decimal_Float_Y[0] + Number_Y;

X = BigInteger.Parse( Number_X );

Y = BigInteger.Parse( Number_Y );

Z = BigInteger.Multiply( X , Y );

Result = Z.ToString();

if( Result.Contains( "-" ) )

{

Sign = "-";

Result = Result.Remove(0,1);

}

if ( Result == Zero )

{

Result = Zero + Comma + Zero;

Comma_Position = 1;

}

else if ( Comma_Position == Result.Length )

{

Result = Result.Insert( 0 , Zero );

}

else if ( Comma_Position > Result.Length )

{

while ( Comma_Counter > 0 )

{

Result = Result.Insert( 0 , Zero );

Comma_Counter = Comma_Counter - 1;

}

}

Result = Result.Insert( Result.Length - Comma_Position , Comma );

Result = Result.Insert( 0 , Sign );

Result = ClearZerosFromNumber( Result );

return Result;

}


//

// DIV function

// Takes two arguments type of string,

// that represents real numbers for Div ( / ) operation

// Returns result as type of string

//

string DIV(string A , string B , int Function_Precision )

{

BigInteger X;

BigInteger Y;

BigInteger Z;

BigInteger Remainder;

string Comma = Number_Decimal_Separator;

string [] Decimal_Float_X = new string[2];

string [] Decimal_Float_Y = new string[2];

string Number_X;

string Number_Y;

string Result;

string Helper;

int X_Lenght;

int Y_Lenght;

X = 0;

Y = 0;

Z = 0;

Remainder = 0;

Number_X = String.Empty;

Number_Y = String.Empty;

Result = String.Empty;

Helper = String.Empty;

X_Lenght = 0;

Y_Lenght = 0;

Decimal_Float_X = A.Split( Comma[0] );

Decimal_Float_Y = B.Split( Comma[0] );

Number_X = Decimal_Float_X[1];

Number_Y = Decimal_Float_Y[1];

X_Lenght = Number_X.Length;

Y_Lenght = Number_Y.Length;

if ( X_Lenght > Y_Lenght )

{

while ( Y_Lenght < X_Lenght )

{

Number_Y = Number_Y + Zero;

Y_Lenght++;

}

}

else

{

while ( X_Lenght < Y_Lenght)

{

Number_X = Number_X + Zero;

X_Lenght++;

}


}

Number_X = Decimal_Float_X[0] + Number_X;

Number_Y = Decimal_Float_Y[0] + Number_Y;

X = BigInteger.Parse( Number_X );

Y = BigInteger.Parse( Number_Y );

if ( X < 0 && Y > 0 )

{

X = X * -1;

Result = Result.Insert( 0 , "-" );

}

if ( X > 0 && Y < 0 )

{

Y = Y * -1;

Result = Result.Insert( 0 , "-" );

}

if

( X < 0 && Y < 0 )

{

X = X * -1;

Y = Y * -1;

}

Z = BigInteger.DivRem( X , Y , out Remainder );

Result = Result + Z.ToString();

if ( Remainder != 0 )

{

Result = Result + Comma;

while ( Remainder != 0 )

{

X = BigInteger.Multiply( Remainder , 10 );

Z = BigInteger.DivRem( X , Y , out Remainder );

if ( Z == 0 )

{

Result = Result + Zero;

}

else

{

Result = Result + Z.ToString();

}

Function_Precision--;

if ( Function_Precision == 0 )

{

Remainder = 0;

}

}

}

Result = ClearZerosFromNumber( Result );

return Result;

}

//

// Improve DIV Precision function

// Takes two arguments type of string,

// that represents real numbers for CHECK operation

// Returns result as type of string

//

string Improve_DIV_Precision( string A, string B, string C)

{

string Comma = Number_Decimal_Separator;

string Addend;

string Error_1;

string Error_2;

string Error_3;


string Error_A;

string Error_B;

string Error_C;

string Result;

Addend = String.Empty;

Addend += Zero + Comma;

for(int i=0;i<Result_Precision-1;i++)

{

Addend += Zero;

}

Addend += One;

Error_1 = String.Empty;;

Error_2 = String.Empty;;

Error_3 = String.Empty;;

Error_A = String.Empty;;

Error_B = String.Empty;;

Error_C = String.Empty;;

Result = String.Empty;;

Result = MUL( B, C);

Result = SetResultPrecision( Result );

Result = ClearZerosFromNumber( Result );

Error_1 = SUB( Result, A );

if(Error_1 == ( Zero + Comma + Zero ))

{

return C;

}

Error_A = Error_1.Replace("-", "");

Result = ADD( C, Addend );

Result = MUL( Result, B);

Result = SetResultPrecision( Result );

Result = ClearZerosFromNumber( Result );

Error_2 = SUB( Result, A );

Error_B = Error_2.Replace("-", "");

Result = SUB( C, Addend );

Result = MUL( Result, B );

Result = SetResultPrecision( Result );

Result = ClearZerosFromNumber( Result );

Error_3 = SUB( Result, A );

Error_C = Error_3.Replace("-", "");

if( CMP(Error_A, Error_B) == "<" && CMP(Error_A, Error_C) == "<" )

C = C;

else if( CMP(Error_B, Error_A) == "<" && CMP(Error_B, Error_C) == "<" )

C = ADD( C, Addend );

else if( CMP(Error_C, Error_A) == "<" && CMP(Error_C, Error_B) == "<" )

C = SUB( C, Addend );

return C;

}

//

// SQRT function

// Takes one argument type of string,

// that represents real number for SQRT ( Square root ) operation

// Returns result as type of string

//

string SQRT(string A, int Function_Precision)

{

BigInteger C;

string Comma = Number_Decimal_Separator;

string [] Number_Digits;

string Square_Root_Of_Number;

string Number;

string Square;

string Addend;

string Ok;

string Ok1;

C = 0;

Square_Root_Of_Number = String.Empty;

Number = String.Empty;

Square = String.Empty;

Addend = String.Empty;

Ok = String.Empty;

Ok1 = String.Empty;

Number = A;

//

// Set initial Addend value

//

Number_Digits = Number.ToString().Split(Comma[0]);

if( ( Number_Digits[0].Length - 2 ) > 1 )

{

C = BigInteger.Pow( 10 , ( Number_Digits[0].Length - 2 ) );

Addend = C.ToString();

Addend = ClearZerosFromNumber( Addend );

}

else

{

Addend = Zero + Comma + One;

}

//

Square_Root_Of_Number = MUL( Number , ( Zero + Comma + Three) );

Square = MUL( Square_Root_Of_Number , Square_Root_Of_Number );

Ok = CMP( Square , Number );

//

Number_Digits = Addend.ToString().Split( Comma[0] );

//

while ( Ok != "=" && Number_Digits[1].Length <= Function_Precision )

{

Ok1 = CMP( Square_Root_Of_Number , Addend);

while( Ok == ">" && ( Ok1 == ">" || Ok1 == "=" ) )

{

Square_Root_Of_Number = SUB( Square_Root_Of_Number , Addend );

Square = MUL( Square_Root_Of_Number , Square_Root_Of_Number );

Ok = CMP( Square , Number);

Ok1 = CMP( Square_Root_Of_Number , Addend );

}

Addend = DIV( Addend , ( Ten + Comma + Zero ) , Addend.Length );

while( Ok == "<" )

{

Square_Root_Of_Number = ADD( Square_Root_Of_Number , Addend );

Square = MUL( Square_Root_Of_Number , Square_Root_Of_Number );

Ok = CMP( Square , Number );

}

Addend = DIV( Addend , ( Ten + Comma + Zero ) , Addend.Length );

Number_Digits = Addend.ToString().Split( Comma[0] );

}

Square_Root_Of_Number = ClearZerosFromNumber( Square_Root_Of_Number );

return Square_Root_Of_Number;

}

//

// Improve SQRT Precision function

// Takes two arguments type of string,

// that represents real numbers for CHECK operation

// Returns result as type of string

//

string Improve_SQRT_Precision( string A, string B)

{

string Comma = Number_Decimal_Separator;

string Addend;

string Error_1;

string Error_2;

string Error_3;


string Error_A;

string Error_B;

string Error_C;

string Result;

Addend = String.Empty;

Addend += Zero + Comma;

for(int i=0;i<Result_Precision-1;i++)

{

Addend += Zero;

}

Addend += One;

Error_1 = String.Empty;;

Error_2 = String.Empty;;

Error_3 = String.Empty;;

Error_A = String.Empty;;

Error_B = String.Empty;;

Error_C = String.Empty;;

Result = String.Empty;;

Result = MUL( B, B);

Result = SetResultPrecision( Result );

Result = ClearZerosFromNumber( Result );

Error_1 = SUB( Result, A );

if(Error_1 == ( Zero + Comma + Zero ))

{

return B;

}

Error_A = Error_1.Replace("-", "");

Result = ADD( B, Addend );

Result = MUL( Result, Result);

Result = SetResultPrecision( Result );

Result = ClearZerosFromNumber( Result );

Error_2 = SUB( Result, A );

Error_B = Error_2.Replace("-", "");

Result = SUB( B, Addend );

Result = MUL( Result, Result );

Result = SetResultPrecision( Result );

Result = ClearZerosFromNumber( Result );

Error_3 = SUB( Result, A );

Error_C = Error_3.Replace("-", "");

if( CMP(Error_A, Error_B) == "<" && CMP(Error_A, Error_C) == "<" )

B = B;

else if( CMP(Error_B, Error_A) == "<" && CMP(Error_B, Error_C) == "<" )

B = ADD( B, Addend );

else if( CMP(Error_C, Error_A) == "<" && CMP(Error_C, Error_B) == "<" )

B = SUB( B, Addend );

return B;

}

//

// COMPARE function

// Takes two arguments type of string,

// that represents real numbers for CMP ( compare ) operation

// Returns result as type of string

//

string CMP(string A , string B)

{

BigInteger X;

BigInteger Y;

BigInteger Z;

string Comma = Number_Decimal_Separator;

string [] Decimal_Float_X = new string[2];

string [] Decimal_Float_Y = new string[2];

string Number_X;

string Number_Y;

string Result;

Number_X = String.Empty;

Number_Y = String.Empty;

Result = String.Empty;


int X_Lenght;

int Y_Lenght;

int Comma_Position;

X = 0;

Y = 0;

Z = 0;

X_Lenght = 0;

Y_Lenght = 0;

Comma_Position = 0;

Decimal_Float_X = A.Split( Comma[0] );

Decimal_Float_Y = B.Split( Comma[0] );

Number_X = Decimal_Float_X[1];

Number_Y = Decimal_Float_Y[1];

X_Lenght = Number_X.Length;

Y_Lenght = Number_Y.Length;

if ( X_Lenght > Y_Lenght )

{

Comma_Position = X_Lenght;

while ( Y_Lenght < X_Lenght )

{

Number_Y = Number_Y + Zero;

Y_Lenght++;

}

}

else

{

Comma_Position = Y_Lenght;

while ( X_Lenght < Y_Lenght )

{

Number_X = Number_X + Zero;

X_Lenght++;

}

}

Number_X = Decimal_Float_X[0] + Number_X;

Number_Y = Decimal_Float_Y[0] + Number_Y;

X = BigInteger.Parse( Number_X );

Y = BigInteger.Parse( Number_Y );

if( X > Y )

{

Result = ">";

}

else if( X < Y )

{

Result = "<";

}

else

{

Result = "=";

}

return Result;

}

#endregion


#region- Validation of entered numbers -

//

// ValidateNumber function

// Takes one argument type of string, that represent real number value

// Checks if value is real number by comparing

// every single letter in entered string value with decimal digits.

// Decimal - Float separator is set to value of Number_Decimal_Separator

// Returns result as type of bool

//

bool ValidateNumber(string A)

{

string Comma = Number_Decimal_Separator;

string Digits = "0123456789";

string Sign = "-";

string Letter;


int Lenght;

int Range;

int Counter;

int Comma_Counter;

bool Is_Number;

Lenght = 0;

Range = 0;

Counter = 0;

Comma_Counter = 0;

Is_Number = false;

Lenght = A.Length;

while ( Counter < Lenght )

{

Letter = A.Substring( Counter , 1 );

if ( Digits.Contains( Letter ) )

{

Is_Number = true;

Counter = Counter + 1;

Range++;

}

else if ( Letter == Comma )

{

Is_Number = true;

Comma_Counter = Comma_Counter + 1;

Counter = Counter + 1;

}

else if ( Letter == Sign && Counter == 0)

{

Is_Number = true;

Counter = Counter + 1;

}

else

{

Is_Number = false;

Counter = Lenght;

}

}

if ( Comma_Counter > 1 || Range > Max_Lenght_Of_Entered_Number - 2)

{

Is_Number = false;

}

return Is_Number;

}

//

// ClearZerosFromNumber function

// Takes one argument type of string, that represent real number value

// Removes redundant zeroes from number

//

// exmpl:

// string A = "0001236589,002364540000"

// string Result = "1236589,00236454"

//

// Returns result as type of string

// that represent float point number with minimum one decimal place

//

// exmpl :

// string A = "134"

// string Result ="134,0"

//

string ClearZerosFromNumber(string A)

{

string Comma = Number_Decimal_Separator;

string Sign = "-";


string [] Decimal_Float = new string[2];

string Number;

string Number_Decimal_Part;

string Number_Float_Part;

string Result;

bool Is_Negative;

Number = String.Empty;

Number_Decimal_Part = String.Empty;

Number_Float_Part = String.Empty;

Result = String.Empty;

Is_Negative = false;

Number = A;

if( Number.Contains( Sign ) )

{

Is_Negative = true;

Number = Number.Substring( 1 );

}

if ( Number.Contains( Comma ) )

{

Decimal_Float = Number.Split( Comma[0] );

Number_Decimal_Part = Decimal_Float[0];

Number_Float_Part = Decimal_Float[1];

Number_Decimal_Part = Number_Decimal_Part.TrimStart( Zero[0] );

if ( Number_Decimal_Part == String.Empty )

{

Number_Decimal_Part = Zero;

}

Number_Float_Part = Number_Float_Part.TrimEnd( Zero[0] );

if ( Number_Float_Part == String.Empty )

{

Number_Float_Part = Zero;

}

Number = Number_Decimal_Part + Comma + Number_Float_Part;

}

else

{

Number = Number.TrimStart( Zero[0] );

if ( Number == String.Empty )

{

Number = Zero + Comma + Zero;

}

else

{

Number = Number + Comma + Zero;

}

}

if( Is_Negative && Number != (Zero+Comma+Zero) )

{

Number = Number.Insert( 0 , Sign );

}

Result = Number;

return Result;

}

//

// SetResultPrecision function

// If lenght of fractal part of result is greater than declared Result Precision,

// this function cuts of, all excessive decimal places.

// Result is shown with maximum decimal places with no number rounding

//

// Notice:

// Result_Precision have different minning from Max_Div_Function_Precision

//

string SetResultPrecision(string A)

{

string Comma = Number_Decimal_Separator;

string [] Decimal_Float;

string Number_Decimal_Part;

string Number_Float_Part ;

string Result;

int Lenght;

Decimal_Float = new String[2];

Number_Decimal_Part = String.Empty;

Number_Float_Part = String.Empty;

Result = String.Empty;

Lenght = 0;

Decimal_Float = A.Split( Comma[0] );

Number_Decimal_Part = Decimal_Float[0];

Number_Float_Part = Decimal_Float[1];

Lenght = Number_Float_Part.Length;

if( Lenght > Result_Precision )

{

Number_Float_Part = Number_Float_Part.Substring( 0, Result_Precision );

}

Result = Number_Decimal_Part + Comma + Number_Float_Part;

return Result;

}

#endregion

#region- Text box events -

//

// TextBox1Leave event

// It raises when control loses focus, after user clicks somewhere out of control

// Takes values from textBox1 and calls ValidateNumber function

// After getting positive result from ValidateNumber function,

// calls function ClearZerosFromNumber & SetResultPrecision

// for formating result and shows result in textBox1

// If result of ValidateNumber function is negative,

// it shows "Wrong entry" message to user

//

void TextBox1Leave(object sender, EventArgs e)

{

string Number_X;

string Result_Z;

bool Is_Number;

Number_X = String.Empty;

Result_Z = String.Empty;

Is_Number = false;

Number_X = textBox1.Text.Trim();

Is_Number = ValidateNumber( Number_X );

if ( Is_Number == true )

{

Result_Z = ClearZerosFromNumber( Number_X );

textBox1.Text = Result_Z;

textBox1.Refresh();

textBox2.Focus();

}

else if ( Is_Number != true )

{

MessageBox.Show( "Wrong entry ! " , " Error" ,

MessageBoxButtons.OK , MessageBoxIcon.Error );

textBox1.Text = String.Empty;

textBox1.Focus();

}

}

//

// TextBox1KeyPress event

// It raises when control loses focus,

// after user presses enter on keyboard after entering value of number

// Takes values from textBox1 and calls ValidateNumber function

// After getting positive result from ValidateNumber function,

// calls function ClearZerosFromNumber & SetResultPrecision

// for formating result and shows result in textBox1

// If result of ValidateNumber function is negative,

// it shows "Wrong entry" message to user

//

void TextBox1KeyPress(object sender, KeyPressEventArgs e)

{

string Number_X;

string Result_Z;

bool Is_Number;

Number_X = String.Empty;

Result_Z = String.Empty;

Is_Number = false;


if ( e.KeyChar == (char) Keys.Return )

{

Number_X = textBox1.Text.Trim();

Is_Number = ValidateNumber( Number_X );

if ( Is_Number == true )

{

Result_Z = ClearZerosFromNumber( Number_X );

textBox1.Text = Result_Z;

textBox1.Refresh();

textBox2.Focus();

}

else if ( Is_Number != true )

{

MessageBox.Show( "Wrong entry ! " , " Error",

MessageBoxButtons.OK , MessageBoxIcon.Error );

textBox1.Text = String.Empty;

textBox1.Focus();

}

}

}


//

// TextBox2Leave event

// It raises when control loses focus,

// after user clicks somewhere out of control

// Takes values from textBox2 and calls ValidateNumber function

// After getting positive result from ValidateNumber function,

// calls function ClearZerosFromNumber & SetResultPrecision

// for formating result and shows result in textBox2

// If result of ValidateNumber function is negative,

// it shows "Wrong entry" message to user

//

void TextBox2Leave(object sender, EventArgs e)

{

string Number_Y;

string Result_Z;

bool Is_Number;

Number_Y = String.Empty;

Result_Z = String.Empty;

Is_Number = false;

Number_Y = textBox2.Text.Trim();


Is_Number = ValidateNumber( Number_Y );

if ( Is_Number == true )

{

Result_Z = ClearZerosFromNumber( Number_Y );

textBox2.Text = Result_Z;

textBox2.Refresh();

button1.Focus();

}

else if( Is_Number != true )

{

MessageBox.Show( "Wrong entry ! " , " Error" ,

MessageBoxButtons.OK , MessageBoxIcon.Error );

textBox2.Text = String.Empty;

textBox2.Focus();

}

}


//

// TextBox2KeyPress event

// It raises when control loses focus,

// after user presses enter on keyboard afther entering value of number

// Takes values from textBox2 and calls ValidateNumber function

// After getting positive result from ValidateNumber function,

// calls function ClearZerosFromNumber & SetResultPrecision

// for formating result and shows result in textBox2

// If result of ValidateNumber function is negative,

// it shows "Wrong entry" message to user

//

void TextBox2KeyPress(object sender, KeyPressEventArgs e)

{

string Number_Y;

string Result_Z;

bool Is_Number;

Number_Y = String.Empty;

Result_Z = String.Empty;

Is_Number = false;


if ( e.KeyChar == (char) Keys.Return )

{

Number_Y = textBox2.Text.Trim();


Is_Number = ValidateNumber( Number_Y );

if ( Is_Number == true )

{

Result_Z = ClearZerosFromNumber( Number_Y );

textBox2.Text = Result_Z;

textBox2.Refresh();

button1.Focus();

}

else if ( Is_Number != true )

{

MessageBox.Show( "Wrong entry ! " , " Error" ,

MessageBoxButtons.OK , MessageBoxIcon.Error );

textBox2.Text = String.Empty;

textBox2.Focus();


}

}

}

#endregion

#region - Precision change event -

void Max_Result_PrecisionValueChanged(object sender, EventArgs e)

{

Result_Precision = (int) Max_Result_Precision.Value;

}

#endregion


//

// End of MainForm class

//

}

}


/************************************************************************

* Program Licence : *

* *

* Copyright 2013 , Perić Željko *

* (periczeljkosmederevo@yahoo.com) *

* *

* According to it's main purpose , this program is licensed *

* under the therms of 'Free Software' licence agreement. *

* *

* If You do not know what those therms applies to *

* please read explanation at the following link : *

* (http://www.gnu.org/philosophy/free-sw.html.en) *

* *

* Since it is Free Software this program has no warranty of any kind. *

************************************************************************

* Ethical Notice : *

* *

* It is not ethical to change program code signed by it's author *

* and then to redistribute it under the same author name , *

* especially if it is incorrect. *

* *

* It is recommended that if You make improvement in program code , *

* to make remarks of it and then to sign it with Your own name , *

* for further redistribution as new major version of program. *

* *

* Author name and references of old program code version should be *

* kept , for tracking history of program development. *

* *

* For any further information please contact code author at his email. *

************************************************************************/


/************************************

* List Of Revisions *

************************************

* Major revision of version 1.0 *

* Author 05.10.2013 *

* Hi precision arithmetic *

* New version number 2.0 *

************************************

* Minor revision of version 2.0 *

* Author 05.10.2013 *

* new comments added *

* New version number 2.0 *

************************************

* Major revision of version 2.0 *

* Author 16.03.2021 *

* Potential error with *

* decimal separator corrected *

* Increase SQRT result precision *

* Increase DIV result precision *

* New version number 3.0 *

************************************

* Minor revision of version 3.0 *

* Author 18.04.2022 *

* Number Format Decimal Separator *

* changed, Current culture format *

* New version number 3.1 *

************************************/