- Feature Articles
- CodeSOD
- Error'd
- Forums
-
Other Articles
- Random Article
- Other Series
- Alex's Soapbox
- Announcements
- Best of…
- Best of Email
- Best of the Sidebar
- Bring Your Own Code
- Coded Smorgasbord
- Mandatory Fun Day
- Off Topic
- Representative Line
- News Roundup
- Editor's Soapbox
- Software on the Rocks
- Souvenir Potpourri
- Sponsor Post
- Tales from the Interview
- The Daily WTF: Live
- Virtudyne
Admin
not sure if you are trolling or just stupid.
Unless you have a RDBMS which runs java code, your previous comment was completely irrelevent (yes, we are discussing java).
Your talk of invoicing customers suggests that you are still in the fantasy world where money and cash are the same thing.
Looking at NASDAQ right now, I can see that Intel shares are going for $19.8559, you know why that is 4dp? because even small variations actually matter. If you start writing systems which calculate fair price to 2dp only, you are going to bankrupt your company pretty damn quickly. If you don't think that potentially losing hundreds of millions of dollars is a big deal, that is your choice - but most people would say you are wrong.
Admin
Shockingly enough, it is possible even in java to represent money without using floating point math. The point of the MONEY datatype in an RDBMS is to establish that money uses fixed point decimals.
"$19.8559, you know why that is 4dp?" Because MONEY in SQL Server goes out to 4 decimal points? Just kidding, but you apparently didn't read any of my comments about the MONEY data type. In Informix it can go to 16 decimal points or something ridiculous. But it will be FIXED point. This is trivial even using integers. First convert everything to pennies. Then, do you care about more than to the penny? If so multiply by 10 for each extra precision. Then do your math. Then convert back into pennies. You will deal with 20 + 25 instead of 0.1999998999 + 0.249999997999, and your results will be more accurate while being no less precise. I mean literally more accurate. There are times with floating points where two things add together and both are sufficiently off that the result is an entire penny different than what it should be. So use fixed point decimals or int or a money class or something to avoid that.
"If you don't think that potentially losing hundreds of millions of dollars is a big deal, that is your choice - but most people would say you are wrong." Yes... that's my point exactly. I only mentioned invoicing customers because I've written several systems like that, and you really notice off by a penny errors there quickly. You notice it quickly on contract entry screens too that you cannot sanely represent a per transaction price as 3.478282828282828282828, or a 10% discount as 1.333333333333, it needs to be a fixed point value that you can simply multiply by number of transactions to find a total.
Admin
public static bool isSafelyEqual(Object obj1, Object obj2) { try { return obj1.equals(obj2); catch (Exception e) { return obj1 == obj2; } }
Just in case obj1's equals is missing a null-check, or perhaps an instanceof.
Admin
Java Date is a moment in time, up to the millisecond. If you want to represent a less formal concept, like an expected arrival date for a shipment, and are working with different timezones, using Java's Date class to represent that information will lead to pain and suffering, as you can get bitten by daylight savings, timezone representations, and all kinds of other things that, conceptually, we'd typically not worry about.
Admin
In Java, best practices for most industries involving money include working with BigDecimal for currencies. It's nowhere near as fast as working on basic types, but it is a far better representation when your main concern is accuracy. Then, you have rounding functions at the appropriate places as dictated by business rules.
This even works for, say, a POS register: Taxes, discounts and all that can be then rounded sale-wide, with the rounding being applied to a single penny in a single item, instead of having to round per item, which in case of multiple discounts and a tax or three, could lead to very different results if you buy, say, an item with a $100 base price over buying 100 $1 items.
Admin
I don't think this is at all sane. Let's say you accumulate 3 chunks of .1 cent, from a state, city, and gift tax, and then at the end of the sale transaction you round the total up 1 full cent higher. What do you do with that penny? Which tax item do you apply it to? Do you send it to the city? If so the state will be mad. Do you send it to the state? If so the city will be mad. You cannot split it, so you have to leave one of them out. Do you pocket it a la Office Space? Not to mention that you are describing a POS which will print out a series of tax items where if the customer checks the math on one of the tax items they will get a different number than the one you show. So in addition to angering either the city or the state, you are also going to anger your customer.
Items are sold in multiples of pennies only. Taxes are collected in multiples of pennies only. I am seriously surprised that either of these statements is controversial.
Admin
In C, assigning a null pointer constant (it need not be a literal character "0") to a pointer-type variable sets that variable to the null pointer representation. Changing that would break nearly all existing C code, so no, it hasn't changed.
However, it has nothing whatsoever to do with how the OS treats addresses, as far as the C language (ie, the standard) is concerned. The C language is described in terms of implementations of a virtual machine. In most C implementations, C pointers happen to be machine addresses (and the common OSes for those machines typically also deal in machine addresses). But it's not the OS that determines a C implementation's null pointer representation.
You're welcome to inspect the representation of pointer objects by treating them as arrays of unsigned char, just as you can with any other object in C. Of course the results are implementation-dependent. And again the OS has nothing to do with it.
The abstract machine defined by the C standard does neither: when a pointer-type object is evaluated in a Boolean context, it evaluates as 0 (false) if null, and 1 (true) if not null. Thus in:
int obj, result, *a = 0, *b = &obj; result = (!!a) + (!!b);
result will have the value 1.
By the way, some posters here seem to have problems understanding the difference between NULL, null pointers, and a null pointer constant in C. A null pointer constant is a constant integer expression that evaluates to 0, or such an expression cast to a pointer type. NULL is a macro, defined by the standard headers stdlib.h and stdio.h, which expands to a null pointer constant; the standard requires that it be a bare constant integer expression, or one cast to void*. There's no such thing, in C, as a "NULL pointer".
Admin
x ====== y // always false; assumes a metaphysics where two entities with all the same attributes are nonetheless distinct
Admin
x ======= y // you have reached enlightenment
Admin
confirmed - you weren't trolling..
Admin
The code probably was clearly based on:
http://www.javapractices.com/topic/TopicAction.do?Id=17
... which is based on Joshua Bloch's must-read book, "Effective Java".
Only the bad/broken/redundant additions to the class are a WTF.
Admin
Reminds me of the day a colleage at work explained to me that in PHP, comparison using === was "better" than plain ol' ==.
No mention of the concept of identity, just "better".
Captcha: valetudo: a TODO big as a whale?
Admin
TRWTF is that
isEqual(null, null) returns true isNotEqual(null, null) returns true
that is,
isEqual(null, null) == isNotEqual(null, null) == notEqual(null, null)
Admin
Why for the love of god would anyone go out of their way to use the java.util.Calendar class in their code... especially when the Date class will actually do what they want.
Admin
You obviously do not in the least understand the problem.
As others have already done all the work to explain this in simple terms, here is a link:
http://www.javaranch.com/journal/2003/07/MoneyInJava.html
Admin
On the contrary, I do understand the problem very well. I am familiar with binary approximations of decimal numbers. This was the cause of a very frustrating bug I had to solve several years ago (unrelated to money). BigDecimal is a good solution. You are the first to suggest it.
Choosing an integer and multiplying by a factor of 10 is a horrible suggestion, hence my disagreement with others.
Admin
The MONEY type I mentioned in the DB is a fixed point decimal. I don't do Java, didn't know there was a direct equivalent. But however you represent it, accumulating fractional parts of pennies through many sub-items in a transaction and then rounding at the end is a horrible idea, and one that only occurs to people because they don't constrain the possible values for a line item to a real amount, which wouldn't even occur to you if you were doing math with ints. Was it you who mentioned a stock being $84.3817? That of course is only an approximation. You cannot by one stock for $84.3817. You will pay $84.38 or $84.39. You could buy 100 stock for $8438.17, giving an average price per stock of $84.3817, but in that case all you really have is a definite price for 100 stocks, and an equation that describes an approximation of the price of one stock.
Now, is int crazy for money? No, not at all. What does http://www.javapractices.com/topic/TopicAction.do?Id=13 say?
"Representing money : * use BigDecimal, int, or long (BigDecimal is the recommended default) * the int and long forms represent pennies (or the equivalent, of course) * BigDecimal is a little more inconvenient to use, but has built-in rounding modes * double or float are not recommended, since they always carry small rounding differences"
The especially interesting comment to me is "the ROUND_HALF_EVEN style of rounding introduces the least bias. It is also called bankers' rounding, or round-to-even. " Which is hilarious, because I had some asp code that i struggled to get to be in synch with some java code, because vbscript does that automatically, and the java code (presumably poorly written) did not, it always rounded .885 up when it could go either way.
Admin
In C:
Admin
It reminds me of the behaviour of '==' operator in javascript ...