Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / December 2005

Tip: Looking for answers? Try searching our database.

double precision vs. integers

Thread view: 
Andersen - 18 Dec 2005 12:42 GMT
I want to take power of something, or the logarithm of something, with
different bases. the Math.* are only defined for doubles, how do I do
these operations if I am sure that everything is a perfect integer log
or a perfect power (integer).
Andersen - 18 Dec 2005 12:45 GMT
> I want to take power of something, or the logarithm of something, with
> different bases. the Math.* are only defined for doubles, how do I do
> these operations if I am sure that everything is a perfect integer log
> or a perfect power (integer).

I extend that question to ceiling and floor which return integers/longs.
O.L. - 18 Dec 2005 13:45 GMT
Andersen a écrit :
> I want to take power of something, or the logarithm of something, with
> different bases. the Math.* are only defined for doubles, how do I do these
> operations if I am sure that everything is a perfect integer log or a perfect
> power (integer).

int a = 5;
int b = 2;
int pow = (int) Math.pow(a, b);

?

Signature

Olivier Ligny
Créateur web free-lance / www.cyber-tamtam.net

Andersen - 18 Dec 2005 16:06 GMT
> int a = 5;
> int b = 2;
> int pow = (int) Math.pow(a, b);

I want the results to be precise and not have any mishaps because of the
conversion.
Mark Thornton - 18 Dec 2005 16:14 GMT
>> int a = 5;
>> int b = 2;
>> int pow = (int) Math.pow(a, b);
>
> I want the results to be precise and not have any mishaps because of the
> conversion.

The specification of Math.pow() includes this

"If both arguments are integers, then the result is exactly equal to the
mathematical result of raising the first argument to the power of the
second argument if that result can in fact be represented exactly as a
double value"

Thus if the arguments are integers and the result is within the range of
int, then the expression given will be correct. This is one of the
advantages of Java's specification; it provides useful guarantees in
circumstances like this.

Mark Thornton
Googmeister - 18 Dec 2005 16:14 GMT
> > int a = 5;
> > int b = 2;
> > int pow = (int) Math.pow(a, b);
>
> I want the results to be precise and not have any mishaps because of the
> conversion.

Not a problem with Math.pow since all values of type int are exactly
representable using type double. According to the API

   If both arguments are integers, then the result
   is exactly equal to the mathematical result of
   raising the first argument to the power of the
   second argument if that result can in fact be
   represented exactly as a double value.
Thomas Weidenfeller - 19 Dec 2005 13:51 GMT
> I want the results to be precise and not have any mishaps because of the
> conversion.

Well, you might want your logarithms "to be precise" in integer
notation, but I am afraid, the odds are very much against you.

logarithms of negative numbers result in complex numbers, so lets forget
about negative numbers at all.

For positive integers, lets take a logarithm where there is some chance
of getting exact results: A logarithm for the base 2 [1]. Then for a 31
bit integer (32 bits minus the sign bit), there are only 32 out of
2147483647 possible integers (the 0 included) where the base 2 logarithm
fits exactly into an integer[1].

That is roughly a chance of one in 67 million to get an exact result for
a random non negative integer argument from a base 2 logarithm.

I think you should reconsider your requirements.

/Thomas

[1] Logarithm computating degenerates into bit counting in this case.

[2] All cases where there is only a single bit true within the 31 bits,
plus when all are false (the 0).
Signature

The comp.lang.java.gui FAQ:
ftp://ftp.cs.uu.nl/pub/NEWS.ANSWERS/computer-lang/java/gui/faq
http://www.uni-giessen.de/faq/archiv/computer-lang.java.gui.faq/

Eric Sosman - 19 Dec 2005 20:32 GMT
Thomas Weidenfeller wrote On 12/19/05 08:51,:

>>I want the results to be precise and not have any mishaps because of the
>>conversion.
[quoted text clipped - 10 lines]
> 2147483647 possible integers (the 0 included) where the base 2 logarithm
> fits exactly into an integer[1].

   ITYM 31 cases, or else you've come up with a new way
of defining the logarithm of zero.  (Also, if "the 0 included"
then why only 2147483647 possible integers instead of ...8?)

> That is roughly a chance of one in 67 million to get an exact result for
> a random non negative integer argument from a base 2 logarithm.

   Well, he could use other bases to improve his odds.
Base-two logarithms cover the 31 values 1,2,4,...,1073741824.
Base-three covers 1,3,9,...,1162261467; the 1 is a duplicate
so that's 19 more values for a total of 50.  Base-five gives
1,5,25,...,1220703125 and raises the total to 63 (we've already
doubled the oroginal coverage), and so on for other bases.
For the ultimate simplification, he can define

    static int exactLog(int n) {
       if (n <= 0)
           throw new IllegalArgumentException();
       return 1;
    }

... with the appropriate logarithmic base implied ;-)

Signature

Eric.Sosman@sun.com

Andersen - 19 Dec 2005 22:53 GMT
>     ITYM 31 cases, or else you've come up with a new way
> of defining the logarithm of zero.  (Also, if "the 0 included"
> then why only 2147483647 possible integers instead of ...8?)

...

>>That is roughly a chance of one in 67 million to get an exact result for
>>a random non negative integer argument from a base 2 logarithm.
[quoted text clipped - 6 lines]
> doubled the oroginal coverage), and so on for other bases.
> For the ultimate simplification, he can define

The bigger the base the fewer numbers fit in the double, not the other
way around.

>     static int exactLog(int n) {
>        if (n <= 0)
>            throw new IllegalArgumentException();
>        return 1;
>     }

For a fact, my program will never be invoked with log_k(k), or there is
something fishy with the postcondition of some other function.
Eric Sosman - 19 Dec 2005 23:15 GMT
Andersen wrote On 12/19/05 17:53,:

>>    ITYM 31 cases, or else you've come up with a new way
>>of defining the logarithm of zero.  (Also, if "the 0 included"
[quoted text clipped - 15 lines]
> The bigger the base the fewer numbers fit in the double, not the other
> way around.

   Yes, but with several bases you can cover more numbers
than with just one.

>>    static int exactLog(int n) {
>>       if (n <= 0)
[quoted text clipped - 4 lines]
> For a fact, my program will never be invoked with log_k(k), or there is
> something fishy with the postcondition of some other function.

   You snipped and apparently overlooked the ;-)

   The function as shown correctly computes the logarithm
of any positive integer.  It does this by using an adaptive
technique, choosing a base that permits the calculation to
be exact.  For example, exactLog(2) computes a binary
logarithm, exactLog(10) computes a decimal logarithm, and
exactLog(42) computes a base-42 logarithm.  100% effective,
100% exact, and surprisingly efficient.  I'll grant that
it has a few drawbacks, but hey ...

Signature

Eric.Sosman@sun.com

Thomas Weidenfeller - 20 Dec 2005 09:16 GMT
>     ITYM 31 cases, or else you've come up with a new way
> of defining the logarithm of zero.

Ups :-)

> (Also, if "the 0 included"
> then why only 2147483647 possible integers instead of ...8?)

Because, ahem, because, aehm, aehm, well :-)

/Thomas
Signature

The comp.lang.java.gui FAQ:
ftp://ftp.cs.uu.nl/pub/NEWS.ANSWERS/computer-lang/java/gui/faq
http://www.uni-giessen.de/faq/archiv/computer-lang.java.gui.faq/

Roedy Green - 19 Dec 2005 22:27 GMT
On Mon, 19 Dec 2005 14:51:04 +0100, Thomas Weidenfeller
<nobody@ericsson.invalid> wrote, quoted or indirectly quoted someone
who said :

>That is roughly a chance of one in 67 million to get an exact result for
>a random non negative integer argument from a base 2 logarithm.

But by that thinking the number 42 is impossible.  It is immeasurable
small on the real line, and only a blip in the universe of doubles.

If he is working with only integers, if he squares one, the odds of a
sqrt giving a int result are much improved. Ditto for log and exp.
Signature

Canadian Mind Products, Roedy Green.
http://mindprod.com Java custom programming, consulting and coaching.

Andersen - 19 Dec 2005 22:45 GMT
> Well, you might want your logarithms "to be precise" in integer
> notation, but I am afraid, the odds are very much against you.
[quoted text clipped - 12 lines]
>
> I think you should reconsider your requirements.

Hope you had a little fun there. I have an application where I know the
numbers are powers of some base k, and I want their logarithm. I could
resort to bit counting and then divide by log_2(k), but I am afraid that
will lead to rouding errors because of the way floating point numbers
are represented.
Eric Sosman - 19 Dec 2005 23:00 GMT
Andersen wrote On 12/19/05 17:45,:

>>Well, you might want your logarithms "to be precise" in integer
>>notation, but I am afraid, the odds are very much against you.
[quoted text clipped - 18 lines]
> will lead to rouding errors because of the way floating point numbers
> are represented.

    static int logBaseK(int n, int k) {
       return (int)Math.round(Math.log(n) / Math.log(k));
    }

Yes, there will be inaccuracies in computing the two logs, and
probably in computing their quotient.  But the inaccuracies
will be small (assuming legitimate n and k), and will be fixed
by the Math.round() call.

   You could do an all-integer (or -long) version using
repeated multiplication: start with 1, multiply by k until
you get n, and return the count.  You'd never need more
than 30 (62) iterations in the worst legitimate case.

   Error-checking (in both versions) is left as an
exercise for the reader.

Signature

Eric.Sosman@sun.com

Chris Uppal - 20 Dec 2005 09:55 GMT
>     You could do an all-integer (or -long) version using
> repeated multiplication: start with 1, multiply by k until
> you get n, and return the count.  You'd never need more
> than 30 (62) iterations in the worst legitimate case.

Or a table lookup (probably with a binary chop or similar).

   -- chris
Thomas Weidenfeller - 20 Dec 2005 10:02 GMT
> Hope you had a little fun there.

Sure, nothing in the group's charter prohibits having a bit of fun.

And as a general hint, playing with then numbers and some formulas when
you have a math problem at hand doesn't hurt. It gives you some feel for
the problem.

> I have an application where I know the
> numbers are powers of some base k,

k being a positive integer? Why didn't you tell us this upfront? You
could e.g. handle that problem with a lookup table. E.g for a base 2 a
table of 31 integers if you really don't trust log():

    final static int logs2[] = {
        0x00000001, 0x00000002, 0x00000004, 0x00000008,
        0x00000010, 0x00000020, 0x00000040, 0x00000080,
        0x00000100, 0x00000200, 0x00000400, 0x00000800,
        0x00001000, 0x00002000, 0x00004000, 0x00008000,
        0x00010000, 0x00020000, 0x00040000, 0x00080000,
        0x00100000, 0x00200000, 0x00400000, 0x00800000,
        0x01000000, 0x02000000, 0x04000000, 0x08000000,
        0x10000000, 0x20000000, 0x40000000
    };

    final static int logs3[] = {
        1, 3, 9, 27,
        ...
    };

   
    private int binSearch(int values[], int e) throws ImpreciseException
    {
        int l = 0;
        int r = values.length - 1;
        int p;
        while(l <= r) {
            p = (l + r) / 2;
            if(e == values[p]) return p;
            if(e < values[p]) {
                r = p - 1;
            } else {
                l = p + 1;
            }
        }
        throw new ImpreciseException();
    }

    public int preciseLog2(int e) throws ImpreciseException
    {
        return binSearch(logs2, e);
    }

    public int preciseLog3(int e) throws ImpreciseException
    {
        return binSearch(logs3, e);
    }

/Thomas
Signature

The comp.lang.java.gui FAQ:
ftp://ftp.cs.uu.nl/pub/NEWS.ANSWERS/computer-lang/java/gui/faq
http://www.uni-giessen.de/faq/archiv/computer-lang.java.gui.faq/

Andersen - 20 Dec 2005 11:02 GMT
> k being a positive integer? Why didn't you tell us this upfront? You
> could e.g. handle that problem with a lookup table. E.g for a base 2 a
> table of 31 integers if you really don't trust log():

That is fine if you need 5 different k's, if you want something general
you need more tables. Given what I said earlier that I am not interested
in the trivial logarithm: log_k(k), that would mean we need
floor(sqrt(2^n)) tables for a n bit numbers. Only for 31 bits that would
be some 46340 tables or so. I suppose you could generate these in a list
of lists... The only limit would be the memory, it would take 100kb of
memory or so, not much for a PC, huge for a smaller device under MIDP.
Roedy Green - 18 Dec 2005 16:18 GMT
On Sun, 18 Dec 2005 13:42:43 +0100, Andersen
<andersen_800@hotmail.com> wrote, quoted or indirectly quoted someone
who said :

>I want to take power of something, or the logarithm of something, with
>different bases. the Math.* are only defined for doubles, how do I do
>these operations if I am sure that everything is a perfect integer log
>or a perfect power (integer).
You can take your answer then round it and see if it matches exactly.

see http://mindprod.com/jgloss/round.html
Signature

Canadian Mind Products, Roedy Green.
http://mindprod.com Java custom programming, consulting and coaching.



Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2009 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.