396 Stimmen

MIN und MAX in C

Wo sind MIN y MAX in C definiert, wenn überhaupt?

Wie lassen sich diese am besten implementieren, und zwar so generisch und typsicher wie möglich? (Compiler-Erweiterungen/Builtins für Mainstream-Compiler bevorzugt.)

24voto

dreamlax Punkte 91447

Ich glaube nicht, dass es sich um standardisierte Makros handelt. Es gibt bereits standardisierte Funktionen für Fließkommazahlen, fmax y fmin (und fmaxf für Schwimmer, und fmaxl für lange Doppelgänger).

Sie können sie als Makros implementieren, solange Sie sich der Problematik der Nebeneffekte/Doppelbewertung bewusst sind.

#define MAX(a,b) ((a) > (b) ? a : b)
#define MIN(a,b) ((a) < (b) ? a : b)

In den meisten Fällen können Sie es dem Compiler überlassen, zu bestimmen, was Sie tun wollen, und es so gut wie möglich zu optimieren. Dies verursacht zwar Probleme, wenn es wie MAX(i++, j++) Ich bezweifle, dass es jemals notwendig sein wird, das Maximum der inkrementierten Werte in einem Durchgang zu überprüfen. Erst inkrementieren, dann prüfen.

11voto

Matt Joiner Punkte 105454

Ich schrieb dies Version die für MSVC, GCC, C und C++ funktioniert.

#if defined(__cplusplus) && !defined(__GNUC__)
#   include <algorithm>
#   define MIN std::min
#   define MAX std::max
//#   define TMIN(T, a, b) std::min<T>(a, b)
//#   define TMAX(T, a, b) std::max<T>(a, b)
#else
#       define _CHOOSE2(binoper, lexpr, lvar, rexpr, rvar) \
                ({ \
                        decltype(lexpr) lvar = (lexpr); \
                        decltype(rexpr) rvar = (rexpr); \
                        lvar binoper rvar ? lvar : rvar; \
                })
#       define _CHOOSE_VAR2(prefix, unique) prefix##unique
#       define _CHOOSE_VAR(prefix, unique) _CHOOSE_VAR2(prefix, unique)
#       define _CHOOSE(binoper, lexpr, rexpr) \
                _CHOOSE2( \
                        binoper, \
                        lexpr, _CHOOSE_VAR(_left, __COUNTER__), \
                        rexpr, _CHOOSE_VAR(_right, __COUNTER__) \
                )
#       define MIN(a, b) _CHOOSE(<, a, b)
#       define MAX(a, b) _CHOOSE(>, a, b)
#endif

8voto

cib Punkte 1874

Wenn Sie min/max benötigen, um eine teure Verzweigung zu vermeiden, sollten Sie den ternären Operator nicht verwenden, da er zu einem Sprung kompiliert wird. Der folgende Link beschreibt eine nützliche Methode zur Implementierung einer min/max-Funktion ohne Verzweigung.

http://graphics.stanford.edu/~seander/bithacks.html#GanzzahlMinOrMax

5voto

rogerdpack Punkte 55995

Sieht aus wie Windef.h (a la #include <windows.h> ) hat max y min (Kleinbuchstaben) Makros, die auch unter der Schwierigkeit der "doppelten Bewertung" leiden, aber sie sind für diejenigen da, die ihre eigenen nicht neu würfeln wollen :)

5voto

Z boson Punkte 31066

Ich denke, es ist erwähnenswert, dass, wenn man den Begriff min y max mit der ternären Operation wie

#define MIN(a,b) (((a)<(b))?(a):(b))
#define MAX(a,b) (((a)>(b))?(a):(b))

um dann das gleiche Ergebnis für den Sonderfall von fmin(-0.0,0.0) y fmax(-0.0,0.0) müssen Sie die Argumente vertauschen

fmax(a,b) = MAX(a,b)
fmin(a,b) = MIN(b,a)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X