You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The calculator component processes mathematical operations sequentially from left to right instead of following the standard mathematical order of operations (PEMDAS/BODMAS). This results in incorrect calculations when multiple operators with different precedence levels are used in a single expression.
Environment
File:src/pages/activities/Calculator.js
Component Type: React Class Component
Lines of Interest: 17-74 (calculation logic in screenUpdate method)
Browser: All browsers (logic error, not browser-specific)
Version: Current main branch
Current Behavior
The calculator evaluates expressions sequentially from left to right, processing each operator as it is encountered regardless of operator precedence. This violates fundamental mathematical principles and produces incorrect results.
Initial: arr = [2, 3, 4], op = ['+', 'x']
Step 1: Identify highest precedence operators (× and /)
- Found 'x' at index 1
Step 2: Process multiplication first
- r = arr[1] * arr[2] = 3 * 4 = 12
- arr = [2, 12]
- op = ['+']
Step 3: Process addition
- r = arr[0] + arr[1] = 2 + 12 = 14
- arr = [14]
Result: 14 (CORRECT)
Proposed Solution
Approach 1: Two-Pass Algorithm (Recommended)
Implement operator precedence by processing high-precedence operators first:
// First pass: Process multiplication and division (left to right)for(letb=0;b<op.length;b++){if(op[b]==='/'||op[b]==='x'){if(op[b]==='/'){r=arr[b]/arr[b+1];}else{r=arr[b]*arr[b+1];}// Replace the two operands with the resultarr.splice(b,2,r);// Remove the operatorop.splice(b,1);// Adjust index since we removed an elementb--;}}// Second pass: Process addition and subtraction (left to right)for(letb=0;b<op.length;b++){if(op[b]==='-'){r=arr[b]-arr[b+1];}elseif(op[b]==='+'){r=arr[b]+arr[b+1];}arr.splice(b,2,r);op.splice(b,1);b--;}
Approach 2: Shunting Yard Algorithm
For a more robust solution that can handle parentheses and future operators:
Convert infix notation to postfix (Reverse Polish Notation) using Shunting Yard algorithm
Evaluate postfix expression using a stack
This approach is more scalable if parentheses or additional operators are added later.
Approach 3: Expression Parser
Use a recursive descent parser or expression tree to properly handle operator precedence. This is the most flexible approach for future enhancements.
Impact Assessment
Severity: High
User Impact:
All users performing multi-operation calculations receive incorrect results
Undermines trust in the calculator functionality
May lead to real-world calculation errors if users rely on the tool
Functional Impact:
Core functionality broken
Violates mathematical standards
Produces incorrect results for approximately 50% of multi-operation expressions
Frequency:
Occurs every time multiple operators with different precedence are used
Affects any expression mixing addition/subtraction with multiplication/division
Affected Use Cases
Basic arithmetic with mixed operations
Educational use (students learning order of operations would get wrong answers)
Quick calculations for daily tasks
Any mathematical expression with more than one operator type
Testing Requirements
Unit Tests Required
describe('Calculator Order of Operations',()=>{test('should multiply before adding: 2 + 3 × 4',()=>{expect(calculate('2+3x4')).toBe(14);});test('should divide before subtracting: 10 - 8 / 2',()=>{expect(calculate('10-8/2')).toBe(6);});test('should process left to right for same precedence: 10 - 5 - 2',()=>{expect(calculate('10-5-2')).toBe(3);});test('should handle multiple operations: 2 + 3 × 4 - 5',()=>{expect(calculate('2+3x4-5')).toBe(9);});test('should handle division and multiplication: 12 / 3 × 2',()=>{expect(calculate('12/3x2')).toBe(8);});test('should handle complex expressions: 5 + 2 × 3 - 4 / 2',()=>{expect(calculate('5+2x3-4/2')).toBe(9);});});
Additional Considerations
Edge Cases to Handle
Negative numbers:-5 + 3 × 2
Decimal operations:2.5 + 3.5 × 2
Division by zero:5 / 0 (currently not handled)
Very long expressions: Performance considerations
Consecutive operators: Should be prevented or handled
Future Enhancements
Once order of operations is fixed, consider:
Adding parentheses support: (2 + 3) × 4
Adding exponent operator: 2 ^ 3
Adding percentage operator: 100 + 10%
Adding memory functions: M+, M-, MR, MC
Scientific calculator mode with advanced functions
Related Issues
Issue Add footer #3: Console.log statements in Calculator (should be removed)
The calculator component processes mathematical operations sequentially from left to right instead of following the standard mathematical order of operations (PEMDAS/BODMAS). This results in incorrect calculations when multiple operators with different precedence levels are used in a single expression.
Environment
src/pages/activities/Calculator.jsscreenUpdatemethod)Current Behavior
The calculator evaluates expressions sequentially from left to right, processing each operator as it is encountered regardless of operator precedence. This violates fundamental mathematical principles and produces incorrect results.
Example 1: Multiplication Before Addition
Input:
2 + 3 × 42014(2 + 3) × 4 = 5 × 4 = 202 + (3 × 4) = 2 + 12 = 14Example 2: Division Before Subtraction
Input:
10 - 8 / 216(10 - 8) / 2 = 2 / 2 = 110 - (8 / 2) = 10 - 4 = 6Example 3: Multiple Operations
Input:
2 + 3 × 4 - 5159((2 + 3) × 4) - 5 = (5 × 4) - 5 = 20 - 5 = 152 + (3 × 4) - 5 = 2 + 12 - 5 = 9Expected Behavior
The calculator should follow the standard mathematical order of operations (PEMDAS/BODMAS):
When evaluating
2 + 3 × 4:3 × 4 = 122 + 12 = 1414Steps to Reproduce
Navigate to the Calculator activity:
http://localhost:3000/activities/calculator(development)https://acm-fun.vercel.app/activities/calculator(production)Enter the following expression:
2+3x(multiply)4=Observe the result displays
20instead of14Try additional test cases:
10 - 8 / 2→ Shows1, should show65 × 2 + 3→ Shows13, should show13(correct by coincidence)5 + 2 × 3→ Shows21, should show1112 / 3 - 1→ Shows3, should show3(correct by coincidence)12 - 3 / 3→ Shows3, should show11Technical Analysis
Root Cause
The issue is located in the
screenUpdatemethod, specifically in the calculation logic (lines 17-74). The current implementation:arr) and operators (op)Problematic Code Section (lines 56-62):
This loop processes operations in the order they appear in the expression, not by their mathematical precedence.
Example Execution Trace
For input
2 + 3 × 4:Current Implementation:
Expected Implementation:
Proposed Solution
Approach 1: Two-Pass Algorithm (Recommended)
Implement operator precedence by processing high-precedence operators first:
Approach 2: Shunting Yard Algorithm
For a more robust solution that can handle parentheses and future operators:
This approach is more scalable if parentheses or additional operators are added later.
Approach 3: Expression Parser
Use a recursive descent parser or expression tree to properly handle operator precedence. This is the most flexible approach for future enhancements.
Impact Assessment
Severity: High
User Impact:
Functional Impact:
Frequency:
Affected Use Cases
Testing Requirements
Unit Tests Required
Additional Considerations
Edge Cases to Handle
-5 + 3 × 22.5 + 3.5 × 25 / 0(currently not handled)Future Enhancements
Once order of operations is fixed, consider:
(2 + 3) × 42 ^ 3100 + 10%M+,M-,MR,MCRelated Issues
References
Mathematical Standards
Implementation Resources
Similar Implementations
Acceptance Criteria
Implementation Checklist
Estimated Effort
Notes for Implementer