Definition
- Signum function – maps a number to +1 (positive), -1 (negative), or 0 (zero).
- Two decisions – first test N > 0 (return 1), else test N < 0 (return -1), final else is exactly zero (return 0).
- BigDecimal.signum() – returns the sign as an
int; uses numeric value, not scale. - Avoids equals –
BigDecimal.ZERO.equals(amount)is scale-sensitive;signum()is not. - Exact arithmetic – a net movement computed in BigDecimal gives a clean zero, not a tiny float residual.
National Bank of India looks at the net movement on Rajesh's account for the day and labels it +1 for a net credit, -1 for a net debit, and 0 for no change, so the dashboard shows an up arrow, a down arrow, or a flat line.
Understanding the Concepts
What is the problem?
Read a number N, print 1 if positive, -1 if negative, 0 if zero. For input -8, output -1.
How do you implement it?
package com.bank.service;
import java.math.BigDecimal;
public class MovementClassifier {
public static int sign(BigDecimal amount) {
return amount.signum();
}
public static int signExplicit(BigDecimal amount) {
if (amount.compareTo(BigDecimal.ZERO) > 0) return 1;
if (amount.compareTo(BigDecimal.ZERO) < 0) return -1;
return 0;
}
public static void main(String[] args) {
BigDecimal credit = new BigDecimal("5000.00");
BigDecimal debit = new BigDecimal("-8000.00");
BigDecimal zero = new BigDecimal("0.00");
System.out.println("Credit sign: " + sign(credit));
System.out.println("Debit sign: " + sign(debit));
System.out.println("Zero sign: " + sign(zero));
}
}
Credit sign: 1
Debit sign: -1
Zero sign: 0
Why use signum() instead of compareTo against zero?
BigDecimal's signum() method is a single call that returns the sign directly. It is cleaner and less error-prone than writing two compareTo conditions. Both approaches produce the same result.
Why not use equals to check for zero?
BigDecimal a = new BigDecimal("0.0"); // scale 1
BigDecimal b = new BigDecimal("0.00"); // scale 2
System.out.println(a.equals(b)); // false! (different scale)
System.out.println(a.signum()); // 0
System.out.println(b.signum()); // 0
equals is scale-sensitive; signum() looks only at the numeric value.
Why does floating-point cause problems here?
A net movement computed from many double additions can land on a tiny nonzero value like 0.0000000001 instead of a clean zero, flipping the sign indicator wrongly. BigDecimal avoids this because its arithmetic is exact.
// Wrong: floating-point drift
double net = 1000.0 - 999.9 - 0.1;
System.out.println(net); // -1.1102230246251565E-16 (not zero!)
System.out.println(net > 0); // false
System.out.println(net < 0); // true (WRONG: should be zero)
// Correct: BigDecimal is exact
BigDecimal bdNet = new BigDecimal("1000.0")
.subtract(new BigDecimal("999.9"))
.subtract(new BigDecimal("0.1"));
System.out.println(bdNet.signum()); // 0 (correct)
What are edge cases?
- Exactly zero: signum returns 0.
- Very small positive: signum returns 1 (e.g., 0.01).
- Very small negative: signum returns -1 (e.g., -0.01).
What are common mistakes?
// Wrong: using equals to compare with zero
if (amount.equals(BigDecimal.ZERO)) { } // scale-sensitive
// Correct: using signum or compareTo
if (amount.signum() == 0) { } // correct
What should a senior engineer know?
Sign classification is only as trustworthy as the arithmetic behind it. Computing the net movement in BigDecimal and reading its sign with signum() is what makes the dashboard indicator reliable. For integers, Integer.signum(n) provides the same function.
What are common interview follow-up questions?
- What is Math.signum and how does it differ from BigDecimal.signum?
- How would you implement signum without using any if statements? (Use
(n >> 31) | (-n >>> 31)for int.) - What is the result of BigDecimal.ZERO.signum()?
Visual Overview
┌─────────┐
│ Start │
└────┬────┘
▼
┌──────────┐
│ Read N │
└────┬─────┘
▼
┌────────────┐
│ N > 0 ? │──Yes──→ Print 1
└────┬───────┘ │
│ No │
▼ │
┌────────────┐ │
│ N < 0 ? │──Yes──→ Print -1
└────┬───────┘ │
│ No │
▼ │
Print 0 │
│ │
└────────┬───────────────┘
▼
┌─────┐
│ End │
└─────┘
Key Takeaway
The signum function maps a number to its sign: +1 for positive, -1 for negative, 0 for zero. The flowchart uses two nested decisions to classify the input. For money, BigDecimal's signum() method returns the sign directly as an int, cleanly and without scale sensitivity.
The important related point is that the net movement itself should be computed in BigDecimal, not double. A floating-point sum of many debits and credits can land on a tiny nonzero residual and flip a flat day into a false movement. BigDecimal arithmetic is exact, so signum() on an exactly computed value gives a correct and reliable sign.
In a banking project at National Bank of India, a dashboard showed whether Rajesh's account moved up, down, or stayed flat for the day. The MovementClassifier took the net BigDecimal movement and returned its signum. A net debit of eight thousand classified as -1 and drew a down arrow; a genuinely no-change day classified as 0 and drew a flat line.
Remember one sentence: compute the value in BigDecimal and read its sign with signum(), because floating-point drift can flip the sign of a value that should be zero.
---