max is initialized to a very high value .. initialize max to 0;
int max = 0;
Here is the fixed code :
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main( void )
{
int i = 0;
int a[11];
int min = 0;
int max = 0;
srandom( (unsigned) time(NULL) );
a[0]=random( ) % 100 ;
min = a[0];
for (i=1;i<11;i++)
{
a[i]=random( ) % 100 ;
printf("%d\n", a[i]);
if (a[i] > max)
{
max = a[i];
}
if (a[i] < min)
{
min = a[i];
}
}
printf("Min: %d\n", min);
printf("Max: %d\n", max);
return 0;
}
Output:
Notra:Desktop Sukhvir$ ./try
82
91
33
8
60
48
60
6
59
62
60
Min: 6
Max: 91
Answer from sukhvir on Stack Overflowmax is initialized to a very high value .. initialize max to 0;
int max = 0;
Here is the fixed code :
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main( void )
{
int i = 0;
int a[11];
int min = 0;
int max = 0;
srandom( (unsigned) time(NULL) );
a[0]=random( ) % 100 ;
min = a[0];
for (i=1;i<11;i++)
{
a[i]=random( ) % 100 ;
printf("%d\n", a[i]);
if (a[i] > max)
{
max = a[i];
}
if (a[i] < min)
{
min = a[i];
}
}
printf("Min: %d\n", min);
printf("Max: %d\n", max);
return 0;
}
Output:
Notra:Desktop Sukhvir$ ./try
82
91
33
8
60
48
60
6
59
62
60
Min: 6
Max: 91
Your problem is right here:
int a[11];
int min = a[0];
int max = a[0];
You're using a[0] to initialize min and max, before a[0] itself has been initialized.
Initialize a[0], then set min and max to its value, then proceed from there.
MInimum element in array ( C ) - Stack Overflow
Finding max and minimum values from an array in C - Stack Overflow
C code to find max and min values: unexpected results
algorithm - Min / Max function of 1D array in C / C++ - Code Review Stack Exchange
Videos
It is a bad idea when a function depends on a global variable.
But in any case your function is incorrect and invokes undefined behavior.
In the first call of the function this if statement
Copyif (array[size] <= min) min = array[size];
trying to access memory outside the passed array because the valid range of indices is [0, size).
Also the array can contain all elements greater than the initial value of the global variable
Copyint min = 1000;
And the function may not be called a second time because the value of the variable min is unspecified.
The function should return the index of the minimal element in the array. In general the user can pass the second argument equal to 0. In this case again the function will invoke undefined behavior if you will try to return a non-existent element of an empty array.
The function can be declared and defined the following way
Copysize_t recursiveMinimum( const int a[], size_t n )
{
if ( n < 2 )
{
return 0;
}
else
{
size_t min1 = recursiveMinimum( a, n / 2 );
size_t min2 = recursiveMinimum( a + n / 2, n - n / 2 ) + n / 2;
return a[min2] < a[min1] ? min2 : min1;
}
}
Here is a demonstration program
Copy#include <stdio.h>
size_t recursiveMinimum( const int a[], size_t n )
{
if (n < 2)
{
return 0;
}
else
{
size_t min1 = recursiveMinimum( a, n / 2 );
size_t min2 = recursiveMinimum( a + n / 2, n - n / 2 ) + n / 2;
return a[min2] < a[min1] ? min2 : min1;
}
}
int main( void )
{
int a[] = { 55, 5, 1, 27, 95, 2 };
const size_t N = sizeof( a ) / sizeof( *a );
size_t min = recursiveMinimum( a, N );
printf( "\nMinimum element of this array is: %d at the position %zu\n",
a[min], min );
}
The program output is
CopyMinimum element of this array is: 1 at the position 2
Pay attention to that the first parameter has the qualifier const because the passed array is not being changed within the function. And to decrease the number of recursive calls the function calls itself for two halves of the array.
Recursion works by reducing the size at the call to the next iteration and comparing the result of the call with the current value and return the lower of the 2.
As recursion stop you can simply return the first element
Copyint recursiveMinimum(int array[], size_t size) {
if (size == 1) return array[0];
int min_of_rest = recursiveMinimum(array, size - 1);
if (array[size - 1] <= min_of_rest) return array[size - 1];
return min_of_rest;
}
Full example: https://godbolt.org/z/sjnh8sYz3
scanf("%lf",&num); will invoke undefined behavior because double(*)[10] is passed where double* is expected.
You should read to each elements if you want to use an array. Note that array index in C starts from 0, not 1. You also should check if reading is successful.
Copy#include<stdio.h>
// main program
int main(void){
int i;
double num[10];
for (i=1;i<=10;i++){
printf("Enter a number: ");
if (scanf("%lf",&num[i - 1]) != 1){
puts("read error");
return 1;
}
}
// calculate max and minimum values and print them
return 0;
}
or this code uses what seems better for range of i.
Copy#include<stdio.h>
// main program
int main(void){
int i;
double num[10];
for (i=0;i<10;i++){
printf("Enter a number: ");
if (scanf("%lf",&num[i]) != 1){
puts("read error");
return 1;
}
}
// calculate max and minimum values and print them
return 0;
}
If, in addition to the other answers, you intend to write/call a function to find both the max and min values in your array of doubles, your first challenge is overcoming the axiom that only a single value (or pointer) can be returned by a function in C. There are several options available to determine the max and min in a function (or functions).
The first, and obvious, alternative is to write both a max and min function and call each. (but that would require iterating over your array twice -- that would be less than optimal). Your next option is to pass a separate array (of at least 2 double values) to store your max and min values in and either update the values or return a pointer to that array
(passing the array will automatically make values stored in the maxmin array available back in your calling function (main() in your case), but to immediately use the values in same call, you can return the pointer to the max/min array for convenience. You can also return NULL on error to indicate failure)
Or, since there are only 2 values needed, you can pass individual pointers to max and min as parameters and update the values pointed to by each within your function. Choosing some return type to indicate success/failure is also a good idea. int in this case is as efficient as any other (better from a numeric conversion standpoint)
With that in mind a simple maxmin function taking a pointer to your array of double values, pointers to each max and min and finally the number of values in the array could be written like:
Copy/** find the max and min in array of 'n' doubles `ad`.
* update 'max' and 'min' pointers so values are available back
* in calling function.
*/
int maxmin_dbl (double *ad, double *max, double *min, size_t n)
{
if (!ad || !max || !min) return 0; /* validate parameters */
*max = (double)LLONG_MIN; /* initialize max/min to sufficiently */
*min = (double)LLONG_MAX; /* large negative/positive values. */
size_t i;
for (i = 0; i < n; i++) {
if (ad[i] > *max) *max = ad[i]; /* test for new max */
if (ad[i] < *min) *min = ad[i]; /* test for new min */
}
return 1;
}
(note: if your data values are outside the range of LLONG_MIN and LLONG_MAX, you will need to adjust your initializations accordingly)
A short example program reading values from the filename given as the first argument (or from stdin by default) and writing the array values and maximum and minimum to stdout could be written as:
Copy#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
enum { MAXD = 10 }; /* constant for no. of values */
int maxmin_dbl (double *ad, double *max, double *min, size_t n);
int main (int argc, char **argv) {
size_t i, n;
double max, min, tmp, ad[MAXD] = {0.0};
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
if (!fp) { /* validate file open for reading */
fprintf (stderr, "error: file open failed '%s'.\n", argv[1]);
return 1;
}
/* read double values from fp until at most 10 values read */
for (n = 0; n < MAXD && fscanf (fp, " %lf", &tmp) == 1; n++)
ad[n] = tmp;
if (fp != stdin) fclose (fp); /* close file if not stdin */
printf ("\narray values:\n\n"); /* output the values read */
for (i = 0; i < n; i++)
printf (" ad[%2zu] : %13.2lf\n", i, ad[i]);
if (maxmin_dbl (ad, &max, &min, n)) /* get max/min from array */
printf ("\n maximum : %.2lf\n minimum : %.2lf\n\n", max, min);
else {
fprintf (stderr, "error: maxmin_dbl failed.\n");
return 1;
}
return 0;
}
/** find the max and min in array of 'n' doubles `ad`.
* update 'max' and 'min' pointers so values are available back
* in calling function.
*/
int maxmin_dbl (double *ad, double *max, double *min, size_t n)
{
if (!ad || !max || !min) return 0; /* validate parameters */
*max = (double)LLONG_MIN; /* initialize max/min to sufficiently */
*min = (double)LLONG_MAX; /* large negative/positive values. */
size_t i;
for (i = 0; i < n; i++) {
if (ad[i] > *max) *max = ad[i]; /* test for new max */
if (ad[i] < *min) *min = ad[i]; /* test for new min */
}
return 1;
}
Example Use/Output
Copy$ ./bin/arrdbl_maxmin <../dat/10int_nl.txt
array values:
ad[ 0] : 8572.00
ad[ 1] : -2213.00
ad[ 2] : 6434.00
ad[ 3] : 16330.00
ad[ 4] : 3034.00
ad[ 5] : 12346.00
ad[ 6] : 4855.00
ad[ 7] : 16985.00
ad[ 8] : 11250.00
ad[ 9] : 1495.00
maximum : 16985.00
minimum : -2213.00
Look over all the answers, those that directly address your error, and then let us know if you have any further questions.
Hi everyone,
I'm trying to find the maximum and minimum values in a C array, but I'm running into a problem. My code calculates the maximum value correctly, but the minimum value is always a very large negative number, even when all the values in the array are positive.
I've tried initializing the min variable to a large positive number, but it doesn't seem to help.
Here's my code:
#include <stdio.h>
int main(void)
{
int i, sum = 0;
int numbers [5];
int min, max, average;
printf("enter 5 numbers:\n");
for (i = 0; i < 5; i++)
{
scanf("%d", &numbers[i]);
sum += numbers[i];
}
max = numbers[i];
min = numbers[i];
for (i = 0; i < 5 ; i++)
{
if (numbers[i] > max)
{
max = numbers[i];
}
if (numbers[i] < min)
{
min = numbers[i];
}
}
average = (double)sum/5;
printf("Average is %d and sum is %d\n", average, sum);
printf("Max number is %d and the min number is %d\n", max, min);
}Can anyone help me figure out what's going wrong?
Thanks!
It's not quite the best. There's some things IMHO that is hindering its performance and usefulness.
There's no point in declaring val as a static variable. In fact, you've killed any chance of it being usable in multi-threaded programs.
The body of the loop is performing an assignment in every single iteration when it doesn't need to. If you want it to be its best, you should only be doing so when it is required.
Your overall structure is fine, assuming we can expect well-formed inputs where array is nonempty and size is positive, I'd just change it so it's more like this:
double min(const double *arr, size_t length) {
// returns the minimum value of array
size_t i;
double minimum = arr[0];
for (i = 1; i < length; ++i) {
if (minimum > arr[i]) {
minimum = arr[i];
}
}
return minimum;
}
You can use SSE2/SSE3 minps / pminsd or relevant instruction set for your processor/architectoure since it is supported directly in GCC / MASM / TASM (In case MASM or TASM is not supported such SSE2/SSE3 instruction set there are also the .inc files to create macros simulating instruction sets on the web for MASM), create .OBJ file by your favorite linker then link it as usual and use in you favorite IDE. You will get from 4x to 16x performance boost compared to the traditional "classic" algorithm. It depend on data size (old compilers treats double not in IEEE format, bout like float in several configurations, on 16x systems, particularly, double means 32 bit data structure, not 64 bit data structure, in modern languages it is correlated to "double" and "long double" data structures, respectively)
The idea is simple: if you have k elements, [k=4n+p, 4>p=>0], complete it with n-p elements or just load last 4 doubles resetting to 0 last p elements, so you can fast evaluate n candidates. evaluate candidates n times comparing to the accumulator, you will get a minimum.
If your processor supports SSE5 or is a brand new, most likely you also will be using one of the HD instructions, which really handy, because it can find maximum (not minimum yet) in array of double values.
Sample of using SSE to calculate peak values of a float array:
#include <xmmintrin.h>
double min(double* array, int size) {
// returns the minimum value of array
int i;
double val = array[0];
for (i = 1; i < size; ++i) {
if (val > array[i]) {
val = array[i];
}
}
return val;
}
#define ARRAY_SIZE 16
float m_fArray[ARRAY_SIZE];
void x86_sse_find_peaks(float *buf, unsigned nframes, float *min, float *max)
{
__m128 current_max, current_min, work;
// Load max and min values into all four slots of the XMM registers
current_min = _mm_set1_ps(*min);
current_max = _mm_set1_ps(*max);
// Work input until "buf" reaches 16 byte alignment
while ( ((unsigned long)buf) % 16 != 0 && nframes > 0) {
// Load the next float into the work buffer
work = _mm_set1_ps(*buf);
current_min = _mm_min_ps(current_min, work);
current_max = _mm_max_ps(current_max, work);
buf++;
nframes--;
}
// use 64 byte prefetch for quadruple quads
while (nframes >= 16) {
//__builtin_prefetch(buf+64,0,0); // for GCC 4.3.2+
work = _mm_load_ps(buf);
current_min = _mm_min_ps(current_min, work);
current_max = _mm_max_ps(current_max, work);
buf+=4;
work = _mm_load_ps(buf);
current_min = _mm_min_ps(current_min, work);
current_max = _mm_max_ps(current_max, work);
buf+=4;
work = _mm_load_ps(buf);
current_min = _mm_min_ps(current_min, work);
current_max = _mm_max_ps(current_max, work);
buf+=4;
work = _mm_load_ps(buf);
current_min = _mm_min_ps(current_min, work);
current_max = _mm_max_ps(current_max, work);
buf+=4;
nframes-=16;
}
// work through aligned buffers
while (nframes >= 4) {
work = _mm_load_ps(buf);
current_min = _mm_min_ps(current_min, work);
current_max = _mm_max_ps(current_max, work);
buf+=4;
nframes-=4;
}
// work through the rest < 4 samples
while ( nframes > 0) {
// Load the next float into the work buffer
work = _mm_set1_ps(*buf);
current_min = _mm_min_ps(current_min, work);
current_max = _mm_max_ps(current_max, work);
buf++;
nframes--;
}
// Find min & max value in current_max through shuffle tricks
work = current_min;
work = _mm_shuffle_ps(work, work, _MM_SHUFFLE(2, 3, 0, 1));
work = _mm_min_ps (work, current_min);
current_min = work;
work = _mm_shuffle_ps(work, work, _MM_SHUFFLE(1, 0, 3, 2));
work = _mm_min_ps (work, current_min);
_mm_store_ss(min, work);
work = current_max;
work = _mm_shuffle_ps(work, work, _MM_SHUFFLE(2, 3, 0, 1));
work = _mm_max_ps (work, current_max);
current_max = work;
work = _mm_shuffle_ps(work, work, _MM_SHUFFLE(1, 0, 3, 2));
work = _mm_max_ps (work, current_max);
_mm_store_ss(max, work);
}
int _tmain(int argc, _TCHAR* argv[])
{
float min = FLT_MAX;
float max = FLT_MIN;
m_fArray[0] = 0;
m_fArray[1] = 1;
m_fArray[2] = 2;
m_fArray[3] = 3;
m_fArray[4] = 4;
m_fArray[5] = 3;
m_fArray[6] = 2;
m_fArray[7] = 1;
m_fArray[8] = -1;
m_fArray[9] = -2;
m_fArray[10] = -3;
m_fArray[11] = -4;
m_fArray[12] = -5;
m_fArray[13] = -6;
m_fArray[14] = -7;
m_fArray[15] = -8;
x86_sse_find_peaks(m_fArray, ARRAY_SIZE, &min, &max);
printf("value = %.2f, max = %.2f\n", min, max); // output is: value = -8.00, max = 4.00
return 0;
}