Results 1 to 10 of 10

Thread: Round to nearest power of 10

  1. #1
    Join Date
    Nov 2006
    Location
    Mumbai, India
    Beans
    186
    Distro
    Ubuntu 8.04 Hardy Heron

    [SOLVED] Round to nearest power of 10

    I'm usually good at Math and algorithms but for some reason my mind is blocked right now and I can't seem to come up with a solution for this quickly.

    How do I round x to the nearest power of 10?

    For example, 9 => 10, 0.3 => 0.1, 1241 => 1000.

    Note that I want to round to the nearest power and not multiple of 10.

    PS: I'm using Java if that's of any relevance (Java sometimes surprises me with it's vast library)


    Edit: I know it's got something to do with logs but ...
    Last edited by Verminox; June 2nd, 2008 at 06:23 PM. Reason: Solved
    http://verminox.wordpress.com - Answers to Life, the Universe and Everything

  2. #2
    Join Date
    May 2008
    Location
    France
    Beans
    120
    Distro
    Kubuntu 8.04 Hardy Heron

    Re: Round to nearest power of 10

    An approximate solution is: 10^round(log10(n))
    But it rounds more often towars the superior power because log10(5)>0.5. For example it will round 500 to 1000 even if 500 is closer to 100. So you have to tweak it a bit if that's not what you want.

    Edit : here's the tweak I was looking for:
    10^round(log10(n) - log10(5.5) + 0.5)

    (Because 5.5 is the mean of 1 and 10.)
    Last edited by Bichromat; June 2nd, 2008 at 03:58 PM.
    À la chasse au boson intermédiaire

  3. #3
    WW is offline Iced Blended Vanilla Crème Ubuntu
    Join Date
    Oct 2004
    Beans
    1,532

    Re: Round to nearest power of 10

    In the following, x must be positive.
    Code:
    from math import floor, log
    
    def pow10floor(x):
        return 10**floor(log(x,10))
    
    def pow10round(x):
        return 10**floor(log(x,10)+0.5)
    pow10floor(x) gives the largest power of 10 that is less than x.

    pow10round(x) gives the "nearest" power of 10, but "nearest" is based on first taking a logarithm. It takes the (base 10) log, rounds that to an integer, then raises 10 to that power. For example, the value of x that is the "midpoint" between 1 and 10 is therefore the value for which log(x,10) = 0.5, which is sqrt(10) (approx. 3.162277).

    EDIT: That code up there is Python, in case you were wondering. The function floor(y) is the greatest integer less than or equal to y.
    Last edited by WW; June 2nd, 2008 at 04:00 PM.

  4. #4
    Join Date
    Nov 2006
    Location
    Mumbai, India
    Beans
    186
    Distro
    Ubuntu 8.04 Hardy Heron

    Re: Round to nearest power of 10

    Quote Originally Posted by Bichromat View Post
    An approximate solution is: 10^round(log10(n))
    But it rounds more often towars the superior power because log10(5)>0.5. For example it will round 500 to 1000 even if 500 is closer to 100. So you have to tweak it a bit if that's not what you want.

    Edit : here's the tweak I was looking for:
    10^round(log10(n) - log10(5.5) + 0.5)

    (Because 5.5 is the mean of 1 and 10.)
    Actually, we have to consider 5 as the mean of 0 and 10, and not 5.5.

    And WW: There is also a need for accounting that log(5) > 0.5....

    So it would be something like:
    10^round(log(x) - log(5) + 0.5)

    However, this notably fails below x<2.....
    http://verminox.wordpress.com - Answers to Life, the Universe and Everything

  5. #5
    Join Date
    Jun 2006
    Beans
    943

    Re: Round to nearest power of 10

    Do you mean like this?

    99 -> 100.0
    40 -> 10.0
    0.001 -> 0.001
    1.5 -> 1.0
    9 -> 10.0
    0.3 -> 0.1
    1241 -> 1000.0
    EDIT: See Bichromat's first post for a more elegant version of what I posted!
    Last edited by Lster; June 2nd, 2008 at 04:39 PM.

  6. #6
    Join Date
    May 2008
    Location
    France
    Beans
    120
    Distro
    Kubuntu 8.04 Hardy Heron

    Re: Round to nearest power of 10

    Lster: what you propose is exactly what my formula does, so it does not seem to be the solution.
    À la chasse au boson intermédiaire

  7. #7
    Join Date
    Jun 2006
    Beans
    943

    Re: Round to nearest power of 10

    Indeed! Whoops - I didn't realize that!

  8. #8
    WW is offline Iced Blended Vanilla Crème Ubuntu
    Join Date
    Oct 2004
    Beans
    1,532

    Re: Round to nearest power of 10

    OK, the pow10round() function I gave earlier seems more "natural" to me, but this should do what you want:
    Code:
    from math import floor, log
    
    def pow_round(x):
        return 10**(floor(log(x,10)-log(0.5,10)))
    Here it is in action:
    Code:
    >>> from math import floor, log
    >>> 
    >>> def pow_round(x):
    ...     return 10**(floor(log(x,10)-log(0.5,10)))
    ... 
    >>> pow_round(1)
    1.0
    >>> pow_round(4)
    1.0
    >>> pow_round(5)
    10.0
    >>> pow_round(4.99)
    1.0
    >>> pow_round(9.99)
    10.0
    >>> pow_round(10.01)
    10.0
    >>> pow_round(49.99)
    10.0
    >>> pow_round(50)
    10.0
    >>> pow_round(50.001)
    100.0
    >>> pow_round(500.001)
    1000.0
    >>> pow_round(499.99)
    100.0
    >>> pow_round(0.3)
    0.10000000000000001
    >>> pow_round(0.5)
    1.0
    >>> pow_round(0.99)
    1.0
    >>> pow_round(0.004)
    0.001
    >>>
    The discrepancy at values that are exactly at the midpoint of a range (e.g. 0.5, 5, 50, etc.) is likely the result of floating point imprecision.
    Last edited by WW; June 2nd, 2008 at 05:07 PM. Reason: Simplified the formula

  9. #9
    Join Date
    Nov 2006
    Location
    Mumbai, India
    Beans
    186
    Distro
    Ubuntu 8.04 Hardy Heron

    Re: Round to nearest power of 10

    WW: Your code works great

    I just reduced the equation to:

    Code:
    10^(floor(log(2*x)))
    But yes it works just as I wanted it to. Thanks a lot
    http://verminox.wordpress.com - Answers to Life, the Universe and Everything

  10. #10
    WW is offline Iced Blended Vanilla Crème Ubuntu
    Join Date
    Oct 2004
    Beans
    1,532

    Re: Round to nearest power of 10

    Quote Originally Posted by Verminox View Post
    I just reduced the equation to:

    Code:
    10^(floor(log(2*x)))
    Right, very nice!

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •