?? calculate.cpp
字號:
#include <stdio.h>
#include <math.h>
#include "stack.h"
#include "calculate.h"
#include "common.h"
#include "math function.h"
#define OVER false
bool checkword (
char word[]
)
/*++
函數描述:
功能:
檢查字符的合法性
參數:
word - 待檢查的字符串
返回值:
字符合法返回 true ,否則返回 false
--*/
{
int i;
for (i = 0;word[i] != '\0';i ++) {
if (word[i] >= 40 && word[i] <= 57 && word[i] != 44
|| word[i] >= 65 && word[i] <= 90
|| word[i] == 92 || word[i] == 94
|| word[i] >= 97 && word[i] <= 122
|| word[i] == 32 || word[i] == 9 || word[i] == 37
) {
continue;
} else {
return false;
}
}
return true;
}
void SingelCalc (
NODE *Operand,
NODE *Operator
)
/*++
函數描述:
功能:
實現一元運算符的運算,并將結果存入到 Operand 中,
且對小數位是零的浮點數,轉換成整數后再保存
參數:
Operand - 操作數
Operator - 一元操作符
返回值:
無
--*/
{
switch (Operator->Term.Operator.Symbol) {
case '-':
if (Operand->Term.Operand.DataSignal == INTEGER) {
Operand->Term.Operand.Data.Integer = 0 - Operand->Term.Operand.Data.Integer;
} else {
Operand->Term.Operand.Data.Real = 0 - Operand->Term.Operand.Data.Real;
}
break;
case '%':
if (Operand->Term.Operand.DataSignal == INTEGER) {
Operand->Term.Operand.Data.Real = Operand->Term.Operand.Data.Integer/100.0;
Operand->Term.Operand.DataSignal = FLOAT;
} else {
Operand->Term.Operand.Data.Real = Operand->Term.Operand.Data.Real/100.0;
}
break;
case 21:
if (Operand->Term.Operand.DataSignal == INTEGER) {
Operand->Term.Operand.Data.Real = sin ((double)Operand->Term.Operand.Data.Integer);
Operand->Term.Operand.DataSignal = FLOAT;
} else {
Operand->Term.Operand.Data.Real = sin (Operand->Term.Operand.Data.Real);
}
break;
case 22:
if (Operand->Term.Operand.DataSignal == INTEGER) {
Operand->Term.Operand.Data.Real = cos ((double)Operand->Term.Operand.Data.Integer);
Operand->Term.Operand.DataSignal = FLOAT;
} else {
Operand->Term.Operand.Data.Real = cos (Operand->Term.Operand.Data.Real);
}
break;
case 23:
if (Operand->Term.Operand.DataSignal == INTEGER) {
Operand->Term.Operand.Data.Real = tan ((double)Operand->Term.Operand.Data.Integer);
Operand->Term.Operand.DataSignal = FLOAT;
} else {
Operand->Term.Operand.Data.Real = tan (Operand->Term.Operand.Data.Real);
}
break;
case 24:
if (Operand->Term.Operand.DataSignal == INTEGER) {
Operand->Term.Operand.Data.Real = 1/tan ((double)Operand->Term.Operand.Data.Integer);
Operand->Term.Operand.DataSignal = FLOAT;
} else {
Operand->Term.Operand.Data.Real = 1/tan (Operand->Term.Operand.Data.Real);
}
break;
case 25:
if (Operand->Term.Operand.DataSignal == INTEGER) {
Operand->Term.Operand.Data.Real = asin ((double)Operand->Term.Operand.Data.Integer);
Operand->Term.Operand.DataSignal = FLOAT;
} else {
Operand->Term.Operand.Data.Real = asin (Operand->Term.Operand.Data.Real);
}
break;
case 26:
if (Operand->Term.Operand.DataSignal == INTEGER) {
Operand->Term.Operand.Data.Real = acos ((double)Operand->Term.Operand.Data.Integer);
Operand->Term.Operand.DataSignal = FLOAT;
} else {
Operand->Term.Operand.Data.Real = acos (Operand->Term.Operand.Data.Real);
}
break;
case 27:
if (Operand->Term.Operand.DataSignal == INTEGER) {
Operand->Term.Operand.Data.Real = atan ((double)Operand->Term.Operand.Data.Integer);
Operand->Term.Operand.DataSignal = FLOAT;
} else {
Operand->Term.Operand.Data.Real = atan (Operand->Term.Operand.Data.Real);
}
break;
case 28:
if (Operand->Term.Operand.DataSignal == INTEGER) {
Operand->Term.Operand.Data.Real = atan (1.0/(double)Operand->Term.Operand.Data.Integer);
Operand->Term.Operand.DataSignal = FLOAT;
} else {
Operand->Term.Operand.Data.Real = atan (1.0/Operand->Term.Operand.Data.Real);
}
break;
case 29:
if (Operand->Term.Operand.DataSignal == INTEGER) {
Operand->Term.Operand.Data.Real = log ((double)Operand->Term.Operand.Data.Integer);
Operand->Term.Operand.DataSignal = FLOAT;
} else {
Operand->Term.Operand.Data.Real = log (Operand->Term.Operand.Data.Real);
}
break;
case 30:
if (Operand->Term.Operand.DataSignal == INTEGER) {
Operand->Term.Operand.Data.Real = log10 ((double)Operand->Term.Operand.Data.Integer);
Operand->Term.Operand.DataSignal = FLOAT;
} else {
Operand->Term.Operand.Data.Real = log10 (Operand->Term.Operand.Data.Real);
}
break;
}
if (Operand->Term.Operand.DataSignal == FLOAT
&& Operand->Term.Operand.Data.Real - (int)Operand->Term.Operand.Data.Real == 0.0) {
Operand->Term.Operand.Data.Integer = (int)Operand->Term.Operand.Data.Real;
Operand->Term.Operand.DataSignal = INTEGER;
}
}
void DoubleCalc (
NODE *Operand1,
NODE *Operand2,
NODE *Operator
)
/*++
函數描述:
功能:
實現二元運算符的運算,并將結果存入到 Operand 中,且對小數位是零的數,轉換成整數后再保存
參數:
Operand1 - 操作數 1
Operand2 - 操作數 2
Operator - 二元操作符
返回值:
無
--*/
{
switch (Operator->Term.Operator.Symbol) {
case '+':
if (Operand1->Term.Operand.DataSignal == INTEGER && Operand2->Term.Operand.DataSignal == INTEGER) {
Operand1->Term.Operand.Data.Integer = Operand1->Term.Operand.Data.Integer + Operand2->Term.Operand.Data.Integer;
} else if (Operand1->Term.Operand.DataSignal == INTEGER && Operand2->Term.Operand.DataSignal == FLOAT) {
Operand1->Term.Operand.Data.Real = Operand1->Term.Operand.Data.Integer + Operand2->Term.Operand.Data.Real;
Operand1->Term.Operand.DataSignal = FLOAT;
} else if (Operand1->Term.Operand.DataSignal == FLOAT && Operand2->Term.Operand.DataSignal == INTEGER) {
Operand1->Term.Operand.Data.Real = Operand1->Term.Operand.Data.Real + Operand2->Term.Operand.Data.Integer;
} else {
Operand1->Term.Operand.Data.Real = Operand1->Term.Operand.Data.Real + Operand2->Term.Operand.Data.Real;
}
break;
case '-':
if (Operand1->Term.Operand.DataSignal == INTEGER && Operand2->Term.Operand.DataSignal == INTEGER) {
Operand1->Term.Operand.Data.Integer = Operand1->Term.Operand.Data.Integer - Operand2->Term.Operand.Data.Integer;
} else if (Operand1->Term.Operand.DataSignal == INTEGER && Operand2->Term.Operand.DataSignal == FLOAT) {
Operand1->Term.Operand.Data.Real = Operand1->Term.Operand.Data.Integer - Operand2->Term.Operand.Data.Real;
Operand1->Term.Operand.DataSignal = FLOAT;
} else if (Operand1->Term.Operand.DataSignal == FLOAT && Operand2->Term.Operand.DataSignal == INTEGER) {
Operand1->Term.Operand.Data.Real = Operand1->Term.Operand.Data.Real - Operand2->Term.Operand.Data.Integer;
} else {
Operand1->Term.Operand.Data.Real = Operand1->Term.Operand.Data.Real - Operand2->Term.Operand.Data.Real;
}
break;
case '*':
if (Operand1->Term.Operand.DataSignal == INTEGER && Operand2->Term.Operand.DataSignal == INTEGER) {
Operand1->Term.Operand.Data.Integer = Operand1->Term.Operand.Data.Integer * Operand2->Term.Operand.Data.Integer;
} else if (Operand1->Term.Operand.DataSignal == INTEGER && Operand2->Term.Operand.DataSignal == FLOAT) {
Operand1->Term.Operand.Data.Real = Operand1->Term.Operand.Data.Integer * Operand2->Term.Operand.Data.Real;
Operand1->Term.Operand.DataSignal = FLOAT;
} else if (Operand1->Term.Operand.DataSignal == FLOAT && Operand2->Term.Operand.DataSignal == INTEGER) {
Operand1->Term.Operand.Data.Real = Operand1->Term.Operand.Data.Real * Operand2->Term.Operand.Data.Integer;
} else {
Operand1->Term.Operand.Data.Real = Operand1->Term.Operand.Data.Real * Operand2->Term.Operand.Data.Real;
}
break;
case '/':
if (Operand2->Term.Operand.DataSignal == INTEGER && Operand2->Term.Operand.Data.Integer == 0
|| Operand2->Term.Operand.DataSignal == FLOAT && Operand2->Term.Operand.Data.Real == 0.0) {
error = the_divisor_can_not_be_zero;
return;
}
if (Operand1->Term.Operand.DataSignal == INTEGER && Operand2->Term.Operand.DataSignal == INTEGER) {
Operand1->Term.Operand.Data.Real = (double)Operand1->Term.Operand.Data.Integer / (double)Operand2->Term.Operand.Data.Integer;
Operand1->Term.Operand.DataSignal = FLOAT;
} else if (Operand1->Term.Operand.DataSignal == INTEGER && Operand2->Term.Operand.DataSignal == FLOAT) {
Operand1->Term.Operand.Data.Real = Operand1->Term.Operand.Data.Integer / Operand2->Term.Operand.Data.Real;
Operand1->Term.Operand.DataSignal = FLOAT;
} else if (Operand1->Term.Operand.DataSignal == FLOAT && Operand2->Term.Operand.DataSignal == INTEGER) {
Operand1->Term.Operand.Data.Real = Operand1->Term.Operand.Data.Real / Operand2->Term.Operand.Data.Integer;
} else {
Operand1->Term.Operand.Data.Real = Operand1->Term.Operand.Data.Real / Operand2->Term.Operand.Data.Real;
}
break;
case '\\':
if (Operand1->Term.Operand.DataSignal == INTEGER && Operand2->Term.Operand.DataSignal == INTEGER) {
Operand1->Term.Operand.Data.Integer = Operand1->Term.Operand.Data.Integer % Operand2->Term.Operand.Data.Integer;
} else {
error = the_mode_operator_only_accept_integral_operands;
return;
}
break;
case '^':
if (Operand1->Term.Operand.DataSignal == INTEGER && Operand2->Term.Operand.DataSignal == INTEGER) {
if (Operand1->Term.Operand.Data.Integer == 1 || Operand2->Term.Operand.Data.Integer >= 0) {
Operand1->Term.Operand.Data.Integer = PlusPow (Operand1->Term.Operand.Data.Integer , Operand2->Term.Operand.Data.Integer);
} else {
Operand1->Term.Operand.Data.Real = MinusPow (Operand1->Term.Operand.Data.Integer , Operand2->Term.Operand.Data.Integer);
Operand1->Term.Operand.DataSignal = FLOAT;
}
} else if (Operand1->Term.Operand.DataSignal == INTEGER && Operand2->Term.Operand.DataSignal == FLOAT) {
Operand1->Term.Operand.Data.Real = pow (Operand1->Term.Operand.Data.Integer , Operand2->Term.Operand.Data.Real);
Operand1->Term.Operand.DataSignal = FLOAT;
} else if (Operand1->Term.Operand.DataSignal == FLOAT && Operand2->Term.Operand.DataSignal == INTEGER) {
Operand1->Term.Operand.Data.Real = pow (Operand1->Term.Operand.Data.Real , Operand2->Term.Operand.Data.Integer);
} else {
Operand1->Term.Operand.Data.Real = pow (Operand1->Term.Operand.Data.Real , Operand2->Term.Operand.Data.Real);
}
break;
}
if (Operand1->Term.Operand.DataSignal == FLOAT
&& Operand1->Term.Operand.Data.Real - (int)Operand1->Term.Operand.Data.Real == 0.0) {
Operand1->Term.Operand.Data.Integer = (int)Operand1->Term.Operand.Data.Real;
Operand1->Term.Operand.DataSignal = INTEGER;
}
}
void FixList (
NODE *Left,
NODE *Right,
NODE *data
)
{
DeleteNodes (Left,Right);
NODEcopyWithoutNext (Left,data);
}
void CalcUnit (
NODE *expHead,
NODE *expEnd
)
/*++
函數描述:
功能:
實現僅含一對括號的表達式的計算,并,將結果保存到 expHead 中
參數:
expHead - 表達式頭節點(也是左括號)
expEnd - 表達式尾節點 (也是右括號)
返回值:
無
--*/
{
bool FirstTerm = true;
NODE *ActivedPointer = expHead;
NODE *Operator = NULL;
NODE *Operand1 = NULL,*Operand2 = NULL;
PushOperator (ActivedPointer);
ActivedPointer = ActivedPointer->Next;
while (ActivedPointer != expEnd->Next) {
//識別負號,由于負號只出現在表達式的表頭
if (ActivedPointer->TermSignal == DUALITY && ActivedPointer->Term.Operator.Symbol == '-' && FirstTerm == true) {
ActivedPointer->Term.Operator.OperandNumber = 1;
ActivedPointer->Term.Operator.Priority = 3;
ActivedPointer->TermSignal = UNITARY;
PushOperator (ActivedPointer);
ActivedPointer = ActivedPointer->Next;
}
if (FirstTerm == true) {
FirstTerm = false;
}
if (ActivedPointer->TermSignal == ISDATA
|| ActivedPointer->TermSignal == ISVARIABLE) {
PushOperand (ActivedPointer);
ActivedPointer = ActivedPointer->Next;
} else {
if (ActivedPointer->Term.Operator.Priority < OperatorHead->Term.Operator.Priority) {
PushOperator (ActivedPointer);
ActivedPointer = ActivedPointer->Next;
} else if (ActivedPointer->Term.Operator.Priority > OperatorHead->Term.Operator.Priority
|| ActivedPointer->Term.Operator.Priority == OperatorHead->Term.Operator.Priority
&& ActivedPointer->Term.Operator.Symbol != '^'
&& ActivedPointer->TermSignal != MATH_FUNCTION
&& ActivedPointer->TermSignal != RIGHT_BRACKET) {
Operator = PopOperator ();
Operand2 = PopOperand ();
if (Operator->Term.Operator.OperandNumber == 2) {
Operand1 = PopOperand ();
DoubleCalc (Operand1,Operand2,Operator);
PushOperand (Operand1);
} else {
SingelCalc (Operand2,Operator);
PushOperand (Operand2);
}
} else {
PushOperator (ActivedPointer);
ActivedPointer = ActivedPointer->Next;
}
}
}
if (OperandHead->Term.Operand.DataSignal == FLOAT
&& OperandHead->Term.Operand.Data.Real - (int)OperandHead->Term.Operand.Data.Real == 0.0) {
OperandHead->Term.Operand.Data.Integer = (int)OperandHead->Term.Operand.Data.Real;
OperandHead->Term.Operand.DataSignal = INTEGER;
}
FixList (expHead,expEnd,OperandHead);
ClearStack ();
}
bool LocateInner (
NODE *expHead,
NODE **InnerLeft,
NODE **InnerRight
)
{
NODE *p;
for (p = expHead;p != NULL; p = p->Next) {
if (p->TermSignal != ISDATA && p->TermSignal != ISVARIABLE) {
if (p->Term.Operator.Symbol == '(') {
*InnerLeft = p;
} else if (p->Term.Operator.Symbol == ')') {
*InnerRight = p;
return true;
}
}
}
return false;
}
void Calculate (
NODE *expHead
)
/*++
函數描述:
功能:
計算給定的格式化后的表達式,并將結果保存到頭節點 expHead 中
參數:
expHead - 格式化后的表達式的頭節點指針
返回值:
表達式節點指針
--*/
{
NODE *Left = NULL,*Right = NULL;
if (error != NULL) {
return;
}
while (LocateInner (expHead,&Left,&Right) != OVER) {
CalcUnit (Left,Right);
}
}
void Calculator (
void
)
{
if (expString[0] == NULL || error != NULL) {
vision = false;
return;
}
if (!checkword (expString)) {
error = find_some_illegal_alpha;
return;
}
reformer (expString);
PrintList ();
Calculate (ExpressionHead);
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -