2
$\begingroup$

I'm developing a C++ program and I need to find a formula that given a number to reduce and a limit number, get a value between 0 and this limit number.

I don't know if it is allow to put C++ code here, but I want to show you my function:

double Utils::reduceNumber(double numberToReduce, double limitNumber)
{
    double factor = 0.0;
    double result = 0.0;

    factor = std::abs(numberToReduce / limitNumber);

    if (factor != (int)factor)
        factor = (int)factor + 1;

    if (numberToReduce > 0)
        result = numberToReduce - (byNumber * factor);
    else
        result = numberToReduce + (byNumber * factor);

    return result;
}

For example, If I want to reduce −465.986246 in a limit between 0 and 24, I have to do this:

−465.986246 + (24 x  20) = 14.013754

What is the formula to obtain that 20?

$\endgroup$
3
  • $\begingroup$ Try setting your factor as: $\frac{l - 2n}{2l}$ where $l$ is your limit and $n$ is the number you are "reducing" to the interval $(0,l)$. $\endgroup$
    – anak
    Jul 31, 2015 at 16:38
  • $\begingroup$ Are you asking for a mathematical formula or one in C++? $\endgroup$ Jul 31, 2015 at 16:43
  • $\begingroup$ I'm asking for a mathematical formula. I'm going to translate it to C++ later. $\endgroup$
    – VansFannel
    Jul 31, 2015 at 16:43

3 Answers 3

4
$\begingroup$

Let $a$ be a given number. Also, suppose that the limit is between $0$ and $N$.

If you want an integer $b$ such that $$0\le a+Nb\le N\iff -\frac{a}{N}\le b\le \frac{N-a}{N},$$ then $$b=\left\lfloor\frac{N-a}{N}\right\rfloor$$ works where $\lfloor x\rfloor$ is the largest integer not greater than $x$.

For $a=−465.986246$ and $N=24$, we have $b=\left\lfloor\frac{24-(−465.986246)}{24}\right\rfloor=20$.

$\endgroup$
3
  • $\begingroup$ Thanks for your great answer. Now, a = 28.668119326367531 and I'm having problems because the b value is rounded to 0. $\endgroup$
    – VansFannel
    Jul 31, 2015 at 17:06
  • $\begingroup$ @VansFannel: For $a=28.668119326367531$ and $N=24$, I think $b=-1$. $\endgroup$
    – mathlove
    Jul 31, 2015 at 17:22
  • $\begingroup$ Thanks. Now I need that the value will be between 1 and N. How can I do it? $\endgroup$
    – VansFannel
    Jan 26, 2016 at 18:01
1
$\begingroup$

Just setting up some notation:

For your limit number $l > 0$ and the number you want to "reduce", $n$, you want to find another number $x$ such that it satisfies: $$(n + l\cdot x) \in (0,l).$$

So for example, we know that $\frac{l}{2} \in (0,l)$ obviously, so we will say you want to satisfy the equation: $$n + l\cdot x = \frac{l}{2}.$$

Solving this equation for $x$ results in the following: $$x = \frac{l-2n}{2l}.$$


Note this will always put the number in the centre of the interval $(0,l)$. You can also do this for other specific points in the interval $(0,l)$.

If you want some sort of random noise to not make it the exact centre of the interval each time, you can just let $\epsilon$ be your randomly generated number in the interval $(-1,1)$ and then set your $x$ as follows: $$x = \frac{l(1+\epsilon) - 2n}{2l}.$$

EDIT: I see that mathlove assumed you wanted an integer, so this solution likely isn't what you wanted (however you specify the 'factor' is a double in your code, so you might want to optimize that if that is the case...).

$\endgroup$
2
  • $\begingroup$ I need an integer, but I have to round factor's value because now I having problems when the number is 28.668119326367531. $\endgroup$
    – VansFannel
    Jul 31, 2015 at 17:05
  • 1
    $\begingroup$ @VansFannel Use mathlove's solution for an integer value. $\endgroup$
    – anak
    Jul 31, 2015 at 17:12
1
$\begingroup$

Using math love's solution, this is my function now:

double Utils::reduceNumber(double numberToReduce, double limitNumber)
{
    float factor = 0.0;
    double result = 0.0;

    factor = (limitNumber - numberToReduce) / limitNumber;

    if (factor < 0.0)
    {
        factor -= 1;
    }
    else
    {
        if ((std::abs(factor) - (int)std::abs(factor)) > 0.5)
        {
            factor += 1;
        }
    }

    result = numberToReduce + (byNumber * (int)factor);

    return result;
}

Now it works with 28.668119326367531 and with −465.986246 numbers.

$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .