BigDecimal and Java Posse #379, Roundup '11 - ReSTful AMF

95 views
Skip to first unread message

Joseph Darcy

unread,
Mar 13, 2012, 10:05:56 PM3/13/12
to java...@googlegroups.com
While listening to episode Java Posse #379, Roundup '11 - ReSTful AMF, some of the technical details of BigDecimal came up and I wanted to address some erroneous statements.

First, logically a BigDecimal is a tuple of an arbitrary precision unscaled integer value and a 32-bit integer exponent where the numerical value of the BigDecimal is equal to

unscaledValue * 10^exponent

The decimal-ness of BigDecimal comes from using 10 as an exponent and not from how unscaledValue is represented.  In particular, BigDecimal does not use a decimal digit-oriented representation internally; instead it uses a BigInteger.  For that reason, multiplies of BigDecimal values are comparatively faster than addition/subtraction because the decimal digit alignment shifts to line up corresponding digits positions in add/subtract are relatively expensive with a binary-based representation.

In addition, since JDK5 update 5, small unscaled values have been represented internally using a 64-bit long rather than a BigInteger, giving a considerable performance boost for such values, up to about 18 decimal digits of precision.

Casper Bang

unread,
Mar 14, 2012, 2:02:34 AM3/14/12
to java...@googlegroups.com
What's the prospect of getting native/literal decimal type support in the future? Regardless of the JDK runtime optimizations underneath, BigDecimal is clunky and error-prone* to work with, making Java look really bad. Seems like low-hanging frontend syntax-sugar fruit that would actually cater to a great number of active Java practitioners.

* It's a leaky abstraction that compareTo(..) ignores scale so in spite of being a numeric type, 0 != 0.0. BD's have go be constructed using Strings: BD's "add" does not actually add/mutate anything so it really should've been named "plus" etc.

/Casper

Joseph Darcy

unread,
Mar 14, 2012, 8:58:50 PM3/14/12
to java...@googlegroups.com
On Tue, Mar 13, 2012 at 11:02 PM, Casper Bang <caspe...@gmail.com> wrote:
What's the prospect of getting native/literal decimal type support in the future?

Certainly technically feasible, but not under consideration for the set of features being contemplated for JDK 8:
http://openjdk.java.net/jeps/0

 
Regardless of the JDK runtime optimizations underneath, BigDecimal is clunky and error-prone* to work with, making Java look really bad. Seems like low-hanging frontend syntax-sugar fruit that would actually cater to a great number of active Java practitioners.

* It's a leaky abstraction that compareTo(..) ignores scale so in spite of being a numeric type, 0 != 0.0.


Yes, that is the documented behavior of compareTo; however, note that such numbers are *not* .equals with each other.

 
BD's have go be constructed using Strings: BD's

No; there are BigDecimal constructors or factories that accept BigInteger, int, or long arguments for the unscaled value including:
http://docs.oracle.com/javase/7/docs/api/java/math/BigDecimal.html#BigDecimal(java.math.BigInteger,%20int)
http://docs.oracle.com/javase/7/docs/api/java/math/BigDecimal.html#valueOf(long,%20int)

 
"add" does not actually add/mutate anything so it really should've been named "plus" etc.

I see no connection between mutation and the name "add", likewise for "subtract" and "multiply". The name "setScale" however is certainly misleading.

-Joe
 

/Casper

On Wednesday, March 14, 2012 3:05:56 AM UTC+1, jddarcy wrote:
While listening to episode Java Posse #379, Roundup '11 - ReSTful AMF, some of the technical details of BigDecimal came up and I wanted to address some erroneous statements.

First, logically a BigDecimal is a tuple of an arbitrary precision unscaled integer value and a 32-bit integer exponent where the numerical value of the BigDecimal is equal to

unscaledValue * 10^exponent

The decimal-ness of BigDecimal comes from using 10 as an exponent and not from how unscaledValue is represented.  In particular, BigDecimal does not use a decimal digit-oriented representation internally; instead it uses a BigInteger.  For that reason, multiplies of BigDecimal values are comparatively faster than addition/subtraction because the decimal digit alignment shifts to line up corresponding digits positions in add/subtract are relatively expensive with a binary-based representation.

In addition, since JDK5 update 5, small unscaled values have been represented internally using a 64-bit long rather than a BigInteger, giving a considerable performance boost for such values, up to about 18 decimal digits of precision.

--
You received this message because you are subscribed to the Google Groups "The Java Posse" group.
To view this discussion on the web visit https://groups.google.com/d/msg/javaposse/-/Q4wo1DlNsJIJ.
To post to this group, send email to java...@googlegroups.com.
To unsubscribe from this group, send email to javaposse+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/javaposse?hl=en.

Casper Bang

unread,
Mar 15, 2012, 6:08:47 AM3/15/12
to java...@googlegroups.com
Certainly technically feasible, but not under consideration for the set of features being contemplated for JDK 8:
http://openjdk.java.net/jeps/0

Which is odd, considering C# (Java's main competitor) had it since its inception and given it's also on its way into C++ via ISO/IEC TR 24733.
 
Yes, that is the documented behavior of compareTo; however, note that such numbers are *not* .equals with each other.

True, but that does little in a common arithmetic algorithmic branching scenario.
 
No; there are BigDecimal constructors or factories that accept BigInteger, int, or long arguments for the unscaled value including:
http://docs.oracle.com/javase/7/docs/api/java/math/BigDecimal.html#BigDecimal(java.math.BigInteger,%20int)
http://docs.oracle.com/javase/7/docs/api/java/math/BigDecimal.html#valueOf(long,%20int)

Yes but that won't help constructing decimals, where the text for the BigDecimal(double) constructor goes "The results of this constructor can be somewhat unpredictable and its use is generally not recommended" which kind of leaves a cliffhanger with the developer.
 
I see no connection between mutation and the name "add", likewise for "subtract" and "multiply". The name "setScale" however is certainly misleading.

It might be a language/culture issue considering it's none less than Josh Bloch that's behind. However, here my rationale: Looking at the in the JDK sources, "add" is overloaded but most often used for the symmetric pair "add"/"remove" and mutating purposes (
java.util.List, java.security.Policy.java, java.lang.ThreadGroup.java, java.net.CookieStore.java etc.). On a BigDecimal, "add" is used as a non-mutating binary plus. Interestingly, the JDK compiler itself (com.sun.source.tree.Tree) and JSR 201 defines these arithmetic operations as plus and minus. To add to the confusion, BigDecimal actually *does* have unary and binary plus() methods, whose existence purpose seems to be that somebody thought negate() needed a symmetric inverse counterpart, which makes very little sense.

What a mess, it's hard to imagine Java is being used with large financial and scientific applications. Put a decimal into the type system, and all this nomenclature goes away.

Kevin Wright

unread,
Mar 15, 2012, 6:53:21 AM3/15/12
to java...@googlegroups.com
On 15 March 2012 00:58, Joseph Darcy <jdd...@gmail.com> wrote:
 
"add" does not actually add/mutate anything so it really should've been named "plus" etc.

I see no connection between mutation and the name "add", likewise for "subtract" and "multiply". The name "setScale" however is certainly misleading.


I think that most native English speakers *will* make a distinction between "x add y" and "x plus y" 

Consider how it sounds when not referring to numbers:

myFriends.add("Fred") vs. myFriends.plus("Fred")

The first form would normally be read as updating my friends to include Fred.  The second form would normally be read as the set comprising both my friends and Fred (who isn't necessarily my friend).

Ricky Clarkson

unread,
Mar 15, 2012, 7:08:33 AM3/15/12
to java...@googlegroups.com

I think that might be a difference between UK and US English. Specifically, I think Americans are more likely to pronounce + as add than as plus in 3 + 2.

--
You received this message because you are subscribed to the Google Groups "The Java Posse" group.

Jon Kiparsky

unread,
Mar 15, 2012, 7:12:25 AM3/15/12
to java...@googlegroups.com
I have literally never heard anyone pronounce 3 + 2 as "three add two". I've heard "minus" used as a verb (cue fingernails on chalkboard!) but this one is completely new to me.
And living in Boston, I talk to Americans almost every day.

Jon Kiparsky

unread,
Mar 15, 2012, 7:14:44 AM3/15/12
to java...@googlegroups.com
Staircase amendment to that last: I have heard something like "take some random number, add two, multiply by a constant, blah blah". That is, "add" used as a verb in a series of instructions. Is that maybe what you meant?

Kevin Wright

unread,
Mar 15, 2012, 7:29:12 AM3/15/12
to java...@googlegroups.com
"plus 2 to x", "minus 3 from y", etc. has got to sound wrong no matter what side of the Atlantic you hail from!
Kevin Wright
mail: kevin....@scalatechnology.com
gtalk / msn : kev.lee...@gmail.com
vibe / skype: kev.lee.wright
steam: kev_lee_wright

"My point today is that, if we wish to count lines of code, we should not regard them as "lines produced" but as "lines spent": the current conventional wisdom is so foolish as to book that count on the wrong side of the ledger" ~ Dijkstra

Russel Winder

unread,
Mar 15, 2012, 7:51:42 AM3/15/12
to java...@googlegroups.com
On Thu, 2012-03-15 at 11:29 +0000, Kevin Wright wrote:
> "plus 2 to x", "minus 3 from y", etc. has got to sound wrong no matter what
> side of the Atlantic you hail from!

Unless you program in COBOL.

--
Russel.
=============================================================================
Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel...@ekiga.net
41 Buckmaster Road m: +44 7770 465 077 xmpp: rus...@winder.org.uk
London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder

signature.asc

Casper Bang

unread,
Mar 15, 2012, 8:33:03 AM3/15/12
to java...@googlegroups.com
I think that most native English speakers *will* make a distinction between "x add y" and "x plus y" 

Consider how it sounds when not referring to numbers:

myFriends.add("Fred") vs. myFriends.plus("Fred")

The first form would normally be read as updating my friends to include Fred.  The second form would normally be read as the set comprising both my friends and Fred (who isn't necessarily my friend).

But we ARE dealing with a numeric type though and a domain revolving around very fundamental mathematical operations. If you were to ask an outsider to this debate what the inverse of "remove" is, they would surely answer "add", inferring a set-theory domain.

Scala doesn't seem to have a problem sticking to the conventional plus and minus, even if it obviously provides operator overloading to them as well:

Joseph Darcy

unread,
Mar 16, 2012, 12:54:35 AM3/16/12
to java...@googlegroups.com
On Thu, Mar 15, 2012 at 3:08 AM, Casper Bang <caspe...@gmail.com> wrote:
Certainly technically feasible, but not under consideration for the set of features being contemplated for JDK 8:
http://openjdk.java.net/jeps/0

Which is odd, considering C# (Java's main competitor) had it since its inception and given it's also on its way into C++ via ISO/IEC TR 24733.
 
Yes, that is the documented behavior of compareTo; however, note that such numbers are *not* .equals with each other.

True, but that does little in a common arithmetic algorithmic branching scenario.
 
No; there are BigDecimal constructors or factories that accept BigInteger, int, or long arguments for the unscaled value including:
http://docs.oracle.com/javase/7/docs/api/java/math/BigDecimal.html#BigDecimal(java.math.BigInteger,%20int)
http://docs.oracle.com/javase/7/docs/api/java/math/BigDecimal.html#valueOf(long,%20int)

Yes but that won't help constructing decimals, where the text for the BigDecimal(double) constructor goes "The results of this constructor can be somewhat unpredictable and its use is generally not recommended" which kind of leaves a cliffhanger with the developer.

If said developer reads the full javadoc of the constructor in question, the situation is not that opaque and even includes a helpful example:

Translates a double into a BigDecimal which is the exact decimal representation of the double's binary floating-point value. The scale of the returned BigDecimal is the smallest value such that (10scale × val) is an integer.

Notes:

  1. The results of this constructor can be somewhat unpredictable. One might assume that writing new BigDecimal(0.1) in Java creates a BigDecimal which is exactly equal to 0.1 (an unscaled value of 1, with a scale of 1), but it is actually equal to 0.1000000000000000055511151231257827021181583404541015625. This is because 0.1 cannot be represented exactly as a double (or, for that matter, as a binary fraction of any finite length). Thus, the value that is being passed in to the constructor is not exactly equal to 0.1, appearances notwithstanding.
  2. The String constructor, on the other hand, is perfectly predictable: writing new BigDecimal("0.1") creates a BigDecimal which is exactly equal to 0.1, as one would expect. Therefore, it is generally recommended that the String constructor be used in preference to this one.
  3. When a double must be used as a source for a BigDecimal, note that this constructor provides an exact conversion; it does not give the same result as converting the double to a String using the Double.toString(double) method and then using the BigDecimal(String) constructor. To get that result, use the static valueOf(double) method.
-Joe

Ricky Clarkson

unread,
Mar 16, 2012, 1:12:53 AM3/16/12
to java...@googlegroups.com
Deprecating the double constructor might help.  I'm not sure there's any non-pathological use case for it.

--
You received this message because you are subscribed to the Google Groups "The Java Posse" group.

Eric Jablow

unread,
Mar 16, 2012, 10:30:27 AM3/16/12
to The Java Posse


On Mar 15, 6:08 am, Casper Bang <casper.b...@gmail.com> wrote:

> What a mess, it's hard to imagine Java is being used with large financial
> and scientific applications. Put a decimal into the type system, and all
> this nomenclature goes away.

So, should Java add PICTURE subclasses of Number? Should it have
(BIN|DEC) (FIXED|FLOAT) types? It's been a long time since I took
my freshman PL/I class.

Eric

Kevin Wright

unread,
Mar 16, 2012, 10:54:43 AM3/16/12
to java...@googlegroups.com
What would the semantics be for adding two pictures?  xor, alpha blend, side-by-side, one above the other?

Casper Bang

unread,
Mar 18, 2012, 2:34:16 PM3/18/12
to java...@googlegroups.com


On Friday, March 16, 2012 3:30:27 PM UTC+1, Eric Jablow wrote:
So, should Java add PICTURE subclasses of Number? Should it have 
(BIN|DEC) (FIXED|FLOAT) types? It's been a long time since I took
my freshman PL/I class.

Since a picture is not a number, it should not be a subclass (Liskov substitution principle).
Reply all
Reply to author
Forward
0 new messages