c - 将 32 位值分配给 64 位变量并保证前 32 位在 C 中为 0 的最佳方法

标签 c casting type-conversion bit-manipulation

我有一些 C 代码,其中的变量要么是 int,要么在一段时间内转换为 int 以便于使用(我们关心的是位值)。在这种情况下,Int 将始终为 32 位。有一次,其中一些被分配给一个 64 位变量,一些是隐式的,一些是显式的:

long long 64bitfoo = 32bitbar;
long long 64bitfoo = (long long)32bitbar;

这在过去没有问题,但最近我遇到了这样的情况,经过这种转换后,64 位变量的前 32 位不为 0。似乎某些特定版本的事件或多或少可以填充垃圾的最高位(或者只是选择一个以前使用过的内存位置并且没有正确清除它)。这行不通,所以我正在寻找解决方案。

我显然可以做这样的事情:

long long 64bitfoo = 32bitbar;
64bitfoo &= ~0xFFFFFFFF00000000;

清除顶部位,这应该可以满足我的需要,但我觉得有更好的选择。到目前为止,这只出现在使用隐式转换的值上,所以我很好奇隐式转换和显式转换之间是否存在允许显式转换自行处理的区别?(不幸的是,我目前不能只添加显式转换并进行测试,触发它的条件很复杂且不易复制,因此代码更改需要非常坚定而不是猜测)。

我敢肯定还有其他选择,做一些事情而不是仅仅使用 = 来设置值,一种更好的清除前 32 位的不同方法,或者设置初始 64 位值的某种方法如果仅设置了底部位,以保证顶部位保持清晰(64 位变量有时会分配给它的其他 64 位变量,因此它不能始终将顶部位强制为 0)。搜索时没有找到很多,这似乎不是经常出现的东西。

编辑:我忘了提到在某些情况下它被签名似乎不是问题所在。一个例子是初始值为0xF8452370,那么long long值显示为-558965697074093200,即0xF83E27A8F8452370。所以低 32 位是相同的,但是高 32 位不是只有 1,而是 1 和 0 的散列。据我所知,签名与未签名没有理由会这样做(所有 1 都是肯定的),但我肯定会弄错。

此外,我认为需要对 64 位变量进行签名,因为在其他情况下,它接受的值需要为负数或正数(实际整数),而在这些情况下,它只需要跟踪位值。这是一个非常多用途的变量,我没有能力让它不被多用途。

edit2:我很可能在这里问错了问题,试图密切关注这一点。但我在限制范围内工作,所以实际问题可能是其他原因,我现在可能只是在添加创可贴。快速总结是这样的:

  1. 有一个 long long 的 64 位变量(或某些系统上的 __int64,但在我遇到的实例中,它应该始终是 long long)。我无法更改它的内容,也无法使其无符号。

  2. 我有一个返回 32 位内存地址的函数。我需要将该 32 位内存地址(不是作为指针,而是作为内存位置的实际值)分配给这个 64 位变量。

  3. 在这些情况下,我需要 64 位变量的前 32 位为 0,而后 32 位与原始值相同。有时它们不是 0,但也不总是 1。

  4. 因为我无法将 64 位变量更改为无符号变量,所以我认为我最好的选择是手动清除前 32 位,我正在寻找最好的方法来做到这一点。

最佳答案

您遇到了符号扩展问题——将带符号的负值转换为更大的类型会将原始值的符号位“扩展”到新类型的所有高位,从而保留数值。例如,(int8_t) 0xFC = -4转换为 (int16_t) 0xFFFC = -4 .额外的位不是“垃圾”;它们具有非常特定的目的和意义。

如果你想避免这种情况,通过一个无符号类型进行转换。例如:

long long sixtyfourbits = (unsigned int) thirtytwobits;

顺便提一下,我建议您使用 <stdint.h>如果您关心代码的大小,请在整个代码中使用整数类型——例如,使用 int64_t而不是 long long , 和 uint32_t而不是 unsigned int .这些名称将更清楚地表明您的意图,并且有一些平台对标准 C 类型使用不同的大小。 (例如,AVR 微 Controller 使用 16 位 int。)

关于c - 将 32 位值分配给 64 位变量并保证前 32 位在 C 中为 0 的最佳方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47538706/

相关文章:

c - 在 C 中记录错误

c - 以下代码将创建多少个进程?

c - 我应该如何设置以使用 GTK4 进行开发?

c# - 哪个是首选 : new Nullable<int> or (int? )null?

python - 与整数差距的季度数

haskell - haskell浮点计算异常?

java - 在 Java 中,如何将 InputStream 转换为字节数组 (byte[])?

c - 需要帮助从 ltp 测试套件文件 tst_res.c 理解这个宏

asp.net-mvc-3 - 即使运算符重载也无法转换为字符串

c# - 检查 C# 中的任何 int 类型?