2024-01-05 12:04
BullseyeCoverage 9.6.4
calc/ CalcCore.cpp
1 // Calculator core logic 2 3 #include "CalcCore.h" 4 #include <assert.h> 5 #include <math.h> 6 #include <stdio.h> 7 #include <stdlib.h> 8 #include <string.h> 9 10 // Perform unit tests 11 void CalcCore::unitTest() 12 { 13 CalcCore core; 14 core.apply(); 15 assert(strcmp(core.display(), "0") == 0); 16 core.addNumber(1.2); 17 assert(strcmp(core.display(), "1.2") == 0); 18 core.apply(Operation::add); 19 core.addNumberChar('3'); 20 core.addNumberChar('.'); 21 core.addNumberChar('4'); 22 assert(strcmp(core.display(), "3.4") == 0); 23 core.apply(); 24 assert(strcmp(core.display(), "4.6") == 0); 25 core.apply(Operation::divide); 26 core.addNumber(0); 27 core.apply(); 28 assert(strcmp(core.display(), "divide by zero") == 0); 29 core.clear(); 30 core.addNumber(1); 31 core.apply(Operation::add); 32 core.addNumber(9); 33 core.apply(Operation::sqrt); 34 assert(strcmp(core.display(), "3") == 0); 35 core.apply(); 36 assert(strcmp(core.display(), "4") == 0); 37 } 38 39 // Enter the next character of a number 40 void CalcCore::addNumberChar(char c) 41 { 42 strncat_s(m_input, sizeof(m_input), &c, 1); 43 m_displayOperand = strtod(m_input, nullptr); 44 } 45 46 // Apply any pending operation 47 void CalcCore::apply() 48 { 49 if (m_operation != Operation::none) { 50 compute(); 51 } 52 m_enteredOperand = 0; 53 m_input[0] = 0; 54 } 55 56 // Apply any pending operation and prepare for another operation 57 void CalcCore::apply(Operation operation) 58 { 59 switch (operation) { 60 case Operation::negate: 61 m_displayOperand = -m_displayOperand; 62 break; 63 case Operation::pow2: 64 m_displayOperand *= m_displayOperand; 65 break; 66 case Operation::sqrt: 67 m_displayOperand = sqrt(m_displayOperand); 68 break; 69 default: 70 if (m_operation != Operation::none) { 71 compute(); 72 } 73 m_enteredOperand = m_displayOperand; 74 m_operation = operation; 75 break; 76 } 77 m_input[0] = 0; 78 } 79 80 void CalcCore::clear() 81 { 82 m_input[0] = 0; 83 m_displayOperand = 0.0; 84 m_enteredOperand = 0.0; 85 m_error = nullptr; 86 m_operation = Operation::none; 87 } 88 89 // Compute the pending operation 90 void CalcCore::compute() 91 { 92 switch (m_operation) { 93 case Operation::add: 94 m_displayOperand = m_enteredOperand + m_displayOperand; 95 break; 96 case Operation::subtract: 97 m_displayOperand = m_enteredOperand - m_displayOperand; 98 break; 99 case Operation::multiply: 100 m_displayOperand = m_enteredOperand * m_displayOperand; 101 break; 102 case Operation::divide: 103 if (m_displayOperand == 0) { 104 m_error = "divide by zero"; 105 } else { 106 m_displayOperand = m_enteredOperand / m_displayOperand; 107 } 108 break; 109 default: 110 m_error = "unknown operation"; 111 break; 112 } 113 } 114 115 // Get the display output 116 const char* CalcCore::display() const 117 { 118 const char* s = m_error; 119 if (m_error == nullptr) { 120 snprintf(m_output, sizeof(m_output), "%g", m_displayOperand); 121 s = m_output; 122 } 123 return s; 124 }