gpt4 book ai didi

C:找到算术表达式类型的最大值和最小值

转载 作者:太空狗 更新时间:2023-10-29 17:24:31 26 4
gpt4 key购买 nike

我需要找到一个没有副作用的任意 C 表达式的最大值和最小值。以下宏在我的机器上工作。他们会在所有平台上工作吗?如果没有,是否可以对其进行修改以使其正常工作?我的意图是随后使用它们来实现宏,如 SAFE_MUL(a,b) 代替 a*bSAFE_MUL 将包括对乘法溢出的检查。

编辑:类型按照史蒂夫的建议进行转换。

#include <stdio.h>
#include <limits.h>

#define IS_SIGNED(exp) (((exp)*0-1) < 0)

#define TYPE_MAX_UNSIGNED(exp) ((exp)*0-1)

#define TYPE_MAX_SIGNED(exp) ( \
sizeof (exp) == sizeof (int) \
? \
INT_MAX \
: \
( \
sizeof (exp) == sizeof (long) \
? \
LONG_MAX \
: \
LLONG_MAX \
) \
)

#define TYPE_MAX(exp) ((unsigned long long)( \
IS_SIGNED (exp) \
? \
TYPE_MAX_SIGNED (exp) \
: \
TYPE_MAX_UNSIGNED (exp) \
))

#define TYPE_MIN_SIGNED(exp) ( \
sizeof (exp) == sizeof (int) \
? \
INT_MIN \
: \
( \
sizeof (exp) == sizeof (long) \
? \
LONG_MIN \
: \
LLONG_MIN \
) \
)

#define TYPE_MIN(exp) ((long long)( \
IS_SIGNED (exp) \
? \
TYPE_MIN_SIGNED (exp) \
: \
(exp)*0 \
))

int
main (void) {

printf ("TYPE_MAX (1 + 1) = %lld\n", TYPE_MAX (1 + 1));
printf ("TYPE_MAX (1 + 1L) = %lld\n", TYPE_MAX (1 + 1L));
printf ("TYPE_MAX (1 + 1LL) = %lld\n", TYPE_MAX (1 + 1LL));
printf ("TYPE_MAX (1 + 1U) = %llu\n", TYPE_MAX (1 + 1U));
printf ("TYPE_MAX (1 + 1UL) = %llu\n", TYPE_MAX (1 + 1UL));
printf ("TYPE_MAX (1 + 1ULL) = %llu\n", TYPE_MAX (1 + 1ULL));
printf ("TYPE_MIN (1 + 1) = %lld\n", TYPE_MIN (1 + 1));
printf ("TYPE_MIN (1 + 1L) = %lld\n", TYPE_MIN (1 + 1L));
printf ("TYPE_MIN (1 + 1LL) = %lld\n", TYPE_MIN (1 + 1LL));
printf ("TYPE_MIN (1 + 1U) = %llu\n", TYPE_MIN (1 + 1U));
printf ("TYPE_MIN (1 + 1UL) = %llu\n", TYPE_MIN (1 + 1UL));
printf ("TYPE_MIN (1 + 1ULL) = %llu\n", TYPE_MIN (1 + 1ULL));
return 0;
}

最佳答案

  • IS_SIGNED对于小于 int 的无符号类型,宏不会说实话. IS_SIGNED((unsigned char)1)在任何正常的实现中都是正确的,因为 (unsigned char)1*0 的类型是int , 不是 unsigned char .

您最终的 SAFE宏仍然应该说出是否发生溢出的真相,因为相同的整数提升适用于所有算术。但它们会告诉您乘法是否发生溢出,不一定当用户将结果转换回其中一个操作数的原始类型时是否一定会发生溢出。

不过想想看,您可能已经知道了,因为您的宏不会尝试建议 CHAR_MIN等等。但是以后发现这个问题的其他人可能没有意识到这个限制。

  • 没有一种类型可以保证能够容纳 TYPE_MIN 的所有值。和 TYPE_MAX可以评价到。但是你可以制作TYPE_MAX始终评估为 unsigned long long (并且该值始终适合该类型),与 TYPE_MIN 相同和 signed long long .这将允许您使用正确的 printf 格式,而无需使用您对表达式是否已签名的了解。目前TYPE_MAX(1)long long ,而 TYPE_MAX(1ULL)是一个 unsigned long long .

  • 技术上允许 intlong由于long,具有相同的大小但不同的范围填充位少于 int .不过,我怀疑是否有任何重要的实现能做到这一点。

关于C:找到算术表达式类型的最大值和最小值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7955285/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com