Separate to nearest 1 decimal place without floating point math?

I am having problems with my C # program and I figured out that this percentage calculation was causing the slowdown. The calculation is just n / d * 100. Both numerators and denominator can be any integer. The numerator can never be larger than the denominator and will never be negative. Therefore, the result is always 0-100. Right now, this is done using floating point math and is somewhat slow as it is calculated tens of millions of times. I really don't need anything more accurate than the nearest 0.1 percent. And I just use this calculated value to see if it is greater than a fixed constant value. I think everything should be stored as an integer, so a range with 0.1 precision would be 0-1000. Is there a way to calculate this percentage without floating point math?

Here is the loop I am using with the calculation:

for (int i = 0; i < simulationList.Count; i++)
{
    for (int j = i + 1; j < simulationList.Count; j++)
    {
        int matches = GetMatchCount(simulationList[i], simulationList[j]);
        if ((float)matches / (float)simulationList[j].Catchments.Count > thresPercent)
        {
            simulationList[j].IsOverThreshold = true;
        }
    }
}

      

+2


source to share


3 answers


Instead, n/d > c

you can use n > d * c

(suppose d > 0

).
( c

is the constant value you are comparing with.)

This way you don't need division at all.



Watch out for overflows, however.

+6


source


If your units are in tenths instead of ones, then you can get 0.1 precision using integer arithmetic:

Instead:

for (...)
{
    float n = ...;
    float d = ...;

    if (n / d > 1.4) // greater than 140% ?

      



... do something like:

for (...)
{
    int n = 10 * ...;
    int d = ...;
    if (n / d > 14) // greater than 140% ?

      

0


source


Instead of recording

if ((float)matches / (float)simulationList[j].Catchments.Count > thresPercent)

      

write this:

if (matches * theresPercent_Denominator > simulationList[j].Catchments.Count * thresPercent_Numerator)

      

This way you get rid of the floating points.

Note: thresPercent

can be expressed as thresPercent_Numerator / theresPercent_Denominator

if the number is a rational number.) I think this is the optimal way on a PC. For some other platform, you can optimize it by shifting left or right if theresPercent_Denominator and / or thresPercent_Numerator is 2 powers. (Usually left shift is sufficient, but it may be necessary to use right shift, rearranging the equation per division to prevent overflow)

0


source







All Articles