Use of Min and Max Functions in C++

MIN and MAX in C

Where are MIN and MAX defined in C, if at all?

They aren't.

What is the best way to implement these, as generically and type safe as possible (compiler extensions/builtins for mainstream compilers preferred).

As functions. I wouldn't use macros like #define MIN(X, Y) (((X) < (Y)) ? (X) : (Y)), especially if you plan to deploy your code. Either write your own, use something like standard fmax or fmin, or fix the macro using GCC's typeof (you get typesafety bonus too) in a GCC statement expression:

 #define max(a,b) \
({ __typeof__ (a) _a = (a); \
__typeof__ (b) _b = (b); \
_a > _b ? _a : _b; })

Everyone says "oh I know about double evaluation, it's no problem" and a few months down the road, you'll be debugging the silliest problems for hours on end.

Note the use of __typeof__ instead of typeof:

If you are writing a header file that
must work when included in ISO C
programs, write __typeof__ instead of
typeof.

Use of min and max functions in C++

fmin and fmax are specifically for use with floating point numbers (hence the "f"). If you use it for ints, you may suffer performance or precision losses due to conversion, function call overhead, etc. depending on your compiler/platform.

std::min and std::max are template functions (defined in header <algorithm>) which work on any type with a less-than (<) operator, so they can operate on any data type that allows such a comparison. You can also provide your own comparison function if you don't want it to work off <.

This is safer since you have to explicitly convert arguments to match when they have different types. The compiler won't let you accidentally convert a 64-bit int into a 64-bit float, for example. This reason alone should make the templates your default choice. (Credit to Matthieu M & bk1e)

Even when used with floats the template may win in performance. A compiler always has the option of inlining calls to template functions since the source code is part of the compilation unit. Sometimes it's impossible to inline a call to a library function, on the other hand (shared libraries, absence of link-time optimization, etc.).

Using functions to determine min or max

#include <stdio.h>
//variables for the functions
void MinMax(double a, double* max, double* min);

//main program
int main() {
double num = 0;
double min = 0;
double max = 0;

printf("Enter a real number: ");
scanf("%lf",&num);

//To exit the loop and avoid undefined behaviour
while (num != -999) {
MinMax(num, &max, &min);
printf("Enter a real number: ");
scanf("%lf",&num);
}

return 0;
}

void MinMax (double a, double* max, double* min) {
if (a > *max)
*max = a;

if (a < *min)
*min = a;

printf("The max is %lf and the min is %lf\n", *max, *min);
}

You may also choose to use:

static double max = 0, min = 0; 

This would go on top of the MinMax function, but the best way to go about your problem is to use pointers to pass by reference. As demonstrated above:

void MinMax(double a, double* min, double* max)

Note: C uses * in prototype not &.

Happy coding.

Is max(a,b) defined in stdlib.h or not?

Any C library which defines a macro named max in its standard headers is broken beyond imagination. Fortunately, an easy workaround if you need to support such platforms is to #undef max (and any other problematic macros it defines) after including the system headers and before any of your own headers/code.

Note that everyone else is saying to wrap your definition in #ifndef max ... #endif. This is not a good idea. Defining max in a system header is an indication that the implementor was incompetent, and it's possible that certain versions of the environment have incorrect macros (for example, ones which do not properly protect arguments with parentheses, but I've even seen a max macro that was incorrectly performing min instead of max at least once in my life!). Just use #undef and be safe.

As for why it's so broken for stdlib.h to define max, the C standard is very specific about what names are reserved for the application and what names are reserved for standard functions and/or internal use by the implementation. There are very good reasons for this. Defining macro names in system headers that could clash with variable/function names used in the application program is dangerous. In the best case it leads to compile-time errors with an obvious cause, but in other cases it can cause very strange behavior that's hard to debug. In any case it makes it very difficult to write portable code because you never know what names will already be taken by the library.

C minimum/maximum function

So it seems there is not such standard function, so here is my solution:


For minimum:

 void* get_min(void* start,size_t size,size_t elementSize,int (*compare)(const void *, const void*))
{
char* minObject = start;
for(int i = elementSize;i<size*elementSize;i+=elementSize){
char* object = start+i;
if(compare(object,minObject)<0){
minObject = object;
}
}
return minObject;
}


and for maximum:

void* get_max(void* start,size_t size,size_t elementSize,int (*compare)(const void *, const void*))
{
char* maxObject = start;
for(int i = elementSize;i<elementSize*size;i+=elementSize){
char* object = start+i;
if(compare(object,maxObject)>0){
maxObject = object;
}
}
return maxObject;
}

Use 'if' to find maximum and minimum

Your max and min are set to 1 at the beginning but after the input, the value of a changes but max and min remain 1.

You can solve this by initializing the max and min after the scanf statement or you could just initialize max and min to INT_MAX and INT_MIN defined in limits.h as pointed out by Barak Manos.

#include <stdlib.h>
//Enter five numbers and find the maximum and minimum.
int main()
{
int a,b,c,d,e;
scanf("%d%d%d%d%d", &a, &b, &c, &d, &e);
int max = a, min = a;
....
....
}

Also, a simple version would be store all the input numbers in an array and call min and max on that array.



Related Topics



Leave a reply



Submit