• Guest, before posting your code please take these rules into consideration:
    • It is required to use our BBCode feature to display your code. While within the editor click < / > or >_ and place your code within the BB Code prompt. This helps others with finding a solution by making it easier to read and easier to copy.
    • Don't share a wall of code. All we want is the problem area, the code related to your issue.
    To learn more about how to use our BBCode feature, please click here.

    Thank you, Code Forum.

Find position of array element

Rusty

New Coder
Function keeps returning a position of 0 (zero) although it should only return zero if wash_abv == the first element. After that the function should return the position of the element that is the lower of the two that wash_abv lies between. Thanks for advice

C:
int find_array_pos(double boiler_abv[], size_t boiler_abv_len, float wash_abv)
{

int pos;
    for(size_t i = 0; i < boiler_abv_len; i++)
    {
        if(boiler_abv[i] == wash_abv)
        {
         return pos = 0;
         break;
        }

         else if (boiler_abv[i] > wash_abv)
         {
          return pos = boiler_abv[i-1];
         }

      }
}
 

LTomy

Active Coder
Staff Team
Guardian
Hello Rusty

Heum... You return statements make no sense.

The following:
C:
return pos = 0;
produces the same result as:
C:
return 0;
Because 'pos' is local to the function and 'return' makes the execution of the function stop.

Also, the 'break' instruction from above will never be executed, because, again, the 'return' statement will make the execution of the function stop before that instruction is reached.

Is your array sorted?
As a reference, if you want to retrieve the position of the element that has the value given in argument and -1 otherwise:
C:
int find_array_pos(double boiler_abv[], size_t boiler_abv_len, float wash_abv)
{
    int pos;
    
    for(size_t i = 0; i < boiler_abv_len; i++)
    {
        if(boiler_abv[i] == wash_abv)
        {
            return pos;
        }
    }
    
    // No elements with the value 'wash_abv' found.
    return -1;
}
 

Rusty

New Coder
Thx LTomy, maybe should have included more?

The array is sorted but the wash_abv variable may or may not be in the array. Just writing this I see another flaw.

In the bigger picture; I have two sorted companion arrays. The first function finds the hi and low values that bracket the passed value and returns an interpolation factor. The second function (shown) wants to return the position of the lower value. The third function will pass the companion array, interpolation factor, and position to return an interpolated value from the companion array.

The flaw I see is I don't allow for a circumstance where the passed value, in either function, actually matches an array element.

Still kinda new at this... might be punching above my weight :thinking: Thanks for advice

Initial and companion arrays:
double boiler_abv[10] = { 0, 0.032, 0.062, 0.092, 0.12,  0.147, 0.174, 0.199, 0.224, 0.248 };
double boiler_abw[10] = { 0, 0.025, 0.05,  0.073, 0.096, 0.119, 0.14,  0.161, 0.182, 0.202 };

function call for interpolate:
float interp_factor = interpolate_array(boiler_abv, sizeof(boiler_abv) / sizeof(boiler_abv[0]), wash_abv);

interpolate definition:
double interpolate_array(double boiler_abv[], size_t boiler_abv_len, float wash_abv)
{
int i;
    for(size_t i = 0; i < boiler_abv_len; i++)
    {
        if(boiler_abv[i] == wash_abv)
        {
         float interp_factor = 1;
         return interp_factor;
         break;
        }

         else if (boiler_abv[i] > wash_abv)
         {
          float low = boiler_abv[i-1];
          float interp_factor = (wash_abv / low);
          return interp_factor;
         }

      }
}
 

LTomy

Active Coder
Staff Team
Guardian
Right now, your function returns 1 if it finds a value inside the array equal to 'wash_abv' or it returns 'wash_abv' divided by the biggest value inside the array that is smaller than 'wash_abv', right? I do not see where is the problem? What behavior do you want it to have?
 

LTomy

Active Coder
Staff Team
Guardian
The problem could be caused by the fact that floating-point variables often approximate the numbers they represent. Because of that, it is rarely a good idea to directly test the equality of two floating-point variables.
This is especially true if the variable are not of the same type (double vs float).
To solve that you should:
1. Use the type 'double' everywhere.
2. Test the equality of two floating-point variables by testing if the difference in their value is small (Like 0.0001) instead of directly using the operator '=='.
 

Rusty

New Coder
You fixed it? How?
Nope. Not getting it. Still returns 0. Same logic as interpolate function, which does work.

All I want is the position of the array value that is either =to or the next one lower than the value passed, i.e., wash_abv. What am I missing?

I take your on float vs double but won't matter here. I'll revise in a bit.
Edit- haha replaced float w/ double and interp_factor turned to garbage.

Code:
int find_array_pos(double boiler_abv[], size_t boiler_abv_len, float wash_abv)
{
    for(size_t i = 0; i < boiler_abv_len; i++)
    {   int pos;
        if(boiler_abv[i] == wash_abv)
        {
         return pos = boiler_abv[i];
         break;
        }

         else if (boiler_abv[i] > wash_abv)
         {
          return pos = boiler_abv[i-1];
         }

      }
}
 
Last edited:

LTomy

Active Coder
Staff Team
Guardian
What is the value of 'wash_abv'?
I do not understand why you are defining the variable 'pos'. Simply write:
C:
int find_array_pos(double boiler_abv[], size_t boiler_abv_len, float wash_abv)
{
    for(size_t i = 0; i < boiler_abv_len; i++)
    { 
        if(boiler_abv[i] == wash_abv)
        {
             return boiler_abv[i];
        }
        else if (boiler_abv[i] > wash_abv)
        {
             return boiler_abv[i-1];
        }

    }
}
 

Rusty

New Coder
wash_abv = .105

I see what you've done. I don't have classroom or mentor training. Self taught- a lot by example. Usually define and initialize a variable before using. This time I didn't initialize.

Edit-No edit... same problem returns 0, interp_factor garbage. Going to start over.
 
Last edited:

LTomy

Active Coder
Staff Team
Guardian
The problem is that you return the value and not the index of the element.
The solution:
C:
int find_array_pos(double boiler_abv[], size_t boiler_abv_len, float wash_abv)
{
    for(size_t i = 0; i < boiler_abv_len; i++)
    {
        if(boiler_abv[i] == wash_abv)
        {
             return i;
        }
        else if (boiler_abv[i] > wash_abv)
        {
             return i-1;
        }

    }
}
I do not know why I did not spot it earlier :sleep:.
You returned the value of the element (A value of type double) as an 'int', so the digits after the decimal point were discarded (Making the result 0).
 

Rusty

New Coder
Truly appreciate your patience and help:thumbsup:

interpolate_ array should return 1.41..... Used to work- not now.

find_array_pos should return 3.

These are the times when I put it down and come back tomorrow;)

full code:
#include <stdio.h>
#include <stdlib.h>*/

/***************************************************/
/*Prototype*/
double interpolate_array(double *boiler_abv, size_t array_len, double wash_abv);
int find_array_pos(double *boiler_abv, size_t array_len, double wash_abv);
double convert(const double *abv_to_abw, size_t abv_to_abw_len, double abv);


int main()
{

double boiler_abv[10] = { 0, 0.032, 0.062, 0.092, 0.12,  0.147, 0.174, 0.199, 0.224, 0.248 };
double boiler_abw[10] = { 0, 0.025, 0.05,  0.073, 0.096, 0.119, 0.14,  0.161, 0.182, 0.202 };


static const double abv_to_abw[9] = /*Array of E Croissants coefficients for conversion of alcohol by weight to alcohol by volume*/
{
0.00018684999875047631, 0.77602465132552556, 0.41803095099103116, -2.5221614925275091, 9.5827123045656251,
-19.928886159385002, 21.4165120890385651, -15.830262207383321, 4.3390473620304988
};
double wash_vol, wash_abv = 0;

printf("/nEnter ABV%% (0 to 1)");
scanf("%f", &wash_abv);
double interp_factor = 0;
interp_factor = interpolate_array(boiler_abv, sizeof(boiler_abv) / sizeof(boiler_abv[0]), wash_abv);

int array_pos = 0;
array_pos = find_array_pos(boiler_abv, sizeof(boiler_abv) / sizeof(boiler_abv[0]), wash_abv);


printf("\n pos = %d\n", array_pos);

printf("interp factor = %f\n", interp_factor);

system("PAUSE");
return (0);
}

/*****************************************************/
/*Definition*/
double interpolate_array(double boiler_abv[], size_t boiler_abv_len, double wash_abv)
{
int i;
    for(size_t i = 0; i < boiler_abv_len; i++)
    {
        if(boiler_abv[i] == wash_abv)
        {
         double interp_factor = 1;
         return interp_factor;
         break;
        }

         else if (boiler_abv[i] > wash_abv)
         {
          double low = boiler_abv[i-1];
          double interp_factor = (wash_abv / low);
          return interp_factor;
         }

      }
}
/********************************************************************************************************/
int find_array_pos(double boiler_abv[], size_t boiler_abv_len, double wash_abv)
{
    for(size_t i = 0; i < boiler_abv_len; i++)
    {
        if(boiler_abv[i] == wash_abv)
        {
             return i;
        }
        else if (boiler_abv[i] > wash_abv)
        {
             return i-1;
        }

    }
}
/******************************************************************************************************/
double convert(const double abw_to_abv[], size_t abw_to_abv_len, double abw)
{
 double abv = abw_to_abv[0];
 double abw_mult = abw;
 for (size_t i = 1; i < abw_to_abv_len; ++i)
 {
  abv = abv + abw_to_abv[i] * abw_mult;
  abw_mult *= abw;
 }
 return abv;
}
 

LTomy

Active Coder
Staff Team
Guardian
Please mark your code as C so it has its syntax highlighted ;).

C:
These are the times when I put it down and come back tomorrow;)
Ahah, yeah, sometimes doing that helps :).

Let us solve 1 function at a time ahah. 'find_array_pos' is still not working? It returns 3 for what value of 'wash_abv'?
 

Rusty

New Coder
Returns 0. But should return array position[3] for a wash_abv of 0.105.

Your immediate responses are both gratifying and encouraging. Thank you but I have to go to dinner now. :)

not sure what you mean by highlight syntax.

regards
 

LTomy

Active Coder
Staff Team
Guardian
Returns 0. But should return array position[3] for a wash_abv of 0.105.

Your immediate responses are both gratifying and encouraging. Thank you but I have to go to dinner now. :)

not sure what you mean by highlight syntax.

regards
You are welcome. Have a nice dinner ;).
Syntax highlighting: So the elements of the code are colored (Ex. keywords like 'int', 'if', 'while'...).
 

LTomy

Active Coder
Staff Team
Guardian
Here is the problem:
I know it is strange, but while "%f" with 'printf' is expecting a value of type 'double', "%f" with 'scanf' is expecting a variable of type 'float'.
To read a 'double', you must use "%lf" with scanf:
C:
scanf("%lf", &wash_abv);
Basically, before, the value of 'wash_abv' was always 0 after the scanf, because it was expecting a 'float' and not a 'double'.
 
Top