如何在不损失结果范围的情况下将C中的uint转换为int

personal_cloud

我想要两个无界整数之间的差异,每个整数都由一个uint32_t表示,该值是取2 ^ 32为模的无界整数。如,例如,TCP序列号。请注意,模2 ^ 32表示形式可以环绕0,这与不允许绕0环绕的更严格的问题不同

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

例如,0 - 0xffffffff = 1因为我们假设基础无界整数在int范围内。证明:如果A mod 2 ^ 32 = 0且B mod 2 ^ 32 = 0xffffffff,则(A = 0,B = -1)(mod 2 ^ 32)因此(AB = 1)(mod 2 ^ 32)和在int此模级范围内,具有单个代表1

我使用了以下代码:

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

这在大多数系统上都有效,因为它们对uint都使用modulo-2 ^ 32表示形式int,并且正常的modulo-2 ^ 32减法是在此处生成的唯一合理的汇编代码。

但是,我相信C标准仅在的情况下定义上述代码的结果delta>=0例如关于这个问题的一个答案说:

如果将超出范围的值分配给带符号类型的对象,则结果不确定。该程序似乎可以运行,崩溃或可能产生垃圾值。

应该如何从模2 ^ 32转换uintint根据C标准做什么?

注意:我希望答案代码不包含条件表达式,除非您可以证明它是必需的。(在代码说明中进行案例分析就可以了)。

personal_cloud

必须有一个执行此操作的标准函数...但与此同时:

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

请注意,如果结果无法表示,则为UB,但问题是可以的。

如果系统具有64位long long类型,则范围也可以轻松自定义和检查:

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位类型。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何在不损失透明度的情况下将图像转换为灰度?

如何在不损失R精度的情况下将因子转换为浮点数?

如何在不损失透明度的情况下将PNG图像转换为灰度C#

如何在不丢失C#中的数字值的情况下将int数字转换为char

如何在不使用幻数的情况下将“字符数”转换为int?(在C ++中)

如何在不损失质量的情况下将10位H.265视频转换为H.264?

如何在不损失质量的情况下将MOD视频文件转换为电视的现代流行格式

如何在不损失效率的情况下将此代码转换为1线性代码?

如何在不增加OverflowError:Python int太大而无法转换为C long的情况下,将数组中的每个元素与大量相乘?

如何在不获取NA的情况下将R中的因子转换为日期?

如何在不违反C ++核心准则的情况下将整数转换为void *?

如何在不复制的情况下将Int32Array转换为Uint8Array

如何在不使用to_string或stoi的情况下将int转换为C ++ 11中的字符串?

如何在不循环元素的情况下将int数组转换为可为null的int数组?

如何在不转换为int的情况下获得字节字符串中的单个字节

在不损失精度的情况下将 NumPy 浮点数转换为整数

在 Google 表格中,如何在不破坏文本的情况下将数字转换为数组中的值?

如何在不使用 for 循环的情况下将 List(Int) 转换为 Int

如何在不创建临时表的情况下将 SQL SERVER 中的行转换为列

如何在不增加数据大小的情况下将熊猫中的分类变量转换为数值?

ncdump - 如何在不包含 nodata 值的情况下将 .nc 转换为文本?

如何在不创建对象的情况下将Java类转换为json格式结构

如何在不循环的情况下将python JSON行转换为dataframe列

如何在不编写中间HTML文件的情况下将Markdown转换为PDF?

如何在不丢失数据的情况下将MBR分区转换为GPT?

如何在不转换为datetime的情况下将“ Ticks”截断毫秒数?

如何在不嵌套特定标签的情况下将EditText转换为html

如何在不丢失列的情况下将列(类别类型)转换为列?

如何在不丢失前导零的情况下将String转换为Long