Cameron Handoe Ответов: 5

Как закодировать научный калькулятор на языке C++


Привет

В рамках личного проекта мне нужно сделать консольный научный калькулятор.

Он должен уметь складывать, вычитать, умножать и делить большое количество чисел за одну команду (например,: 2+2+2+2+2+2*9/7* sin 45 - 88.277) и уметь правильно манипулировать числами с помощью BIDMAS.

Он должен уметь вычислять тригонометрические функции, логарифмы, мод целого числа, вычислять факториалы и вычислять экспоненты и корни в N-й степени.

Как я могу это сделать и сколько строк кода это займет?

Я не хочу, чтобы у него был графический интерфейс в данный момент.

Любой исходный код будет выпущен, и вся программа будет бесплатной.


Я искал вокруг целую вечность и все что я могу найти это калькуляторы которые могут сложить только два числа

Заранее большое спасибо

Sergey Alexandrovich Kryukov

Причина моего голосования 2
Бессмысленный.
--СА

5 Ответов

Рейтинг:
2

Abdelrahman Elzedy

//scientific calculator in c++
//written by Abd - elrahman Elmasry
//e-mail: abdoasemelzedy@hotmail.com
//there is no copy right for this code


#include<iostream>//main library
#include<math.h>// for mathimatics function
#include<stdexcpt.h>//for exeption conditions

using namespace std;

class calc
{
private:
    int len,//for the length of array
        intPartTemp,//for using its value
        intLen,//for the len of integer part
        floatLen,//for the len of float part
        ten,//for pow function
        str;//for deter mine starting point

    double value,//for the value of mid
        floatPartTemp,//for getting floating part of numbers for converting
        x; // for the value of variable x

    char ch[1000] ;//charchters for saving formulas
    char carriage[100];//for putting num in it as a caracter
    char copy [1000];//for saving user formula

//getting information form user
    void setInfo()
{
    cin.getline(copy,1000);//getting formulas from user
    copyArray(copy, ch);//copy array to save its value
    replace(x,'x');//replacing variable x with its value
}

void copyArray (char main [], char copy [] )
{
    //getting main array lenght
    int len = strlen(main);
    int temp;

    //it counts to null because of null
    for(temp=0;temp<=len;temp++)
    {
        copy[temp] = main[temp];
    }
}


//editing formulas to be adaptable to computing rules
void edit()
{//star edit
    int temp;

    len = strlen(ch);

    for(temp=0;temp<len;temp++)
    {//loop for cover all characters

        //the condition there is two variables after them thelf without *
         if(!triangleMove(temp) && isalpha(ch[temp]) && isalpha(ch[temp+1]) )
            //not triangle to make sure they aren't triangle functions
            insert(temp,len,'*');

        //the condition when there is a number and after it a variable without *
        else if(temp!=0 && isalpha(ch[temp]) && isdigit(ch[temp-1]))
            insert(temp,len,'*');

        //the condition there is two parentheses after them thelf without *
        else if(temp!=0 && ch[temp] == '(' && ch[temp-1] ==')' )
            insert(temp,len,'*');

        //the condition when there is a number before (
        else if(temp!=0 && ch[temp] == '(' && isdigit(ch[temp-1]) )
        insert(temp,len,'*');

        else if( ( ch[temp]=='.' && temp == 0) || ( temp>0 && ch[temp] == '.' && !isdigit( (ch[temp-1]) ) ) )
            insert(temp,len,'0');

        //the condition when there is ++
        else if( ch[temp] == '+' && ch[temp+1] =='+' )
            smaller(temp,len,'+');

        //the condition when there is ++
        else if( ch[temp] == '+' && ch[temp+1] =='-' )
            smaller(temp,len,'-');

        //the condition when there is ++
        else if( ch[temp] == '-' && ch[temp+1] =='-' )
            smaller(temp,len,'+');

        //the condition when there is ++
        else if( ch[temp] == '-' && ch[temp+1] =='+' )
            smaller(temp,len,'-');

    }//end loop of coverting

    //the condition when first digit is +
    if(ch[0]=='+')
        decrease(0,1);

}//end edit

//for examing formulas from being out of math rules
bool exam ()
{
    int leftBracket=0,//for count left brackts
        rightBracket=0,//for count right brackt
        len = strlen(ch), // for array lenght
        temp;//temprature variable

    for(temp = 0; temp<len; temp++)
    {
        //continue defaule condition of being number
        if( isdigit(ch[temp]) )
            continue;

        //count left brackets
        else if(ch[temp] == '(')
            leftBracket ++;

        //count right brackets
        else if(ch[temp] == ')')
            rightBracket ++;

        //the condition of being two mathimatics symbols after themself
        else if( !isalpha(ch[temp]) && !isalpha(ch[temp+1]) && !isdigit(ch[temp+1]) )
            return false;

    }//end covering loop

    //false formulas with right brackets not equal leftbrackets
    if(rightBracket != rightBracket)
        return false;

    //condition with the last idgits isn't number or ')'
    if( !isdigit (ch[len-1] ) && ch[len-1] != ')'  )
        return false;

    //defaule condition
    return true;
}


//for moving temp
bool triangleMove(int &temp)
{

    //sin condition
    if(ch[temp] == 's' && ch[temp+1] == 'i' && ch[temp+2] == 'n' && ch[temp+3] == '(' && isdigit(ch[temp+4]) )
    {
        temp+=4;//for going to next element
        return true;
    }

    //cos condition
    else if(ch[temp] == 'c' && ch[temp+1] == 'o' && ch[temp+2] == 's' && ch[temp+3] == '(' && isdigit(ch[temp+4]) )
    {
        temp+=4;//for going to next element
        return true;
    }

    //tan condition
    else if(ch[temp] == 't' && ch[temp+1] == 'a' && ch[temp+2] == 'n' && ch[temp+3] == '(' && isdigit(ch[temp+4]) )
    {
        temp+=4;//for going to next element
        return true;
    }

    //defaul condition
    return false;
}

//examing triangle functions
bool triangle (int temp)
{

    //sin condition
    if(ch[temp] == 's' && ch[temp+1] == 'i' && ch[temp+2] == 'n' && ch[temp+3] == '(' && isdigit(ch[temp+4]) )
    {
        return true;
    }

    //cos condition
    else if(ch[temp] == 'c' && ch[temp+1] == 'o' && ch[temp+2] == 's' && ch[temp+3] == '(' && isdigit(ch[temp+4]) )
    {
        return true;
    }

    //tan condition
    else if(ch[temp] == 't' && ch[temp+1] == 'a' && ch[temp+2] == 'n' && ch[temp+3] == '(' && isdigit(ch[temp+4]) )
    {
        return true;
    }

    //defaul condition
    return false;
}

void increase (int order,  int &len, int count)
{//for increaseing array's element
    int temp, temp2;

    //punt any digit

    for(temp2=0; temp2<count; temp2++)
{
    len++;//increase len by one for the new character

    for(temp=len;temp>order;temp--)
    {//increase array with one starting with last element
        ch[temp]=ch[temp-1];
    }
}
}//end increase function

void decrease (int order, int count)
{//for increaseing array's element
    int temp, temp2;
    int len = strlen(ch);
    for(temp2=0;temp2<count;temp2++)
{

    for(temp=order;temp<len;temp++)
    {//increase array with one starting with last element
        ch[temp]=ch[temp+1];
    }
    len--;//increase len by one for the new character
}
}//end increase function

void insert(int order,  int &len, char ob)
{//for puting an element in some order

    //increase characters
    increase (order, len,1);
    //put requred element in its position
    ch[order] = ob;

}//end insert function

void smaller(int order,  int &len, char ob)
{//for shorting two elements with one as ++ to be +

    //decrease
    decrease(order, 1);
    //put requred element in its position
    ch[order] = ob;

}//end smaller function

int getNumLen(double num)
{//for the lenght of a num to put it in a character

    int intPart,//for the  integer part
        temp, //temprature variable
        numLen;//for the lenght of the num

    bool plus = false;

    double floatPart;//for the float part

    if(num<0)
    {
        plus = true;
        num*=-1;
    }


    //determine integer part
    intPart = intPartTemp = static_cast<int>(num);
    floatPart = floatPartTemp = num - intPart;

    //getting integer part lenght
    for(intLen=0;intPart>0;intPart/=10)
    {
        intLen++;
    }

    if(intLen == 0)
        intLen = 1;//for making a digit for 0

    //getting integer part lenght
    //initializing floatLen with 1 for '.'
    floatPart>0?floatLen=1:floatLen=0;
    for(temp= 1; floatPart!=0 && floatLen<10 ; floatLen++)
    {
        floatPart*=10;//put one digit in the integer part
        temp = static_cast<int>(floatPart) ;
        floatPart-=temp;//remove the digit
    }

    if(plus){
        intLen++;//increase digit for -
        intPart *=-1;
    }
    numLen = intLen + floatLen;



    return numLen;
}//end getLength function

void convert(char carriage[], double num, int intLen, int intPart, int floatLen, double floatPart, int numLen, bool sign )
{
    int temp1, temp;
    int start = 0;

        //making the first position for 0 in the condition
        //of numbers less than 1

        if(numLen>0)
        {
            carriage[numLen]=0;
        }
        else
        {
            numLen=1;
            carriage[numLen]=0;
        }

        //negative conditions
    if(!sign){
        start ++;
        carriage[0] = '-';
    }


    //integer part
    for(temp=intLen-1;temp>=start;temp--)
    {
        temp1= intPart % 10 ;//getting the first digit
        carriage[temp]= temp1+48;//put the first digit

        intPart/=10; //remove the first digit
    }

    //floating part

    //move null to next position
    if(floatPart!=0){

        //intLen as null in this time is in intLen position
        carriage[intLen]='.';
        carriage[intLen + floatLen ]=0;

        //starting with intLen because of int part and .
    for(temp=intLen+1;temp<floatLen+intLen; temp++)
    {
        floatPart*=10;//put one digit in the integer part
        temp1 = floatPart;//get the digit and put it in integer variable
        carriage[temp]=temp1+48;//get the digit in the integer part
        floatPart-=temp1;//remove the digit
    }

    }//end if

}//end convert function

void replace ( double num, char var)
{//for replacing a variable with a numberical value
    int len = strlen(ch);
    int temp;

    for(temp=0;temp<len;temp++)
    {
        if(ch[temp]==var)
        {
            decrease(temp,1);//remove variable
            insertNum(temp,  num);//replace variable with the number
  


Рейтинг:
1

Andreas Gieriet

Это в основном задача синтаксического анализа, не очень подходящая для новичка в C++.
Специалист по синтаксическому анализу решил бы эту проблему в течение нескольких часов - полный новичок мог бы потратить месяцы, чтобы сделать это так или иначе.
Я бы выбрал другую тему, в зависимости от ваших личных интересов или хобби.
Подумайте также о том, где C++ полезен сегодня, и выберите соответствующую тему.

Если вы настаиваете на задаче синтаксического анализа в C++, вы можете взять flex/bison и научиться
- tokeinzing (определение токенов)
- синтаксический анализ (определение производств)
- таблица символов (система типов, поиск переменных/операторов/функций, хранение и извлечение данных, поддерживаемые операции, выполнение операций)
- действия (определение действий для анализируемых производств и способов передачи значений, например, по стеку)

Возможно, вам придется купить книгу о построении компилятора.

Удачи.

Энди


Рейтинг:
1

Nelek

Это будет нелегко, и потребуется больше строк кода, чем вы думаете.

Вам нужно будет разобрать входную строку для поиска символов и чисел, дифференцировать функции тригонометрии, проверить орфографию (возможно, давая ошибки или автокоррекцию), добавить () там, где это необходимо (что означает: найти "*" или "/" или число, за которым следуют буквы "2sin 45", а затем выполнить поиск сзади и спереди, чтобы установить приоритет операций) и многое другое... и это только для чтения входных данных.

Затем вызовите соответствующие операции, следующие в порядке приоритета и имеющие дело с исключениями (например, погружение на 0, мнимые корни и т. д.).

В заключение... слишком широкая тема, чтобы сразу все объяснить.


Начните кодирование и вернитесь, когда у вас появятся более конкретные проблемы, вы получите лучшие ответы и более полезную помощь, если вы ограничите вопросы конкретной проблемой.

Удачи и получайте удовольствие от кодирования :)


Cameron Handoe

Большое вам спасибо за ответ! Я очень скоро приступлю к работе.

Просто вопрос, как я могу хранить так много переменных? Все калькуляторы, которые я видел до сих пор, присваивают значения глобальным переменным и поэтому очень ограничены. Как я могу обойти это?

Sergey Alexandrovich Kryukov

Я думаю, что начинать с парсера-это пустая трата времени, если только кто-то не хочет учиться синтаксическому анализу.

Один из подходов-это интерпретирующие языки, такие как JavaScript (с Eval) - вы можете анализировать, интерпретировать и запускать код, поставляемый из пользовательских данных (см. Мой комментарий к моему решению).
Другой подход заключается модели.

--СА

Рейтинг:
1

Philippe Mori

Вы также можете использовать boost, если хотите сделать это в C++ (или в смешанном режиме с C++/CLI).

http://www.boost.org/doc/libs/1_49_0/libs/spirit/doc/html/index.html[^]

Что касается количества строк кода, то это будет во многом зависеть от того, как вы это сделаете...


Cameron Handoe

Пожалуйста, простите мое невежество, но я новичок.

Что эти форсированные ливреи позволяют мне делать?

Philippe Mori

Ну а предоставленная ссылка указывает на документацию по библиотеке для синтаксического анализа. Я никогда не использовал его, но это должно очень помочь сделать парсер, но вам также придется многому научиться. Начните с введения, а затем учебника.

Что я действительно знаю, так это то, что boost поставляется с большим количеством библиотек, выполненных экспертом, и некоторые из них становятся частью стандартной библиотеки. В моем случае, поскольку я в основном пишу управляемый код (C# и C++/CLI), то boost менее применим.

Abdelrahman Elzedy

Я думаю, что этот код поможет вам
Наилучшие пожелания

Рейтинг:
1

Sergey Alexandrovich Kryukov

В этом нет ничего особенного: чтобы иметь код, его нужно проектировать, разрабатывать и отлаживать. Вместо того, чтобы смотреть по сторонам целую вечность. О чем спрашивать? Если вы не являетесь разработчиком программного обеспечения, то этот форум не для вас, но если вы им являетесь — просто приступайте к работе.
Никто не может сказать вам, сколько строк кода вам понадобится. Как считать эти строки? В любом случае, это ваш код. Кто знает ваши навыки и стиль?

Мне также было бы любопытно: зачем вам вообще нужен калькулятор? Есть много способов рассчитать вещи.

Если у вас есть какие-то конкретные проблемы, пожалуйста, задайте вопрос, мы с радостью постараемся вам помочь.

—СА


Cameron Handoe

Это просто небольшое развлечение и упражнение по кодированию. Я довольно Новичок и хочу оценить свои способности до сих пор.

Спасибо за ответ, я очень ценю это.

Я просто хотел знать, что было бы лучшим методом, чтобы быть в состоянии к этому

Sergey Alexandrovich Kryukov

Ну, для удовольствия или нет, это не меняет технологии. Если вы сделаете это и столкнетесь с некоторыми проблемами, я постараюсь помочь.
Вот почему я спрашиваю "почему калькулятор": например: JavaScript уже является калькулятором, потому что вы можете использовать Eval, то есть вы можете использовать JavaScript для интерпретации кода и представления результата. Пожалуйста, посмотрите мои:
http://sakryukov.org/freeware/calculator/.
Это всего лишь несколько строк кода JavaScript.
Более продвинутый подход (но почему?) заключается в использовании CodeDom для компиляции конечного кода выполнения во время выполнения. Это также освобождает вас от разбора исключений, потому что вы можете использовать C# или VB.NET для компилятора выражений. Компиляторы поставляются бесплатно вместе с .NET.
--СА

Cameron Handoe

Ух ты! Этот код впечатляет!

Причина, по которой я хотел закодировать его на C/C++, заключается просто в том, что я изучаю C/C++, и мне нужен был вызов.

Очевидно, вы эксперт. Мне просто нужно знать лучший способ хранения переменных, чтобы мой калькулятор не был ограничен

Sergey Alexandrovich Kryukov

Если вам нравится моя идея, вы примете ответ формально (зеленая кнопка)? -- спасибо.
Я действительно не понимаю вашу проблему с хранением переменных. Если вам нужно сделать калькулятор с выражением (единственный, который имеет некоторый смысл), вам нужно будет разобрать выражение в дерево и сохранить все в этом дереве. Попробуйте найти CodeProject:

http://www.codeproject.com/search.aspx?doctypeid=1&q=%22C%2b%2b%22+expression+%28parser+OR+evaluator%29

--СА

SajeeshCheviry

Вы абсолютно правы

Sergey Alexandrovich Kryukov

Спасибо, Саджиш.
—СА

SajeeshCheviry

добро пожаловать :-)