Definition
- Accumulator – a variable
suminitialized to 0, the additive identity. - Counter – runs from 1 to 10; each iteration reads a value and adds it to sum.
- BigDecimal for money –
sum = sum.add(x)keeps the total exact to the paisa. - O(1) space – only the sum and counter are kept in memory, regardless of count.
- Validation – each input should be checked for null and potentially for negativity.
National Bank of India tallies the ten cash deposits made at a branch counter over a shift. The teller starts a running total at zero and adds each deposit as it is counted. For deposits 1 through 10 thousand the total is 55 thousand.
Understanding the Concepts
What is the algorithm?
Initialize sum to 0 and counter to 1. Loop while counter <= 10: read a number x, add it to sum, increment counter. After the loop, print sum.
package com.bank.service;
import java.math.BigDecimal;
import java.math.RoundingMode;
public class TillReconciler {
public static BigDecimal sumDeposits(BigDecimal[] deposits) {
BigDecimal sum = BigDecimal.ZERO;
for (BigDecimal d : deposits) {
if (d == null) throw new IllegalArgumentException("Null deposit");
sum = sum.add(d);
}
return sum.setScale(2, RoundingMode.HALF_EVEN);
}
public static void main(String[] args) {
BigDecimal[] deposits = new BigDecimal[10];
for (int i = 0; i < 10; i++) {
deposits[i] = new BigDecimal((i + 1) * 1000 + ".00");
}
System.out.println("Total: " + sumDeposits(deposits));
}
}
Total: 55000.00
Why seed at 0?
Zero is the additive identity: adding 0 to any value changes nothing, so it is the correct neutral starting point. If you seeded at 1 by mistake, every total would be off by 1.
// Wrong
int sum = 1; // off by 1!
for (int x : values) sum += x;
// Correct
int sum = 0;
for (int x : values) sum += x;
How does this compare to a product loop?
| Feature | Sum loop | Product loop | |---|---|---| | Identity | 0 | 1 | | Operation | + | * | | Danger | seeding at 1 → off by 1 | seeding at 0 → all zeros | | Banking use | total deposits | compounding factor |
What about streaming input?
The accumulation uses only one running variable regardless of count. Even if you read a million values, only the sum is kept in memory. This is ideal for streaming input where you cannot hold everything at once.
How does the Stream-based approach work?
Java Streams provide a reduce operation that replaces the explicit loop. The identity element is BigDecimal.ZERO and the accumulator is BigDecimal::add. This is functionally identical to the loop.
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
List<BigDecimal> deposits = Arrays.asList(
new BigDecimal("1000.00"),
new BigDecimal("2000.00"),
new BigDecimal("3000.00")
);
BigDecimal total = deposits.stream()
.reduce(BigDecimal.ZERO, BigDecimal::add);
System.out.println("Stream total: " + total); // 6000.00
What are edge cases?
- All zeros: sum is 0.
- Mix of positive and negative: sum reflects the net.
- Very large values: BigDecimal handles them without overflow.
- Empty input (zero values): sum stays at 0, the identity.
What are common mistakes?
// Wrong: using double for money
double sum = 0;
for (double d : deposits) sum += d; // drift!
// Correct: BigDecimal
BigDecimal sum = BigDecimal.ZERO;
for (BigDecimal d : deposits) sum = sum.add(d);
Why is double dangerous for money?
Floating-point addition accumulates rounding errors over many operations. For example, adding 0.10 ten times in double gives 0.9999999999999999, not 1.00. In a bank till handling thousands of transactions per shift, this drift becomes material. BigDecimal performs exact decimal arithmetic.
double drift = 0.0;
for (int i = 0; i < 10; i++) drift += 0.10;
System.out.println(drift); // 0.9999999999999999
System.out.println(drift == 1.0); // false!
What should a senior engineer know?
For a real bank till reconciliation, each deposit is validated as non-null and non-negative, and the final total is set to two decimal places with HALF_EVEN rounding. The sum must always be a BigDecimal for exactness. Parallel summation with streams uses stream().reduce(BigDecimal.ZERO, BigDecimal::add) for large datasets. At National Bank of India, the TillReconciler runs at the end of every shift and any mismatch with the physical cash triggers an audit.
What are common interview follow-up questions?
- How would you sum N numbers where N is not fixed?
- What is the difference between iterative and stream-based summation?
- How would you detect an overflow when summing primitive longs?
Visual Overview
sum = 0, i = 1
│
▼
┌───────────┐
│ i <= 10? │──No──→ Print sum → End
└────┬──────┘
│ Yes
▼
Read x
sum = sum + x
i = i + 1
└──→ back to i <= 10?
Key Takeaway
Summing ten numbers read one by one is an additive accumulation loop. The running total starts at zero, each of the ten values is added in turn, and after the last one the total is the sum. For deposits 1 through 10 thousand, the total is 55 thousand.
The seed value is zero because zero is the additive identity: adding it to the first value changes nothing and gives the correct start. Seeding at 1 would make every total off by 1. This is the mirror of the product loop, which seeds at 1.
For money, the accumulator must be a BigDecimal starting at BigDecimal.ZERO, with additions via the add method. Double would drift over many additions. The final total is set to two decimal places with HALF_EVEN rounding for consistent storage.
In a banking project at National Bank of India, this reconciled the ten cash deposits a teller took during a shift against the physical cash in the till. The TillReconciler seeded a BigDecimal total at zero, added each deposit, and fixed the result to two decimals.
Remember one sentence: a sum loop seeds at 0 because 0 is the additive identity, and for money that sum must be a BigDecimal.
---