How would you define a simple “min” method in obj-c

前端 未结 7 2210
感动是毒
感动是毒 2020-12-16 11:42

I want to define a min and max methods in a Utils class.

@interface Utils

int min(int a, int b);
int max(int a, int b);

@end

But I don\'t

相关标签:
7条回答
  • 2020-12-16 12:03

    Here is a macro I created for multi-max and multi-min which allows more than just 2 inputs.

    float a = MMAX(1,2,9.33,2.5); //a = 9.33

    The internal mechanisms use long double and you'll just cast the output to whatever variable you're using. I'd prefer a solution using typeof but couldn't figure out how to do it on __VA_ARGS__ on a per argument basis, maybe someone more versed than me in C can figure it out and comment? Anyways, here's the macro definition:


    #define MMAX(...) ({\
    long double __inputs[(sizeof((long double[]){__VA_ARGS__})/sizeof(long double))] = {__VA_ARGS__};\
    long double __maxValue = __inputs[0];\
    for (int __i = 0; __i < (sizeof((long double[]){__VA_ARGS__})/sizeof(long double)); ++__i) {\
    long double __inputValue = __inputs[__i];\
    __maxValue = __maxValue>__inputValue?__maxValue:__inputValue;\
    }\
    __maxValue;\
    })
    
    #define MMIN(...) ({\
    long double __inputs[(sizeof((long double[]){__VA_ARGS__})/sizeof(long double))] = {__VA_ARGS__};\
    long double __minValue = __inputs[0];\
    for (int __i = 0; __i < (sizeof((long double[]){__VA_ARGS__})/sizeof(long double)); ++__i) {\
    long double __inputValue = __inputs[__i];\
    __minValue = __minValue<__inputValue?__minValue:__inputValue;\
    }\
    __minValue;\
    })
    
    0 讨论(0)
  • 2020-12-16 12:07

    Since you aren't using the OS X Implementation of objective-c, you may not have access to the predefined MIN and MAX macros.

    You can define these yourself as

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

    There is probably a better way to define them, but these will create the simple macros for your use. You can add them into any common .h file that your classes normally share.

    0 讨论(0)
  • 2020-12-16 12:12

    There's a serious issue with the solution posted by Brandon Bodnár (which by the time of this writing is marked as a valid solution).

    Issue described here: http://gcc.gnu.org/onlinedocs/gcc-3.4.6/gcc/Min-and-Max.html And the (valid & secure) solution to it: http://gcc.gnu.org/onlinedocs/gcc-3.4.6/gcc/Typeof.html

    Check it out yourself:

    #include <stdio.h>
    
    #define NAIVE_MAX(a,b) (a > b ? a : b)
    
    #define NAIVE_MIN(a,b) (a < b ? a : b)
    
    #if !defined MAX
    #define MAX(a,b) \
    ({ __typeof__ (a) __a = (a); \
    __typeof__ (b) __b = (b); \
    __a > __b ? __a : __b; })
    #endif
    
    #if !defined MIN
    #define MIN(a,b) \
    ({ __typeof__ (a) __a = (a); \
    __typeof__ (b) __b = (b); \
    __a < __b ? __a : __b; })
    #endif
    
    int main (int argc, const char * argv[]) {
        int a = 3;
        int b = 5;
    
    #pragma mark NON-FATAL CASES:
        printf("NAIVE_MAX(%d, %d) => %d\n", a, b, NAIVE_MAX(a, b));
        printf("NAIVE_MIN(%d, %d) => %d\n", a, b, NAIVE_MIN(a, b));
    
        printf("MAX(%d, %d) => %d\n", a, b, MAX(a, b));
        printf("MIN(%d, %d) => %d\n", a, b, MIN(a, b));
    
        printf("\nEverything fine so far...\n\n");
    
    #pragma mark FATAL CASES:
        //cache:
        int _a = a;
        int _b = b;
        printf("NAIVE_MAX(%d++, %d++) => %d\n", _a, _b, NAIVE_MAX(a++, b++));
    
        //reset:
        a = _a;
        b = _b;
        printf("NAIVE_MIN(%d++, %d++) => %d\n", _a, _b, NAIVE_MIN(a++, b++));
    
        //reset:
        a = _a;
        b = _b;
        printf("NAIVE_MAX(++%d, ++%d) => %d\n", _a, _b, NAIVE_MAX(++a, ++b));
    
        //reset:
        a = _a;
        b = _b;
        printf("NAIVE_MIN(++%d, ++%d) => %d\n", _a, _b, NAIVE_MIN(++a, ++b));
    
        printf("\nOuch, this doesn't look right at all!\n\n");
    
    #pragma mark NON-FATAL CASES:
        //reset:
        a = _a;
        b = _b;
        printf("MAX(%d++, %d++) => %d\n", _a, _b, MAX(a++, b++));
    
        //reset:
        a = _a;
        b = _b;
        printf("MIN(%d++, %d++) => %d\n", _a, _b, MIN(a++, b++));
    
        //reset:
        a = _a;
        b = _b;
        printf("MAX(++%d, ++%d) => %d\n", _a, _b, MAX(++a, ++b));
    
        //reset:
        a = _a;
        b = _b;
        printf("MIN(++%d, ++%d) => %d\n", _a, _b, MIN(++a, ++b));
    
        printf("\nAh, much better now.\n\n");
    
        return 0;
    }
    

    Console log:

    NAIVE_MAX(3, 5) => 5
    NAIVE_MIN(3, 5) => 3
    MAX(3, 5) => 5
    MIN(3, 5) => 3
    
    Everything fine so far...
    
    NAIVE_MAX(3++, 5++) => 6
    NAIVE_MIN(3++, 5++) => 4
    NAIVE_MAX(++3, ++5) => 7
    NAIVE_MIN(++3, ++5) => 5
    
    Ouch, this doesn't look right at all!
    
    MAX(3++, 5++) => 5
    MIN(3++, 5++) => 3
    MAX(++3, ++5) => 6
    MIN(++3, ++5) => 4
    
    Ah, much better now.
    

    So never ever use the naive implementation as seen in the code above (and as suggested by Brandon Bodnár, sorry buddy ;) ) if you want to avoid worst cases like these.

    0 讨论(0)
  • 2020-12-16 12:18

    In a template file named "XXIntegerMath.h" drop this...

    #import <Foundation/Foundation.h>
    
    static inline NSInteger imax(NSInteger a, NSInteger b) {
        return  a > b ? a : b;
    }
    
    static inline NSInteger imin(NSInteger a, NSInteger b) {
        return  a < b ? a : b;
    }
    

    Then in your objective-c class ...

    #import "XXIntegerMath.h"
    NSInteger minValue = imin(someValue, someOtherValue);
    

    It doesn't suffer from the problems described by Regexident.

    0 讨论(0)
  • 2020-12-16 12:20

    It is already defined as a macro.

    MIN(a, b)
    
    MAX(a, b)
    

    You dont need to redefine these ones.

    0 讨论(0)
  • 2020-12-16 12:21

    This is probably not a good idea for this particular application, but it is possible to write Objective-C methods with parameters “without names”, or rather with zero-length names:

    + min:(int)a :(int)b;
    ...
    [Utils min:a :b]
    

    (The selector would be @selector(min::).)

    0 讨论(0)
提交回复
热议问题