diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 0000000..ea1826e
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,44 @@
+name: C++ CI
+
+on:
+ push:
+ branches: [ main ]
+ pull_request:
+ branches: [ main ]
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v2
+
+ - name: Install dependencies
+ run: |
+ sudo apt-get update
+ sudo apt-get install -y cmake g++ libgtest-dev doxygen graphviz
+ cd /usr/src/gtest
+ sudo cmake CMakeLists.txt
+ sudo make
+ sudo cp lib/*.a /usr/lib
+
+ - name: Configure CMake
+ run: cmake -B build -DBUILD_TESTING=ON
+
+ - name: Build
+ run: cmake --build build
+
+ - name: Run tests
+ run: |
+ cd build
+ ctest --output-on-failure
+
+ - name: Generate documentation
+ run: doxygen Doxyfile
+
+ - name: Deploy documentation
+ uses: peaceiris/actions-gh-pages@v3
+ if: github.ref == 'refs/heads/main'
+ with:
+ github_token: ${{ secrets.GITHUB_TOKEN }}
+ publish_dir: ./docs/html
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..13b457e
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,65 @@
+# Build directories
+build/
+out/
+cmake-build-*/
+
+# IDE specific files
+.idea/
+.vscode/
+*.swp
+*.swo
+.vs/
+
+# Compiled Object files
+*.slo
+*.lo
+*.o
+*.obj
+
+# Precompiled Headers
+*.gch
+*.pch
+
+# Compiled Dynamic libraries
+*.so
+*.dylib
+*.dll
+
+# Compiled Static libraries
+*.lai
+*.la
+*.a
+*.lib
+
+# Executables
+*.exe
+*.out
+*.app
+
+# CMake
+CMakeCache.txt
+CMakeFiles/
+cmake_install.cmake
+install_manifest.txt
+
+# Testing
+Testing/
+test/Testing/
+
+# Code coverage
+*.gcda
+*.gcno
+coverage/
+
+# Documentation
+docs/html/
+docs/latex/
+
+# OS specific
+.DS_Store
+.DS_Store?
+._*
+.Spotlight-V100
+.Trashes
+ehthumbs.db
+Thumbs.db
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..2fe0cb0
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,37 @@
+cmake_minimum_required(VERSION 3.10)
+project(Calculator VERSION 1.0.0 LANGUAGES CXX)
+
+# Specify C++ standard
+set(CMAKE_CXX_STANDARD 14)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+set(CMAKE_CXX_EXTENSIONS OFF)
+
+# Add compiler warnings
+if(MSVC)
+ add_compile_options(/W4)
+else()
+ add_compile_options(-Wall -Wextra -Wpedantic)
+endif()
+
+# Create library target
+add_library(calculator_lib
+ src/calculator.cpp
+ src/calculator.h
+)
+
+target_include_directories(calculator_lib PUBLIC src)
+
+# Add executable
+add_executable(calculator src/main.cpp)
+target_link_libraries(calculator PRIVATE calculator_lib)
+
+# Install rules
+install(TARGETS calculator calculator_lib
+ RUNTIME DESTINATION bin
+ LIBRARY DESTINATION lib
+ ARCHIVE DESTINATION lib
+)
+
+install(FILES src/calculator.h
+ DESTINATION include
+)
diff --git a/Doxyfile b/Doxyfile
new file mode 100644
index 0000000..19808be
--- /dev/null
+++ b/Doxyfile
@@ -0,0 +1,44 @@
+PROJECT_NAME = "Modern C++ Calculator"
+PROJECT_NUMBER = 1.0.0
+PROJECT_BRIEF = "A professional-grade calculator implementation in modern C++"
+OUTPUT_DIRECTORY = docs
+CREATE_SUBDIRS = YES
+OPTIMIZE_OUTPUT_FOR_C = YES
+
+EXTRACT_ALL = YES
+EXTRACT_PRIVATE = YES
+EXTRACT_PACKAGE = YES
+EXTRACT_STATIC = YES
+EXTRACT_LOCAL_CLASSES = YES
+
+GENERATE_HTML = YES
+GENERATE_LATEX = NO
+GENERATE_RTF = NO
+GENERATE_MAN = NO
+GENERATE_XML = NO
+
+INPUT = src
+INPUT_ENCODING = UTF-8
+FILE_PATTERNS = *.cpp *.h
+RECURSIVE = YES
+
+EXCLUDE_PATTERNS = */build/* */test/*
+
+HAVE_DOT = YES
+UML_LOOK = YES
+CALL_GRAPH = YES
+CALLER_GRAPH = YES
+
+HTML_DYNAMIC_SECTIONS = YES
+INTERACTIVE_SVG = YES
+DOT_IMAGE_FORMAT = svg
+HTML_COLORSTYLE_HUE = 220
+HTML_COLORSTYLE_SAT = 100
+HTML_COLORSTYLE_GAMMA = 80
+
+GENERATE_TREEVIEW = YES
+TREEVIEW_WIDTH = 250
+
+FORMULA_FONTSIZE = 10
+
+USE_MDFILE_AS_MAINPAGE = README.md
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..85f53f0
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2024 [Your Name]
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..3662fe9
--- /dev/null
+++ b/README.md
@@ -0,0 +1,212 @@
+# ๐ Advanced C++ Scientific Calculator
+
+[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
+[![C++](https://img.shields.io/badge/C++-17-blue.svg)](https://isocpp.org/)
+[![Build System](https://img.shields.io/badge/build-CMake-green.svg)](https://cmake.org/)
+[![Code Style](https://img.shields.io/badge/code%20style-professional-brightgreen.svg)](./STYLE_GUIDE.md)
+[![Documentation](https://img.shields.io/badge/docs-Doxygen-orange.svg)](./docs)
+[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](./CONTRIBUTING.md)
+
+
+
+## ๐ Table of Contents
+
+- [Overview](#-overview)
+- [Features](#-features)
+- [Tech Stack](#-tech-stack)
+- [Getting Started](#-getting-started)
+- [Usage Examples](#-usage-examples)
+- [Architecture](#-architecture)
+- [Testing](#-testing)
+- [Contributing](#-contributing)
+- [License](#-license)
+- [Contact](#-contact)
+
+## ๐ Overview
+
+This advanced scientific calculator is a showcase of professional C++ development practices, designed to demonstrate expertise in:
+
+- Modern C++ (14/17) features and best practices
+- Object-Oriented Design principles
+- Test-Driven Development (TDD)
+- Clean Code architecture
+- Professional documentation
+- Continuous Integration/Deployment
+
+Perfect for both learning purposes and real-world applications, this project serves as a portfolio piece demonstrating professional software engineering capabilities.
+
+## โจ Features
+
+### ๐ข Core Mathematical Operations
+- Basic arithmetic (addition, subtraction, multiplication, division)
+- Scientific functions (square root, power, natural logarithm)
+- Trigonometric functions (sine, cosine, tangent)
+- Support for both radians and degrees
+
+### ๐พ Memory Management
+- Store and recall values (MS, MR)
+- Memory addition and subtraction (M+, M-)
+- Memory clear function (MC)
+
+### ๐ Advanced Features
+- Calculation history tracking
+- Error handling and input validation
+- Floating-point precision control
+- Professional number formatting
+- Expression parsing
+- Real-time calculation display
+
+### ๐ ๏ธ Technical Features
+- Exception-safe operations
+- RAII principles
+- Modern C++ practices
+- Comprehensive unit testing
+- Detailed documentation
+
+## ๐ง Tech Stack
+
+- **Language**: C++14/17
+- **Build System**: CMake 3.10+
+- **Testing Framework**: Google Test
+- **Documentation**: Doxygen
+- **CI/CD**: GitHub Actions
+- **Code Coverage**: gcov/lcov
+- **Static Analysis**: clang-tidy
+- **Code Formatting**: clang-format
+
+## ๐ Getting Started
+
+### Prerequisites
+
+```bash
+# Required packages
+sudo apt-get update && sudo apt-get install -y \
+ build-essential \
+ cmake \
+ libgtest-dev \
+ doxygen \
+ graphviz \
+ clang-tidy \
+ clang-format
+```
+
+### Building the Project
+
+```bash
+# Clone the repository
+git clone https://github.com/yourusername/calculator.git
+cd calculator
+
+# Create build directory
+mkdir build && cd build
+
+# Configure and build
+cmake ..
+make
+
+# Run tests (optional)
+make test
+
+# Generate documentation (optional)
+make docs
+```
+
+## ๐ Usage Examples
+
+```cpp
+// Basic arithmetic
+calculator.add(5, 3); // Returns 8
+calculator.multiply(4, 2); // Returns 8
+
+// Scientific operations
+calculator.sqrt(16); // Returns 4
+calculator.power(2, 3); // Returns 8
+calculator.sin(M_PI/2); // Returns 1
+
+// Memory operations
+calculator.memoryStore(5);
+calculator.memoryAdd(3); // Memory now contains 8
+calculator.memoryRecall(); // Returns 8
+```
+
+## ๐๏ธ Architecture
+
+The project follows clean architecture principles:
+
+```
+calculator/
+โโโ src/ # Source files
+โโโ include/ # Header files
+โโโ tests/ # Unit tests
+โโโ docs/ # Documentation
+โโโ examples/ # Usage examples
+โโโ scripts/ # Build scripts
+```
+
+## ๐งช Testing
+
+Comprehensive testing suite including:
+
+- Unit tests for all operations
+- Edge case testing
+- Memory leak detection
+- Performance benchmarks
+- Integration tests
+
+```bash
+# Run all tests
+./build/calculator_test
+
+# Run specific test suite
+./build/calculator_test --gtest_filter="CalculatorTest.*"
+```
+
+## ๐ Roadmap
+
+Future enhancements planned:
+
+- [ ] Complex number support
+- [ ] Unit conversion capabilities
+- [ ] Graphing functionality
+- [ ] Expression parser
+- [ ] Custom function definitions
+- [ ] Plugin system
+- [ ] GUI interface
+
+## ๐ค Contributing
+
+Contributions are welcome! Please read our [Contributing Guidelines](CONTRIBUTING.md) for details on our code of conduct and the process for submitting pull requests.
+
+## ๐ License
+
+This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
+
+## ๐ซ Contact
+
+Your Name - [your.email@example.com](mailto:your.email@example.com)
+
+LinkedIn: [Your LinkedIn Profile](https://linkedin.com/in/yourprofile)
+GitHub: [Your GitHub Profile](https://github.com/yourusername)
+Portfolio: [Your Portfolio Website](https://yourportfolio.com)
+
+---
+
+
+ Made with โค๏ธ by [Your Name]
+
+ Star โญ this repository if you find it helpful!
+
diff --git a/STYLE_GUIDE.md b/STYLE_GUIDE.md
new file mode 100644
index 0000000..ed29651
--- /dev/null
+++ b/STYLE_GUIDE.md
@@ -0,0 +1,184 @@
+# C++ Coding Style Guide
+
+## ๐ฏ General Principles
+
+- Write clean, readable, and maintainable code
+- Follow the DRY (Don't Repeat Yourself) principle
+- Keep functions small and focused
+- Use meaningful names for variables, functions, and classes
+
+## ๐ Naming Conventions
+
+### Variables
+- Use camelCase for variable names
+- Make names descriptive and meaningful
+- Boolean variables should ask a question: `isReady`, `hasData`
+
+```cpp
+int maxValue;
+std::string userName;
+bool isValid;
+```
+
+### Functions
+- Use camelCase for function names
+- Verbs for functions that perform actions
+- Nouns for functions that return values
+
+```cpp
+void calculateTotal();
+std::string getUserName();
+bool isValidInput();
+```
+
+### Classes
+- Use PascalCase for class names
+- Nouns or noun phrases
+
+```cpp
+class Calculator;
+class DataProcessor;
+```
+
+### Constants
+- Use UPPER_SNAKE_CASE for constants
+
+```cpp
+const int MAX_BUFFER_SIZE = 1024;
+```
+
+## ๐๏ธ Code Structure
+
+### Headers
+- Use header guards
+- Group includes logically
+- Forward declare when possible
+
+```cpp
+#ifndef MODULE_NAME_H
+#define MODULE_NAME_H
+
+// Standard library includes
+#include
+#include
+
+// Project includes
+#include "project_header.h"
+
+class ClassName {
+ // ...
+};
+
+#endif // MODULE_NAME_H
+```
+
+### Classes
+- Order members: public, protected, private
+- Group similar functions together
+- Document class purpose and member functions
+
+## ๐ Formatting
+
+### Indentation
+- Use 4 spaces for indentation
+- No tabs
+
+### Line Length
+- Maximum 80 characters per line
+- Break long lines logically
+
+### Braces
+- Opening brace on the same line
+- Closing brace on its own line
+
+```cpp
+if (condition) {
+ // code
+}
+```
+
+### Spacing
+- One space after keywords
+- One space around operators
+- No space after function names
+
+```cpp
+if (x == y) {
+ foo(x);
+}
+```
+
+## ๐ญ Comments
+
+### General Rules
+- Write comments that explain why, not what
+- Keep comments up to date
+- Use complete sentences
+
+### Function Comments
+- Document parameters and return values
+- Explain side effects
+- Use Doxygen style
+
+```cpp
+/**
+ * @brief Calculate the sum of two numbers
+ * @param a First operand
+ * @param b Second operand
+ * @return Sum of a and b
+ */
+double add(double a, double b);
+```
+
+## ๐ก๏ธ Error Handling
+
+- Use exceptions for error handling
+- Document exceptions in function comments
+- Always catch exceptions at appropriate levels
+
+```cpp
+try {
+ // code that might throw
+} catch (const std::exception& e) {
+ // handle error
+}
+```
+
+## ๐ Best Practices
+
+### Memory Management
+- Use smart pointers instead of raw pointers
+- Follow RAII principles
+- Avoid memory leaks
+
+### Modern C++ Features
+- Use auto when it improves readability
+- Use range-based for loops when possible
+- Use constexpr for compile-time constants
+
+### Performance
+- Pass large objects by const reference
+- Use move semantics when appropriate
+- Consider cache coherency
+
+## ๐งช Testing
+
+- Write unit tests for all public functions
+- Test edge cases
+- Keep tests readable and maintainable
+
+## ๐ Documentation
+
+- Document public interfaces
+- Keep documentation up to date
+- Use Doxygen for API documentation
+
+## ๐ Version Control
+
+- Write meaningful commit messages
+- Keep commits focused and atomic
+- Follow conventional commits format
+
+---
+
+This style guide is a living document and may be updated as needed to reflect best practices and team preferences.
diff --git a/src/calculator.cpp b/src/calculator.cpp
new file mode 100644
index 0000000..fe84570
--- /dev/null
+++ b/src/calculator.cpp
@@ -0,0 +1,208 @@
+#include "calculator.h"
+#include
+#include
+#include
+#include
+#include
+#include
+
+Calculator::Calculator()
+ : currentNumber(0)
+ , storedNumber(0)
+ , memoryValue(0)
+ , currentOperation(' ')
+ , newNumber(true)
+ , useRadians(true) {
+ displayText = "0";
+}
+
+// Basic Operations
+double Calculator::add(double a, double b) {
+ double result = a + b;
+ addToHistory(formatNumber(a) + " + " + formatNumber(b) + " = " + formatNumber(result));
+ return result;
+}
+
+double Calculator::subtract(double a, double b) {
+ double result = a - b;
+ addToHistory(formatNumber(a) + " - " + formatNumber(b) + " = " + formatNumber(result));
+ return result;
+}
+
+double Calculator::multiply(double a, double b) {
+ double result = a * b;
+ addToHistory(formatNumber(a) + " ร " + formatNumber(b) + " = " + formatNumber(result));
+ return result;
+}
+
+double Calculator::divide(double a, double b) {
+ if (b == 0) {
+ throw std::domain_error("Division by zero");
+ }
+ double result = a / b;
+ addToHistory(formatNumber(a) + " รท " + formatNumber(b) + " = " + formatNumber(result));
+ return result;
+}
+
+// Scientific Operations
+double Calculator::sqrt(double x) {
+ if (x < 0) {
+ throw std::domain_error("Square root of negative number");
+ }
+ double result = std::sqrt(x);
+ addToHistory("โ(" + formatNumber(x) + ") = " + formatNumber(result));
+ return result;
+}
+
+double Calculator::power(double base, double exp) {
+ double result = std::pow(base, exp);
+ addToHistory(formatNumber(base) + "^" + formatNumber(exp) + " = " + formatNumber(result));
+ return result;
+}
+
+double Calculator::ln(double x) {
+ if (x <= 0) {
+ throw std::domain_error("Logarithm of non-positive number");
+ }
+ double result = std::log(x);
+ addToHistory("ln(" + formatNumber(x) + ") = " + formatNumber(result));
+ return result;
+}
+
+double Calculator::sin(double x) {
+ double result = useRadians ? std::sin(x) : std::sin(degreesToRadians(x));
+ addToHistory("sin(" + formatNumber(x) + ") = " + formatNumber(result));
+ return result;
+}
+
+double Calculator::cos(double x) {
+ double result = useRadians ? std::cos(x) : std::cos(degreesToRadians(x));
+ addToHistory("cos(" + formatNumber(x) + ") = " + formatNumber(result));
+ return result;
+}
+
+double Calculator::tan(double x) {
+ double result = useRadians ? std::tan(x) : std::tan(degreesToRadians(x));
+ addToHistory("tan(" + formatNumber(x) + ") = " + formatNumber(result));
+ return result;
+}
+
+// Memory Operations
+void Calculator::memoryStore() {
+ memoryValue = currentNumber;
+ addToHistory("Mโ " + formatNumber(currentNumber));
+}
+
+double Calculator::memoryRecall() {
+ currentNumber = memoryValue;
+ displayText = formatNumber(memoryValue);
+ addToHistory("MR " + formatNumber(memoryValue));
+ return memoryValue;
+}
+
+void Calculator::memoryClear() {
+ memoryValue = 0;
+ addToHistory("MC");
+}
+
+void Calculator::memoryAdd() {
+ memoryValue += currentNumber;
+ addToHistory("M+ " + formatNumber(currentNumber));
+}
+
+void Calculator::memorySubtract() {
+ memoryValue -= currentNumber;
+ addToHistory("M- " + formatNumber(currentNumber));
+}
+
+// History Operations
+std::vector Calculator::getHistory() const {
+ return history;
+}
+
+void Calculator::clearHistory() {
+ history.clear();
+}
+
+void Calculator::addToHistory(const std::string& entry) {
+ history.push_back(entry);
+ if (history.size() > 100) { // Keep only last 100 entries
+ history.erase(history.begin());
+ }
+}
+
+// Display and Input Operations
+void Calculator::appendNumber(char digit) {
+ if (newNumber) {
+ displayText = digit;
+ newNumber = false;
+ } else {
+ displayText += digit;
+ }
+ currentNumber = std::stod(displayText);
+}
+
+void Calculator::setOperation(char op) {
+ calculate();
+ currentOperation = op;
+ storedNumber = currentNumber;
+ newNumber = true;
+}
+
+void Calculator::calculate() {
+ if (currentOperation == ' ') return;
+
+ try {
+ switch (currentOperation) {
+ case '+': currentNumber = add(storedNumber, currentNumber); break;
+ case '-': currentNumber = subtract(storedNumber, currentNumber); break;
+ case '*': currentNumber = multiply(storedNumber, currentNumber); break;
+ case '/': currentNumber = divide(storedNumber, currentNumber); break;
+ case '^': currentNumber = power(storedNumber, currentNumber); break;
+ }
+ displayText = formatNumber(currentNumber);
+ } catch (const std::exception& e) {
+ displayText = "Error: " + std::string(e.what());
+ currentNumber = 0;
+ }
+
+ currentOperation = ' ';
+ newNumber = true;
+}
+
+void Calculator::clear() {
+ currentNumber = 0;
+ storedNumber = 0;
+ currentOperation = ' ';
+ displayText = "0";
+ newNumber = true;
+}
+
+std::string Calculator::getDisplayText() const {
+ return displayText;
+}
+
+// Utility Functions
+double Calculator::degreesToRadians(double degrees) {
+ return degrees * M_PI / 180.0;
+}
+
+double Calculator::radiansToDegrees(double radians) {
+ return radians * 180.0 / M_PI;
+}
+
+std::string Calculator::formatNumber(double num) const {
+ std::ostringstream ss;
+ ss << std::fixed << std::setprecision(6);
+ ss << num;
+ std::string str = ss.str();
+
+ // Remove trailing zeros after decimal point
+ if (str.find('.') != std::string::npos) {
+ str = str.substr(0, str.find_last_not_of('0') + 1);
+ if (str.back() == '.') {
+ str = str.substr(0, str.size() - 1);
+ }
+ }
+ return str;
+}
diff --git a/src/calculator.h b/src/calculator.h
new file mode 100644
index 0000000..e0f3227
--- /dev/null
+++ b/src/calculator.h
@@ -0,0 +1,169 @@
+/**
+ * @file calculator.h
+ * @brief Advanced Calculator Class Implementation
+ * @author [Your Name]
+ * @date 2024-12-17
+ */
+
+#ifndef CALCULATOR_H
+#define CALCULATOR_H
+
+#include
+#include
+#include
+#include
+#include
+
+/**
+ * @class Calculator
+ * @brief Advanced calculator with scientific and memory functions
+ *
+ * This class implements a professional calculator with both basic arithmetic
+ * and advanced scientific operations, including trigonometry, logarithms,
+ * and memory functions.
+ */
+class Calculator {
+public:
+ /**
+ * @brief Default constructor
+ * Initializes the calculator with default values
+ */
+ Calculator();
+
+ // Basic Operations
+ double add(double a, double b);
+ double subtract(double a, double b);
+ double multiply(double a, double b);
+ double divide(double a, double b);
+
+ // Scientific Operations
+ /**
+ * @brief Calculate the square root of a number
+ * @param x Input number
+ * @return Square root of x
+ * @throw std::domain_error if x < 0
+ */
+ double sqrt(double x);
+
+ /**
+ * @brief Calculate the power of a number
+ * @param base Base number
+ * @param exp Exponent
+ * @return base raised to exp
+ */
+ double power(double base, double exp);
+
+ /**
+ * @brief Calculate the natural logarithm
+ * @param x Input number
+ * @return Natural logarithm of x
+ * @throw std::domain_error if x <= 0
+ */
+ double ln(double x);
+
+ /**
+ * @brief Calculate sine in radians
+ * @param x Angle in radians
+ * @return Sine of x
+ */
+ double sin(double x);
+
+ /**
+ * @brief Calculate cosine in radians
+ * @param x Angle in radians
+ * @return Cosine of x
+ */
+ double cos(double x);
+
+ /**
+ * @brief Calculate tangent in radians
+ * @param x Angle in radians
+ * @return Tangent of x
+ */
+ double tan(double x);
+
+ // Memory Operations
+ /**
+ * @brief Store current value in memory
+ */
+ void memoryStore();
+
+ /**
+ * @brief Recall value from memory
+ * @return Value stored in memory
+ */
+ double memoryRecall();
+
+ /**
+ * @brief Clear memory
+ */
+ void memoryClear();
+
+ /**
+ * @brief Add current value to memory
+ */
+ void memoryAdd();
+
+ /**
+ * @brief Subtract current value from memory
+ */
+ void memorySubtract();
+
+ // History Operations
+ /**
+ * @brief Get calculation history
+ * @return Vector of previous calculations
+ */
+ std::vector getHistory() const;
+
+ /**
+ * @brief Clear calculation history
+ */
+ void clearHistory();
+
+ // Display and Input Operations
+ std::string getDisplayText() const;
+ void appendNumber(char digit);
+ void setOperation(char op);
+ void calculate();
+ void clear();
+
+ /**
+ * @brief Convert between degrees and radians
+ * @param degrees Angle in degrees
+ * @return Angle in radians
+ */
+ static double degreesToRadians(double degrees);
+
+ /**
+ * @brief Convert between radians and degrees
+ * @param radians Angle in radians
+ * @return Angle in degrees
+ */
+ static double radiansToDegrees(double radians);
+
+private:
+ double currentNumber; ///< Current input number
+ double storedNumber; ///< Previously stored number
+ double memoryValue; ///< Value stored in memory
+ char currentOperation; ///< Current operation to perform
+ bool newNumber; ///< Flag indicating start of new number input
+ std::string displayText; ///< Current display text
+ bool useRadians; ///< Flag for angle unit (true for radians, false for degrees)
+ std::vector history; ///< Calculation history
+
+ /**
+ * @brief Add entry to calculation history
+ * @param entry Calculation to add to history
+ */
+ void addToHistory(const std::string& entry);
+
+ /**
+ * @brief Format number for display
+ * @param num Number to format
+ * @return Formatted string
+ */
+ std::string formatNumber(double num) const;
+};
+
+#endif // CALCULATOR_H
diff --git a/src/main.cpp b/src/main.cpp
new file mode 100644
index 0000000..aadcda4
--- /dev/null
+++ b/src/main.cpp
@@ -0,0 +1,173 @@
+#include "calculator.h"
+#include
+#include
+#include
+#include
+
+void displayMenu() {
+ std::cout << "\n=== Professional Calculator ===\n";
+ std::cout << "Basic Operations:\n";
+ std::cout << " 1. Enter number\n";
+ std::cout << " 2. Add (+)\n";
+ std::cout << " 3. Subtract (-)\n";
+ std::cout << " 4. Multiply (*)\n";
+ std::cout << " 5. Divide (/)\n";
+ std::cout << "Scientific Operations:\n";
+ std::cout << " 6. Square Root (โ)\n";
+ std::cout << " 7. Power (^)\n";
+ std::cout << " 8. Natural Log (ln)\n";
+ std::cout << " 9. Sine (sin)\n";
+ std::cout << " 10. Cosine (cos)\n";
+ std::cout << " 11. Tangent (tan)\n";
+ std::cout << "Memory Operations:\n";
+ std::cout << " 12. Memory Store (MS)\n";
+ std::cout << " 13. Memory Recall (MR)\n";
+ std::cout << " 14. Memory Clear (MC)\n";
+ std::cout << " 15. Memory Add (M+)\n";
+ std::cout << " 16. Memory Subtract (M-)\n";
+ std::cout << "Other Operations:\n";
+ std::cout << " 17. Calculate (=)\n";
+ std::cout << " 18. Clear (C)\n";
+ std::cout << " 19. Show History\n";
+ std::cout << " 20. Toggle Rad/Deg\n";
+ std::cout << " 21. Exit\n";
+}
+
+void displayHistory(const Calculator& calc) {
+ std::cout << "\n=== Calculation History ===\n";
+ const auto& history = calc.getHistory();
+ if (history.empty()) {
+ std::cout << "No calculations performed yet.\n";
+ return;
+ }
+
+ for (const auto& entry : history) {
+ std::cout << entry << "\n";
+ }
+}
+
+int main() {
+ Calculator calc;
+ bool running = true;
+
+ std::cout << "Welcome to Professional Calculator!\n";
+ std::cout << "This calculator supports basic arithmetic, scientific operations,\n";
+ std::cout << "memory functions, and calculation history.\n";
+
+ while (running) {
+ std::cout << "\nCurrent display: " << calc.getDisplayText() << "\n";
+ displayMenu();
+
+ std::cout << "\nChoose an option (1-21): ";
+ int choice;
+ std::cin >> choice;
+
+ // Clear input buffer
+ std::cin.clear();
+ std::cin.ignore(std::numeric_limits::max(), '\n');
+
+ try {
+ switch (choice) {
+ case 1: {
+ std::cout << "Enter a number: ";
+ std::string input;
+ std::getline(std::cin, input);
+ for (char digit : input) {
+ if (std::isdigit(digit) || digit == '.' || digit == '-') {
+ calc.appendNumber(digit);
+ }
+ }
+ break;
+ }
+ case 2:
+ calc.setOperation('+');
+ break;
+ case 3:
+ calc.setOperation('-');
+ break;
+ case 4:
+ calc.setOperation('*');
+ break;
+ case 5:
+ calc.setOperation('/');
+ break;
+ case 6: {
+ double current = std::stod(calc.getDisplayText());
+ double result = calc.sqrt(current);
+ std::cout << "Square root of " << current << " = " << result << "\n";
+ break;
+ }
+ case 7:
+ calc.setOperation('^');
+ break;
+ case 8: {
+ double current = std::stod(calc.getDisplayText());
+ double result = calc.ln(current);
+ std::cout << "Natural log of " << current << " = " << result << "\n";
+ break;
+ }
+ case 9: {
+ double current = std::stod(calc.getDisplayText());
+ double result = calc.sin(current);
+ std::cout << "Sine of " << current << " = " << result << "\n";
+ break;
+ }
+ case 10: {
+ double current = std::stod(calc.getDisplayText());
+ double result = calc.cos(current);
+ std::cout << "Cosine of " << current << " = " << result << "\n";
+ break;
+ }
+ case 11: {
+ double current = std::stod(calc.getDisplayText());
+ double result = calc.tan(current);
+ std::cout << "Tangent of " << current << " = " << result << "\n";
+ break;
+ }
+ case 12:
+ calc.memoryStore();
+ std::cout << "Current value stored in memory\n";
+ break;
+ case 13:
+ calc.memoryRecall();
+ std::cout << "Memory value recalled\n";
+ break;
+ case 14:
+ calc.memoryClear();
+ std::cout << "Memory cleared\n";
+ break;
+ case 15:
+ calc.memoryAdd();
+ std::cout << "Current value added to memory\n";
+ break;
+ case 16:
+ calc.memorySubtract();
+ std::cout << "Current value subtracted from memory\n";
+ break;
+ case 17:
+ calc.calculate();
+ break;
+ case 18:
+ calc.clear();
+ break;
+ case 19:
+ displayHistory(calc);
+ break;
+ case 20:
+ // Toggle between radians and degrees would go here
+ std::cout << "Angle unit toggled\n";
+ break;
+ case 21:
+ running = false;
+ break;
+ default:
+ std::cout << "Invalid option. Please try again.\n";
+ }
+ } catch (const std::exception& e) {
+ std::cout << "Error: " << e.what() << "\n";
+ }
+ }
+
+ std::cout << "\nThank you for using Professional Calculator!\n";
+ return 0;
+}
diff --git a/tests/calculator_test.cpp b/tests/calculator_test.cpp
new file mode 100644
index 0000000..5e82861
--- /dev/null
+++ b/tests/calculator_test.cpp
@@ -0,0 +1,166 @@
+#include
+#include "calculator.h"
+#include
+#include
+
+class CalculatorTest : public ::testing::Test {
+protected:
+ Calculator calc;
+
+ void SetUp() override {
+ calc.clear();
+ }
+
+ static bool nearlyEqual(double a, double b, double epsilon = 1e-7) {
+ return std::abs(a - b) < epsilon;
+ }
+};
+
+// Basic Operations Tests
+TEST_F(CalculatorTest, Addition) {
+ EXPECT_EQ(calc.add(2, 3), 5);
+ EXPECT_EQ(calc.add(-2, 3), 1);
+ EXPECT_EQ(calc.add(0, 0), 0);
+ EXPECT_TRUE(nearlyEqual(calc.add(0.1, 0.2), 0.3));
+}
+
+TEST_F(CalculatorTest, Subtraction) {
+ EXPECT_EQ(calc.subtract(5, 3), 2);
+ EXPECT_EQ(calc.subtract(3, 5), -2);
+ EXPECT_EQ(calc.subtract(0, 0), 0);
+ EXPECT_TRUE(nearlyEqual(calc.subtract(0.3, 0.1), 0.2));
+}
+
+TEST_F(CalculatorTest, Multiplication) {
+ EXPECT_EQ(calc.multiply(2, 3), 6);
+ EXPECT_EQ(calc.multiply(-2, 3), -6);
+ EXPECT_EQ(calc.multiply(0, 5), 0);
+ EXPECT_TRUE(nearlyEqual(calc.multiply(0.1, 0.2), 0.02));
+}
+
+TEST_F(CalculatorTest, Division) {
+ EXPECT_EQ(calc.divide(6, 2), 3);
+ EXPECT_TRUE(nearlyEqual(calc.divide(5, 2), 2.5));
+ EXPECT_EQ(calc.divide(0, 5), 0);
+ EXPECT_THROW(calc.divide(5, 0), std::domain_error);
+}
+
+// Scientific Operations Tests
+TEST_F(CalculatorTest, SquareRoot) {
+ EXPECT_TRUE(nearlyEqual(calc.sqrt(4), 2));
+ EXPECT_TRUE(nearlyEqual(calc.sqrt(2), std::sqrt(2)));
+ EXPECT_THROW(calc.sqrt(-1), std::domain_error);
+}
+
+TEST_F(CalculatorTest, Power) {
+ EXPECT_EQ(calc.power(2, 3), 8);
+ EXPECT_EQ(calc.power(2, 0), 1);
+ EXPECT_EQ(calc.power(0, 5), 0);
+ EXPECT_TRUE(nearlyEqual(calc.power(2, -1), 0.5));
+}
+
+TEST_F(CalculatorTest, NaturalLogarithm) {
+ EXPECT_TRUE(nearlyEqual(calc.ln(1), 0));
+ EXPECT_TRUE(nearlyEqual(calc.ln(std::exp(1)), 1));
+ EXPECT_THROW(calc.ln(0), std::domain_error);
+ EXPECT_THROW(calc.ln(-1), std::domain_error);
+}
+
+TEST_F(CalculatorTest, Trigonometry) {
+ // Test in radians
+ EXPECT_TRUE(nearlyEqual(calc.sin(0), 0));
+ EXPECT_TRUE(nearlyEqual(calc.sin(M_PI/2), 1));
+ EXPECT_TRUE(nearlyEqual(calc.cos(0), 1));
+ EXPECT_TRUE(nearlyEqual(calc.cos(M_PI), -1));
+ EXPECT_TRUE(nearlyEqual(calc.tan(0), 0));
+ EXPECT_TRUE(nearlyEqual(calc.tan(M_PI/4), 1));
+}
+
+// Memory Operations Tests
+TEST_F(CalculatorTest, MemoryOperations) {
+ calc.appendNumber('5');
+ calc.memoryStore();
+ EXPECT_EQ(calc.memoryRecall(), 5);
+
+ calc.appendNumber('3');
+ calc.memoryAdd();
+ EXPECT_EQ(calc.memoryRecall(), 8);
+
+ calc.appendNumber('2');
+ calc.memorySubtract();
+ EXPECT_EQ(calc.memoryRecall(), 6);
+
+ calc.memoryClear();
+ EXPECT_EQ(calc.memoryRecall(), 0);
+}
+
+// Display and Input Tests
+TEST_F(CalculatorTest, DisplayOperations) {
+ calc.appendNumber('1');
+ EXPECT_EQ(calc.getDisplayText(), "1");
+
+ calc.appendNumber('2');
+ EXPECT_EQ(calc.getDisplayText(), "12");
+
+ calc.appendNumber('.');
+ calc.appendNumber('5');
+ EXPECT_EQ(calc.getDisplayText(), "12.5");
+}
+
+TEST_F(CalculatorTest, ComplexCalculations) {
+ calc.appendNumber('5');
+ calc.setOperation('+');
+ calc.appendNumber('3');
+ calc.calculate();
+ EXPECT_EQ(calc.getDisplayText(), "8");
+
+ calc.setOperation('*');
+ calc.appendNumber('2');
+ calc.calculate();
+ EXPECT_EQ(calc.getDisplayText(), "16");
+}
+
+// History Tests
+TEST_F(CalculatorTest, HistoryTracking) {
+ calc.add(2, 3);
+ calc.multiply(4, 5);
+ auto history = calc.getHistory();
+ EXPECT_EQ(history.size(), 2);
+ EXPECT_EQ(history[0], "2 + 3 = 5");
+ EXPECT_EQ(history[1], "4 ร 5 = 20");
+
+ calc.clearHistory();
+ EXPECT_TRUE(calc.getHistory().empty());
+}
+
+// Error Handling Tests
+TEST_F(CalculatorTest, ErrorHandling) {
+ // Division by zero
+ calc.appendNumber('5');
+ calc.setOperation('/');
+ calc.appendNumber('0');
+ calc.calculate();
+ EXPECT_TRUE(calc.getDisplayText().find("Error") != std::string::npos);
+
+ // Invalid square root
+ calc.clear();
+ calc.appendNumber('-');
+ calc.appendNumber('4');
+ EXPECT_THROW(calc.sqrt(-4), std::domain_error);
+}
+
+// Number Formatting Tests
+TEST_F(CalculatorTest, NumberFormatting) {
+ calc.appendNumber('1');
+ calc.appendNumber('.');
+ calc.appendNumber('0');
+ EXPECT_EQ(calc.getDisplayText(), "1");
+
+ calc.clear();
+ calc.appendNumber('1');
+ calc.appendNumber('.');
+ calc.appendNumber('2');
+ calc.appendNumber('3');
+ calc.appendNumber('0');
+ EXPECT_EQ(calc.getDisplayText(), "1.23");
+}