How to Execute Multiplications And/Or Divisions in the Right Order

How to execute multiplications and/or divisions in the right order?

If you only have the four operations +, -, x, and ÷, you can do this by keeping track of a pendingOperand and pendingOperation whenever you encounter a + or -.

Then compute the pending operation when you encounter another + or -, or at the end of the calculation. Note that + or - computes the pending operation, but then immediately starts a new one.

I have modified your function to take the stringNumbers, operators, and initial values as input so that it could be tested independently in a Playground.

func calculateTotal(stringNumbers: [String], operators: [String], initial: Double) -> Double {

func performPendingOperation(operand: Double, operation: String, total: Double) -> Double {
switch operation {
case "+":
return operand + total
case "-":
return operand - total
default:
return total
}
}

var total = initial
var pendingOperand = 0.0
var pendingOperation = ""

for (i, stringNumber) in stringNumbers.enumerated() {
if let number = Double(stringNumber) {
switch operators[i] {
case "+":
total = performPendingOperation(operand: pendingOperand, operation: pendingOperation, total: total)
pendingOperand = total
pendingOperation = "+"
total = number
case "-":
total = performPendingOperation(operand: pendingOperand, operation: pendingOperation, total: total)
pendingOperand = total
pendingOperation = "-"
total = number
case "÷":
total /= number
case "×":
total *= number
default:
break
}
}
}

// Perform final pending operation if needed
total = performPendingOperation(operand: pendingOperand, operation: pendingOperation, total: total)

// clear()
return total
}

Tests:

// 4 + 3    
calculateTotal(stringNumbers: ["3"], operators: ["+"], initial: 4)
7
// 4 × 3
calculateTotal(stringNumbers: ["3"], operators: ["×"], initial: 4)
12
// 2 + 2 × 4
calculateTotal(stringNumbers: ["2", "4"], operators: ["+", "×"], initial: 2)
10
// 2 × 2 + 4
calculateTotal(stringNumbers: ["2", "4"], operators: ["×", "+"], initial: 2)
8
// 17 - 2 × 3 + 10 + 7 ÷ 7
calculateTotal(stringNumbers: ["2", "3", "10", "7", "7"], operators: ["-", "×", "+", "+", "÷"], initial: 17)
22

How can I preserve the order of multiplications and divisions?

Actually:

You (and the others) are misunderstanding what is being said. There is no problem here.

They're saying if you have f(x) + g(y), there is no guarantee that f(x) is evaluated before g(y) (or vice-versa).

But if you have

milliVolts * 32767 * 32 / 1000 * 1024 / ticks * 2

it is automatically interpreted as

(((((milliVolts * 32767) * 32) / 1000) * 1024) / ticks) * 2

which means evaluating the left- and right-hand sides of any operator out of order will not result in any problem, since all the expressions to the right-hand side of an operator are either variables or numbers, in either case of which the evaluation of the right-hand side is a no-op (no side-effects, contrary to a function call).

Thus there is nothing to be worried about.

C++ order of operation during multiplication

What's happening here is the difference between integer division and floating-point divison. Multiplication and division are interpreted left to right. In the first case, the 4/3 is read first. When you write 4/3, the compiler interprets that as an integer division, which would return 1. However, in the second case, the M_PI*4 makes the current value into a double, so when you divide by 3 next, the program performs a floating-point division, giving you the correct answer.

How can I multiply and divide using only bit shifting and adding?

To multiply in terms of adding and shifting you want to decompose one of the numbers by powers of two, like so:

21 * 5 = 10101_2 * 101_2             (Initial step)
= 10101_2 * (1 * 2^2 + 0 * 2^1 + 1 * 2^0)
= 10101_2 * 2^2 + 10101_2 * 2^0
= 10101_2 << 2 + 10101_2 << 0 (Decomposed)
= 10101_2 * 4 + 10101_2 * 1
= 10101_2 * 5
= 21 * 5 (Same as initial expression)

(_2 means base 2)

As you can see, multiplication can be decomposed into adding and shifting and back again. This is also why multiplication takes longer than bit shifts or adding - it's O(n^2) rather than O(n) in the number of bits. Real computer systems (as opposed to theoretical computer systems) have a finite number of bits, so multiplication takes a constant multiple of time compared to addition and shifting. If I recall correctly, modern processors, if pipelined properly, can do multiplication just about as fast as addition, by messing with the utilization of the ALUs (arithmetic units) in the processor.

How is division before multiplication in Javascript?

See this fiddle: https://www.w3schools.com/code/tryit.asp?filename=FRB0CCQOKZT2

the code is evaluated in this order:

  • Parentheses
  • Multiply and Divide
  • Addition and Subtraction

If you have Multiple and Divide in the same equation then it evaluates the first one it encounters. you can override this by using parentheses.

Is multiplication and division using shift operators in C actually faster?

Short answer: Not likely.

Long answer:
Your compiler has an optimizer in it that knows how to multiply as quickly as your target processor architecture is capable. Your best bet is to tell the compiler your intent clearly (i.e. i*2 rather than i << 1) and let it decide what the fastest assembly/machine code sequence is. It's even possible that the processor itself has implemented the multiply instruction as a sequence of shifts & adds in microcode.

Bottom line--don't spend a lot of time worrying about this. If you mean to shift, shift. If you mean to multiply, multiply. Do what is semantically clearest--your coworkers will thank you later. Or, more likely, curse you later if you do otherwise.



Related Topics



Leave a reply



Submit