1

How do you handle the following scenario without null?

You have this problem (In Java):

BigDecimal sales = ...;
BigDecimal cost = ...;
BigDecimal profit = sales.subtract(cost);
// Profit Margin = profit / sales
BigDecimal profitMargin = profit.divide(sales, 20, RoundingMode.HALF_UP);

Because sales is sometimes zero, we turn the last line into:

BigDecimal profitMargin = sales.compareTo(BigDecimal.ZERO) == 0 ? null : profit.divide(sales, 20, RoundingMode.HALF_UP);

In which case if profitMargin == null, then we know what that means. If you make profitMargin = 0, that isn't really correct, nor is infinity a good value either. It seems best that it would remain undefined. Yet, it is an "unexploded bomb." So, what's the best way to handle this?

This questions as originally asked on Stack Overflow, and also referred me to the question Are null references really a bad thing?

ryvantage
  • 119

4 Answers4

8

If sales are zero, profit margin is zero.

Zero is a perfectly good result to substitute for the undefined result of a divide by zero calculation in many cases, and it avoids the use of null unless you specifically want to know about the zero sales case.

Robert Harvey
  • 200,592
7

Don't ask Us! We're not the ones making business decisions based on the output of your calculations!

Having said that, developers need to know how to approach these situations. In my experience, dilemmas like this fall into two broad scenarios:

  1. This happens relatively often and business users will see output based on $0.00 sales on a regular basis.

  2. This is a corner case that happens extremely rarely. It is so infrequent that business users have difficulty remembering the "last time" it happened. When it does happen, its not a business crisis.

For scenario #1, I would go to the business users and ask them what profit margin % they want to see for $0.00 sales.

For scenario #2, this probably isn't worth wasting the time of business users to find out what they want to see. I would set it to something that is least likely to give a false impression, probably 0%. In my opinion using a number like 20% would give the false impression that money is being made. Don't make a decision on your own unless you are familiar with the users and business. When in doubt, consult the business users.

poke
  • 560
2

My question is: how do you handle the following scenario without null?

The way you would handle it on a balance sheet (i.e. it's 0).

Maths is a bad example for nulls. Maths has worked without nulls for centuries, and there is never a balance sheet or a general ledger or a kid's maths homework book that says "null".

Programming had the problem of what to assign to a variable for which memory was not yet allocated, and that's where null was born. Perhaps you need to find another example for null (and you'll find many), but definitely not maths :-)

Omer Iqbal
  • 3,264
1

@Robert answer requires that you can use a profit margin of 0 if sales are 0, or have the ability at later times to access sales to test if they are 0 before using profit margin. If this is the case, then his answer is acceptable.

If however you need to know if the profit margin is 'NaN' at some future processing stage, another approach would be to extend BigDecimal so the fact that sales was 0 when trying to calculate it is preserved.

It would be my preferred approach to extend BigDecimal and create a new class for Profit Margin regardless, as the improved type correctness makes programs easier to understand and maintain.

mattnz
  • 21,490