On Dec 28, 2008, at 5:27 AM, Christophe Grand wrote:

>
> Mark Engelberg a écrit :
>> So one thing I don't get is why would tristan's pow code sometimes
>> generate a BigInteger, and sometimes a Long for the same resulting
>> number?
>>
> Good question.
>
> (pow 2 32); returns 4294967296 (BigInteger)
> (pow 4 16); returns 4294967296 (Long)
> (pow 16 8); returns 4294967296 (Long)
>
> and if we expand Tristan's pow we get:
> (* 2 (pow 2 31)); where (class (pow 2 31)) is Long since
> Integer/MAX_VALUE is 2^31-1
> (* 4 (pow 4 15)); where (class (pow 4 15)) is Integer
> (* 16 (pow 16 7)); where (class (pow 16 7)) is Integer
> ;(2, 4 and 16 are Integers).
>
> With (* 4 (pow 4 15)) or (* 16 (pow 16 7)) each operand is promoted  
> from
> Integer to Long and since the result can't fit into an Integer, a Long
> is returned.
> With (* 2 (pow 2 31)) each operand is promoted to BigInteger (since  
> (pow
> 2 31) is already a Long) and... the result is not reduced to a Long
> albeit small enough.
>
> Looking at Numbers.java, the code that should perform this reduction  
> is
> commented
> http://code.google.com/p/clojure/source/browse/trunk/src/jvm/clojure/lang/Numbers.java#270
> and is commented since it first appeared in rev 811.
>
> We'll have to wait for Rich to know why these two lines are  
> commented out.
>
>

This lack of reduction to smallest representation is indeed the  
problem here. I'm not sure commenting out those two lines is a  
sufficient fix.

The original concern is one of efficiency, since long ops are promoted  
to BigInteger it would be inefficient to represent as Long and convert  
to BigInteger for every op.

The right thing I think is to represent as Integer and Long whenever  
possible, and do overflow checking (as is done in the static  
add(long,long) etc) rather than pre-op upconversion to next size. This  
would require the addition of a LongOps etc.

I've added an issue for this:

http://code.google.com/p/clojure/issues/detail?id=22

Patch welcome.

Rich
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to