【问题标题】:convert signed to unsigned value in C在C中将有符号转换为无符号值
【发布时间】:2016-10-14 12:20:46
【问题描述】:

不知何故我得到了一个负值,我需要等效的正值。我虽然将 MAX + 1 添加到该值,其中 MAX 是可以用这么多位数表示的最大值,我们可以解决这个问题。但这并没有帮助。例如请看下面的代码:

#include <stdio.h>

int main()
{
    long long int i;
    unsigned long long u;

    u = 0xffffffff38034080;

    u = 0xffffffffffffffff + u + 1;

    printf("0x%llx", u);
}

但是这个程序返回的是相同的负数。

程序的输出是:0xffffffff38034080。我希望它是0x0000000038034080

【问题讨论】:

  • 0xffffffff38034080 是一个正十六进制数。你期待什么?
  • 我要转换 0xffffffff38034080 -> 0x0000000038034080
  • 您只是引发了溢出,然后您的数字完全相同。您可以乘以 -1 或将其与~ 反转并加 1 我认为或使用位操作,如&amp;
  • @mch 已修复,您可以删除您的评论。谢谢
  • 您正在使用一些不寻常的“等效”定义,您需要指定这些定义才能让这个问题得到回答。

标签: c unsigned signed


【解决方案1】:

我认为您正在寻找的是 2 的补码:

{
    unsigned long long u;

    u = 0xffffffff38034080;

    u = ~u + 1;

    printf("0x%llx", u);
}

【讨论】:

  • 你运行过这个吗?结果不正确。它输出0xc7fcbf80
  • 问题包括“我需要等效的正值”。负值像我的示例一样处理,位模式0xffffffff38034080 的等效正值是0xc7fcbf80。这个结果是正确的。如果还有别的意思,这个问题就不够精确。没有进一步的信息,如 OP 所述,转换为 0x0000000038034080 没有任何意义。这不是处理器的工作方式。
【解决方案2】:

检查数字的最高位。如果已设置,则左移一位以将其删除并增加一个位计数器。重复直到没有设置最高位。

完成此操作后,请在柜台右移。这将移位为 0 的位。

unsigned long long u;
int i,cnt = 0;

u = 0xffffffff38034080ULL;

while (((0x8000000000000000 & u) != 0) && (cnt < 64)) {
    u <<= 1;
    cnt++;
}
u >>= cnt;

printf("0x%llx", u);

【讨论】:

  • 这就是我要找的东西,但我们可以有一个宏或更简单的方法来做到这一点
  • @HimanshuDutta 澄清一下,你确定这是你想要的吗?值0xffffffff38034080 解释为十进制负数是-3355230080,而0x38034080 作为十进制正数是939737216。相反,0xc7fcbf80 作为正小数是3355230080
  • 是的。这有点 2 的补码对我不起作用。所以需要这样做。
  • @HimanshuDutta 那么以上就是你将如何做到这一点。您可以将其放入一个函数中以使其更易于使用。一般来说,当使用函数有意义时,您不应该使用宏,因为如果您不知道自己在做什么,宏可能会带来一些微妙的问题。
【解决方案3】:

我认为,如果您想确定它是如何工作的(我假设您正在做这个练习)也许您可以做一些类似的事情:

#include <stdio.h>
#include <string.h>

int main(int argc, char* argv[]){
    long long int i;
    unsigned long long u;
    long long negative_u;
    long long positive_u;

    u = 0xffffffff38034080;        
    memcpy(&negative_u, &u, sizeof(long long int));
    positive_u = negative_u * -1;      

    printf("0x%llx\n", u);
    printf("0x%llx\n", negative_u);
    printf("0x%llx\n", positive_u);
    return 0;
}

现在您应该会看到为实现您要查找的内容而必须更改的字节的确切值。

问候!

【讨论】:

  • 输出为:0xffffffff38034080 0xffffffff38034080 0xc7fcbf80
  • 现在我们可以肯定地说 Chris Tophski 是完全正确的 ;)
  • @HimanshuDutta 我不明白你是否满意。 Chris Tophski 是完全正确的,如果你想改变符号,你必须计算 2 的补码并加 1。结果就是你所看到的 (0xc7fcbf80),这在我的代码中很明显。显然你必须考虑0x00000000c7fcbf80
  • 我也想知道我的回答是否足够。不仅是为了接受答案,而且@HimanshuDutta 可能真的会想到一些不同的东西,如果是这样的话,我很好奇它是什么。
猜你喜欢
  • 2011-04-19
  • 1970-01-01
  • 1970-01-01
  • 2013-01-22
  • 2014-10-29
  • 2012-08-13
  • 1970-01-01
  • 2012-01-09
相关资源
最近更新 更多