• Advertisement
Sign in to follow this  

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

This topic is 3651 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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
Advertisement
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
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
This is an interesting little gem. Mind if I ask what you are using it for, and what the specific conditions are?

Thanks!

Share this post


Link to post
Share on other sites
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
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
Sign in to follow this  

  • Advertisement