Sign in to follow this  
hydroo

Algorithm to find the roundest/most beautiful number in a given interval

Recommended Posts

hydroo    295
As the heading says. Intervals are arbitrarily, positive, negative, huge numbers, very very small numbers. That's what I am doing at the moment
    double delta = max - min;
    double deltalog = floor(logarithm(delta,type));

    /* power of the floor of the log of delta
        ... e.g. 4000 -> 1000, 323 -> 100 */
    double biggeststep = power(deltalog,type);

    /* round down the minmum to a multiple of biggeststep */
    double minround = min - fmod(min,biggeststep);

    /* round min down  */
    double nicenumber = minround;

    /* increase nicenumber by one step */
    if (min > nicenumber) {
        nicenumber += biggeststep;
    }
(the logarithm-/power-wrapper-thing deals with BI- and SI-values separately It produces results. Relatively good ones. flaws: - does not prefere .5-values and even values over others - does sometimes not produce a zero, but the interval is [-x,+y] Any ideas to improve this? Thanks in advance

Share this post


Link to post
Share on other sites
Cygon    1219
I've done something like that for a dynamic time scale display. I don't have the code right now, but from the top of my head, it was something like this:

Take the floor of the logarithm of your interval, eg.
double nextSmallerLog = floor(log10(interval));


then calculate the factor this number has to the obtained next smaller logarithmic whole:
double factor = interval / exp10(nextSmallerLog);


and finally choose the nice number based on where you want to divide a decade:

if(factor < 2.5)
niceNumber = exp10(nextSmallerLog) * 2.5;
else if(factor < 5.0)
niceNumber = exp10(nextSmallerLog) * 5.0;
else
niceNumber = exp10(nextSmallerLog) * 10;


This should round any given interval into numbers like 0.25, 0.50, 1.00, 2.50, 5.00, 10.00, 25.00, 50.00, 100.00, ...

As I said, I'm not quite sure that's the actual code I used, but maybe it does give you an idea about how to proceed.

-Markus-

EDIT: Fixed a stupid spelling error ;)

[Edited by - Cygon on February 22, 2008 12:39:56 AM]

Share this post


Link to post
Share on other sites
hydroo    295
Thanks for your input.

I adopted your idea, and changed the big if into something better imho.


factor = pow(0.5,floor(log10(factor/20.0) / log10(0.5)))*20.0;

nicestep = deltalogpower * factor;

This rounds the factor to 10,5.0,2.5,1.25,0.625, ... which produces kick-ass values :).

Thanks a lot.


@Antheus:
"Human preference". No periods, prefer .5 over even over odd values ... and and and.

Share this post


Link to post
Share on other sites
hydroo    295
For a "performance"-visualization tool. I need a scales for various purposes.
One is displaying an arbitrary time slice of a program to analyze.

Share this post


Link to post
Share on other sites
choffstein    1090
Would you mind posting the entire algorithm and an example or two of how it is used? I think I might be able to apply it to some work that I am doing with psychological interpretations of numbers in the stock market...

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this