简体   繁体   English

比较两个整数的通用函数?

[英]Generic function for comparing two integers?

Is there a fairly standard C (Linux) function, or a code-efficient but good-performing approach, for comparing two integers of an arbitrary size? 是否有一个相当标准的C(Linux)函数,或者一个代码有效但性能良好的方法,用于比较任意大小的两个整数?

I'm looking for something with the parameters int intcmp(const void *a, const void *b, size_t size) that works on integers a and b for any practical size size . 我正在寻找具有参数int intcmp(const void *a, const void *b, size_t size) ,它适用于任何实际尺寸size整数ab ( memcmp() would work (I think) if the architecture was big endian.) memcmp()可以工作(我认为),如果架构是大端。)

The implementation I tend to use goes like this (with improvements from Efficient integer compare function ) but it's not completely generic and has enough of a code overhead that I generally think twice before slotting it in. 我倾向于使用的实现是这样的( 有效整数比较函数的改进),但它不是完全通用的,并且有足够的代码开销,我通常会在插入之前三思而后行。

int intcmp(const void *a, const void *b, size_t size) {

    #define CASE_SIZE_RETURN_A_B_CMP(_t) \
        case sizeof(_t): \
            return ((*(_t *)(a) > *(_t *)(b)) - (*(_t *)(a) < *(_t *)(b)))

    switch (size) {
    CASE_SIZE_RETURN_A_B_CMP(char);
    CASE_SIZE_RETURN_A_B_CMP(short);
    CASE_SIZE_RETURN_A_B_CMP(int);
    CASE_SIZE_RETURN_A_B_CMP(long long);
    }
    #undef CASE_SIZE_RETURN_A_B_CMP

    assert(0);
    return 0;
}

Static inline functions have the advantage of the arguments being evaluated only once (this is hard/impossible to do with macros) . 静态内联函数的优点是参数只被评估一次(这很难/不可能用于宏)。 This would allow function calls like int diff = cmp_all (p++, q++, sizeof *p); 这将允许函数调用,如int diff = cmp_all (p++, q++, sizeof *p); :

#include <stdlib.h>
#include <stdint.h>

static inline int cmp1(const int8_t *one, const int8_t *two)
{
if (*one < *two) return -1;
else if (*one > *two) return 1;
else return 0;
}

static inline int cmp2(const int16_t *one, const int16_t *two)
{
if (*one < *two) return -1;
else if (*one > *two) return 1;
else return 0;
}

static inline int cmp4(const int32_t *one, const int32_t *two)
{
if (*one < *two) return -1;
else if (*one > *two) return 1;
else return 0;
}

static inline int cmp8(const int64_t *one, const int64_t *two)
{
if (*one < *two) return -1;
else if (*one > *two) return 1;
else return 0;
}

int cmp_all(const void *one, const void *two, size_t size)
{
switch(size) {
case 1: return cmp1(one, two);
case 2: return cmp2(one, two);
case 4: return cmp4(one, two);
case 8: return cmp8(one, two);
default: return 0; /* that will teach them ... */
        }
}

If you really need to good performing comparation of integers of arbitrary sizes I recommend you look at The GNU Multiple Precision Arithmetic Library . 如果你真的需要对任意大小的整数进行良好的比较,我建议你看一下GNU多精度算术库 That requires you to use it's special mpz_t type (which has the length included). 这需要你使用它的特殊mpz_t类型(包括长度)。 Then you can use the function int mpz_cmp(mpz_t op1, mpz_t op2) . 然后你可以使用函数int mpz_cmp(mpz_t op1, mpz_t op2) Deciding on your own representation of big integers and implement it in way that is both fairly portable and efficient is not trivial. 决定你自己的大整数表示并以相当便携和高效的方式实现它并非易事。

If, on the other hand, you just need the standard integer sizes you mention I think your implementation is fine. 另一方面,如果你只需要标准的整数大小,我认为你的实现很好。 But for even better portability you shouldn't make assumptions on the various integer sizes: 但是为了更好的可移植性,你不应该对各种整数大小做出假设:

#include <stdint.h>

int intcmp(const void *a, const void *b, size_t size) {
    switch (size) {
    case 1: return (*(int8_t*)a > *(int8_t*)b) - (*(int8_t*)a < *(int8_t*)b)
    case 2: return (*(int16_t*)a > *(int16_t*)b) - (*(int16_t*)a < *(int16_t*)b)
    case 4: return (*(int32_t*)a > *(int32_t*)b) - (*(int32_t*)a < *(int32_t*)b)
    case 8: return (*(int64_t*)a > *(int64_t*)b) - (*(int64_t*)a < *(int64_t*)b)
    }

    assert(0);
    return 0;
}

Perhaps you'll find it better to create a separate function for each length you need instead of using the same for all? 也许你会发现为你需要的每个长度创建一个单独的函数更好,而不是为所有长度使用相同的函数? And finally, if efficiency is important, it is often less efficient to do arithmetics with char or short than with int . 最后,如果效率很重要,使用charshort而不是int进行算术运算通常效率较低。 So try to avoid the cases where you need to call this function with char or short and use int instead. 因此,请尽量避免需要使用char或short调用此函数并使用int的情况。

I think the following link will help. 我认为以下链接会有所帮助。 You make the comparison without using comparators keeping your code overhead down a bit. 您可以在不使用比较器的情况下进行比较,从而使代码开销保持一定程度。 I have made use of the code associated with this link myself in the past. 我过去曾使用过与此链接相关的代码。

-Good Hunting- - 好狩猎 -

C program to compare integers without using logical operators? C程序比较整数而不使用逻辑运算符?

如果调用站点具有可用的大小,我宁愿将其用作查找表中的索引,以便立即调用正确的函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM