首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在结果范围最小的C中将uint转换为int

如何在结果范围最小的C中将uint转换为int
EN

Stack Overflow用户
提问于 2019-11-05 22:37:03
回答 1查看 598关注 0票数 6

我想要两个无界整数之间的区别,每个都由一个uint32_t值表示,这个值是取模2^32的无界整数。例如,TCP序列号。注意,与more restricted questions that do not allow wrapping around 0不同,模2^32表示可以环绕在0左右。

假设基础无界整数之间的差异在正常int的范围内。我要这个有符号的差额值。换句话说,返回一个在正常int范围内的值,该值等于两个uint32_t输入模2^32的差值。

例如,0 - 0xffffffff = 1,因为我们假设底层无界整数在int范围内。证明:如果A mod 2^32 =0,B mod 2^32 =0 0xffffffff,则(A=0,B=-1) (mod 2^32),因此(A-B=1) (mod 2^32),在int范围内,该模类具有单一代表的1

我使用了以下代码:

代码语言:javascript
复制
static inline int sub_tcp_sn(uint32_t a, uint32_t b)
{
    uint32_t delta = a - b;

    // this would work on most systems
    return delta;

    // what is the language-safe way to do this?
}

这在大多数系统上都是有效的,因为它们对uintint都使用模2^32表示,而普通的模2^32减法是在这里生成的唯一合理的汇编代码。

但是,我认为C标准只在delta>=0中定义了上述代码的结果。例如,在this question上,有一个回答说:

如果我们将一个超出范围的值赋值给一个有符号类型的对象,则结果是未定义的.程序看起来可能工作,它可能崩溃,或者它可能产生垃圾值。

如何按照C标准实现从uintint的模-2^32转换?

注意:我希望答案代码不包含条件表达式,除非你能证明它是必需的。(代码解释中的案例分析是可以的)。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-11-05 23:35:51

一定有一个标准的函数来做这个..。但与此同时:

代码语言:javascript
复制
#include <stdint.h>  // uint32_t
#include <limits.h>  // INT_MAX
#include <assert.h>  // assert

static inline int sub_tcp_sn(uint32_t a, uint32_t b)
{
    uint32_t delta = a - b;
    return delta <= INT_MAX ? delta : -(int)~delta - 1;
}

请注意,在这种情况下,结果是不可表示的,但问题是,这是可以的。

如果系统具有64位long long类型,那么范围也可以很容易地进行定制和检查:

代码语言:javascript
复制
typedef long long sint64_t;

static inline sint64_t sub_tcp_sn_custom_range(uint32_t a, uint32_t b,
                             sint64_t out_min, sint64_t out_max)
{
    assert(sizeof(sint64_t) == 8);
    uint32_t delta = a - b;
    sint64_t result = delta <= out_max ? delta : -(sint64_t)-delta;
    assert(result >= out_min && result <= out_max);
    return result;
}

例如,sub_tcp_sn_custom_range(0x10000000, 0, -0xf0000000LL, 0x0fffffffLL) == -0xf00000000

使用范围自定义,该解决方案在所有情况下都将范围损失降到最低,假设时间戳的行为是线性的(例如,在0周围没有特殊意义),并且可以使用被签名的64位类型。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58720505

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档