当前位置: 首页 > 知识库问答 >
问题:

比较两个整数的泛型函数?

邢昊焜
2023-03-14

有没有一个相当标准的C(Linux)函数,或者一种代码高效但性能良好的方法来比较任意大小的两个整数?

我正在寻找一些参数为int intcmp(const void*a,const void*b,size\t size)的东西,它适用于任何实际大小的整数。(memcmp()如果架构是big-endian的话(我认为)可以工作。)

我倾向于使用这样的实现(通过高效整数比较函数的改进),但它不是完全通用的,并且有足够的代码开销,我通常在插入之前会三思而后行。

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;
}

共有3个答案

司徒元明
2023-03-14

我认为下面的链接会有所帮助。您可以在不使用比较器的情况下进行比较,从而降低代码开销。我过去也使用过与此链接相关的代码。

-很好的狩猎-

C程序在不使用逻辑运算符的情况下比较整数?

楚茂实
2023-03-14
匿名用户

如果您真的需要对任意大小的整数进行良好的比较,我建议您查看GNU多精度算术库。这要求您使用它的特殊mpz\U t类型(包括长度)。然后可以使用函数int mpz\u cmp(mpz\u t op1,mpz\u t op2)。决定自己的大整数表示并以可移植和高效的方式实现它并非易事。

另一方面,如果您只需要您提到的标准整数大小,我认为您的实现很好。但是为了更好的可移植性,您不应该对各种整数大小做出假设:

#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;
}

也许您会发现,最好为所需的每个长度创建一个单独的函数,而不是对所有长度都使用相同的函数?最后,如果效率很重要,那么使用char或short进行算术通常比使用int效率低。因此,尽量避免需要使用char或short调用此函数并使用int的情况。

刁浩言
2023-03-14

静态内联函数的优点是参数只被计算一次(这对于宏来说是很难/不可能的)。这将允许函数调用,例如int diff=cmp\u 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 ... */
        }
}

 类似资料:
  • 问题内容: 我必须比较两个对象(不是)。比较它们的规范方法是什么? 我可以想到: 该运营商只比较基准,因此这将仅适用于较低的整数值的工作。但是也许自动装箱开始了…? 这看起来像一个昂贵的操作。是否以此方式计算出哈希码? 有点冗长… 编辑: 谢谢您的答复。尽管我现在知道该怎么办,但事实已分布在所有现有答案(甚至是已删除的答案)上,我也不知道该接受哪个答案。因此,我将接受最佳答案,即所有三种比较可能性

  • 问题内容: 我正在尝试编写代码以比较两个数组。在第一个数组中,我输入了自己的数字,但是在第二个数组中,输入了输入文件中的数字。该数组的大小由文件中的第一个数字确定,而第一个数组的大小始终为10。两个数组以及数字的长度必须相同。 我的代码如下: 问题答案:

  • 比较三个整数变量是您可以轻松编写的最简单的程序之一。 在此程序中,您可以使用scanf()函数从用户获取输入,也可以在程序本身中静态定义。 我们希望它也是一个简单的程序。 我们将一个值与其余的两个值进行比较并检查结果,并对所有变量应用相同的过程。 对于此程序,所有值都应该是不同的(唯一的)。 算法 (Algorithm) 让我们首先看看比较三个整数的分步过程应该是什么 - START Ste

  • 比较两个整数变量是您可以轻松编写的最简单的程序之一。 在此程序中,您可以使用scanf()函数从用户获取输入,也可以在程序本身中静态定义。 我们希望它也是一个简单的程序。 我们只是比较两个整数变量。 我们首先看一下算法,然后是流程图,然后是伪代码和实现。 算法 (Algorithm) 让我们首先看看比较两个整数的分步过程应该是什么 - START Step 1 → Take two inte

  • 过滤出数组中比较函数不返回 true 的所有值。 类似于difference ,除了接受一个 comparator (比较函数)。 使用 Array.filter() 和 Array.findIndex() 来查找合适的值。 const differenceWith = (arr, val, comp) => arr.filter(a => val.findIndex(b => comp(a, b