Home > Mobile >  Precesion Error in C , using double or float data type in for loop
Precesion Error in C , using double or float data type in for loop

Time:11-08

So I encountered this weird issue that is self explanatory in this photo:C   program

In the first 8 lines, I used a variable called classwidth to add increments to l which is set to have an initial value of 18.75. Each iteration of the loop prints l value.

However in the second 8 lines, I do the same thing but, I replaced classwidth variable with a constant 1.68, the results are identical in the first 2 lines in each iteration, but in the second 8 lines the program calculates numbers correctly and as expected, while in the first 8 lines, the code starts to lose precession in the fourth line as shown in the photo.

I don't want to use a constant value of 1.68, because this value is calculated by range and k parameters, so it will not always be 1.68.

What should I do to have the precession in the second eight lines while using constant classwidth?

This is my code:

#include <iostream>
#include <algorithm>
#include <cmath>
#include <iomanip>
using namespace std;

int main()
{
//    cout << fixed;
//    cout << setprecision(2);
//    cout << 20.42   1.68*3 << endl;
    double range;
    double l;
    int k = 8;
    range = 32.17 -18.75;
    double classwidth = range/k;
    cout << fixed;
    cout << setprecision(2);
    l = 18.75;
    for(int n = 1; n<=k ; n  ){
        cout<< l << "                 classwidth: "<< classwidth<<endl;
        l  = classwidth;




    }
    cout << "\n\n\n";
    l = 18.75;
    for(int n = 1; n<=k ; n  ){
        cout<< l << "                 classwidth: "<< 1.68 <<endl;
        l  = 1.68;



    }
    //groupedData();


}

I commented the

cout << fixed;
cout << setprecision(2);

line of code so it is nonfunctional and I still didn't achieve what I want: C   program

This is the full program:

#include <iostream>
#include <algorithm>
#include <cmath>
#include <iomanip>
using namespace std;
//CURRENTLY UNFINISHED YET!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
void groupedData()
{
    int b = 0;
    int j;
    double numberOfClasses = 0;
    int i = 0;
    double arr[300];
    cout << "Will you specify number of classes (k) 1(yes), 0(no)?"<<endl;
    bool k_manual;
    cin >> k_manual;
    if(cin.fail())
    {
        cout <<"Invalid input."<<endl;
        exit(0);
    }
    else if(k_manual == 1)
    {
        cout << "What is it?\n";
        cin >> numberOfClasses;
        if(cin.fail())
        {
            cout <<"Invalid input."<<endl;
            exit(0);
        }
    }

    cout << "Enter grouped discrete quantitative data to calculate measures of central tendency and measures of variation.\nUse 0 to terminate.\n";
    cout << "======================================"<<endl;
    while (i < 300)
    {
        cin >> arr[i];
        if (!cin.fail() && arr[i] == 0)
        {
            int classesK[150];
            if (numberOfClasses == 0)
            {
                numberOfClasses = ceil(1   3.3*log10(i));
            }
            for(j=0; j<= numberOfClasses; j  )
            {
                b  = 1;
                classesK[j] = b;

            }
            double classWidthPrecession;
            cout << "Class width precession (1/0.1/0.01)?"<<endl;
            cin >> classWidthPrecession;
            //int arr[] = {1,2,3,3,2,5,4,4,3,1,2,1,4,6,5,5,4,2,3,2};
            cout << "\n\nCalculating..."<<endl;
            cout << "------------------"<<endl;
            //mean calculation

            double mean;
            double sum = 0;
            for (j=0; j < i; j  )
            {
                sum  = arr[j];

            }
            mean = sum / i;
            cout << "\nMeasures of central tendency:\n----------------------------\n";
            cout <<"Mean(x_-): "<< mean <<endl;
            //median calculation
            sort(arr, arr   i, less<double>());
            if (!((i % 2) == 0))
            {
                int median_index = (i 1) / 2;
                double median = arr[median_index - 1];
                cout << "Median (x_~): " <<  median;

            }
            else
            {
                double median = (arr[i/2 - 1]   arr[i/2] ) / 2.0;
                cout << "Median (x_~): " <<  median;
            }
            //range calculation
            double range = arr[i-1] - arr[0];
            cout << "\n\nMeasures of variability:\n-------------------------\n";
            cout << "Range: " << range;
            sum = 0;
            for (j=0; j<i; j  )
            {
                sum  = pow((arr[j] - mean), 2);
            }
            double variance = sum / (i-1);
            double stdDeviation = sqrt(variance);
            double COV = (stdDeviation/mean) * 100;
            cout << "\nVariance_s2: " << variance;
            cout << "\nStandard Deviation: " << stdDeviation;
            cout << "\nCoefficient of Variation: " << COV << "%";
            //mean deviation calc
            sum = 0;
            for (j=0; j<i; j  )
            {
                sum  = abs(arr[j] - mean);
            }
            double meanDeviation = sum / i;
            cout << "\nMean Deviation: " << meanDeviation <<endl;
            cout << "-----------------------------------------------------------"<<endl;


            int frqArr[150];
            double XiArr[150];
            for(j=0; j<150; j  )
            {
                frqArr[j]=0;
            }
            int k = 0;
//            for(j=0; j<i; j  )
//            {
//                if(arr[j] == arr[j   1])
//                {
//                    frqArr[k]  = 1;
//                    continue;
//                }
//                else
//                {
//                    k  ;
//                    XiArr[k] = arr[j];
//                }
//            }
//            int cumArr[150];
//            int sumInt = 0;
//            for(j=0; j<=k; j  )
//            {
//                sumInt  = frqArr[j];
//                cumArr[j] = sumInt;
//
//            }

            sort(arr, arr i, less<double>());
            double classWidth = range/numberOfClasses;
            if(classWidthPrecession == 1)
            {
                classWidth = ceil(classWidth);
            }
            cout << fixed;
            cout << setprecision(3);

            double temp = 1.0;
            double ll = arr[0];
            double ul;
            double ulArr[150];
            double llArr[150];
            ul = (ll   classWidth) - classWidthPrecession;
            double num = classWidth;
            for(j=0; j<=numberOfClasses; j  )
            {
                ulArr[j] = ul;
                llArr[j] = ll;
                temp = 2.0;
                ll = ll   (temp-1.0)*(classWidth);
                ul = ul   (temp-1.0)*(classWidth);
            }
            b=0;
            k=0;

            for(j=0; j<=i; j  )
            {
                if((arr[j] >= llArr[b]) && (arr[j] <= ulArr[b]))
                {
                    frqArr[k]  ;
                    continue;
                }
                else
                {
                    b  ;
                    k  ;
                    continue;
                }
            }
            frqArr[0] -= 1;
            int cumArr[150];
            int sumInt = 0;
            for(j=0; j<=k; j  )
            {
                sumInt  = frqArr[j];
                cumArr[j] = sumInt;
            }
            cout << fixed;
            cout << setprecision(2);
            cout << "k\t\b|classes\t\t\t\b|Fi\t\t\b|FiXi\t\b|(Xi - X_)^2\t\b|Fi(Xi - X_)^2\t\b|Xi - X_|\t\b|Fi|Xi - X_|"<<endl;
            for(j=1; j<=numberOfClasses; j  )
            {
                //table output..........................
                cout<<classesK[j-1]<< "\t\b|" << llArr[j-1] << " - " << ulArr[j-1] << "\t\t\b|" << frqArr[j-1]<<endl;

            }
//            int frqArrSorted [150];
//            copy(frqArr, frqArr   k, frqArrSorted);
//            sort(frqArrSorted, frqArrSorted   k);
//            // cout << "\n\n" << frqArrSorted[k-1];
//            int largestFrq = frqArrSorted[k-1];
//            bool isMultimodal = 0;
//
//
//            for(b=2; b<=k; b  )
//            {
//                if(largestFrq == frqArrSorted[k-b])
//                {
//                    isMultimodal = 1;
//                    continue;
//
//                }
//                else if(!isMultimodal)
//                {
//                    break;
//                }
//            }
//            b = 0;
//            int ModeValIndex[150];
//            for(j=0; j<=k; j  )
//            {
//                if (frqArr[j] == largestFrq && !isMultimodal)
//                {
//                    ModeValIndex[0] = j;
//                    break;
//                }
//                else if(frqArr[j] == largestFrq && isMultimodal)
//                {
//                    ModeValIndex[b] = j ;
//                    b  ;
//                }
//                continue;
//            }
//
//            if(isMultimodal)
//            {
//                cout << "\n\nModes are: " <<endl;
//                for(j=0; j<b; j  )
//                {
//                    cout <<  XiArr[ModeValIndex[j]   1] <<endl;
//                }
//                if(b==2)
//                {
//                    cout << "\nMode is BiModal."  << endl;
//                }
//                else
//                {
//                    cout << "\nMode is MultiModal." << endl;
//                }
//
//
//
//            }
//
//            else
//            {
//                cout << "\n\nMode is: " << XiArr[ModeValIndex[0]   1] << " (UniModal) " <<endl;
//
//            }
//

//            int max_frqArrVal = 0;
//            for(j=0; j<=k; j  ){
//                if(frqArr[j] > frqArr[j 1]){
//                    if(frqArr[j] > max_frqArrVal){
//                            max_frqArrVal = frqArr[j];
//                            continue;
//                    }else if()
//                    else{
//                        continue;
//                    }
//
//                }else{
//                        continue;
//                }
//
//            }




            exit(0);


        }
        else if (!cin.fail())
        {
            i  ;
            continue;

        }
        else
        {
            cout<<"Wrong!"<<endl;
            system("pause");
            exit(0);
        }



    }
}





int main()
{
//    cout << fixed;
//    cout << setprecision(2);
//    cout << 20.42   1.68*3 << endl;
    double range;
    double l;
    int k = 8;
    range = 32.17 -18.75;
    double classwidth = range/k;
//    cout << fixed;
//    cout << setprecision(2);
    l = 18.75;
    for(int n = 1; n<=k ; n  )
    {
        cout<< l << "                 classwidth: "<< classwidth<<endl;
        l  = classwidth;




    }
    cout << "\n\n\n";
    l = 18.75;
    for(int n = 1; n<=k ; n  )
    {
        cout<< l << "                 classwidth: "<< 1.68 <<endl;
        l  = 1.68;



    }
    //groupedData();


}

These are the test data that I use:

21.52
19.83
23.11
18.75
20.5
22.48
21.61
19.24
20.48
22.25
19.72
24.36
20.84
22.74
19.37
21.75
20.21
32.17
20.38
20.76
21.87
19.81
21.95
20.93
19.05
23.39
21.05
22.87
22.17
21.24
24.1
20.15
19.84
23.6
20.26
21.47
22.98
21.13
20.04
22.05
21.33
21.36
24.87
19.42
21.23
25.12
20.58
21.75
19.95
21.94

CodePudding user response:

(32.17−18.75)/8 is 1.6775, not 1.68, so it is unclear why you would expect 1.68 to maintain accuracy.

To avoid accumulating rounding errors in a loop, recalculate the value from scratch in each iteration instead of adding to a previous value:

double start = 18.75, end = 32.17;
for (int n = 0; n < k;   n)
{
    l = start   (end-start)*n/k;
    cout << l << endl;
}

CodePudding user response:

So I finally found an answer, which relies on using this function to round every number that requires so:

double rounderFunction(double request, int decimalPlaces)
{
    double newNum;
    double shiftAmount = pow(10, decimalPlaces);
    newNum = round(request * shiftAmount) / shiftAmount;
    return newNum;

}
  • Related