整数上的Shift运算符

时间:2014-12-11 13:08:44

标签: c

我有以下功能:

 #include<stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdint.h>
#include <inttypes.h>

uint64_t dtally(uint64_t x)
{
    uint64_t t = 0;
    while (x){ t += 1 << ((x%10) * 6), x /= 10;
    return t;
}

int main(int argc, char *argv[])
{
    printf("%" PRIu64 "\n", dtally(39));
    return 0;
}

当我将数字传递为39时,我理解应返回以下值

18014398509481984

但它返回此值:

4456448

因为返回此值而不是您所期望的那样?

2 个答案:

答案 0 :(得分:4)

您的代码有两个问题(事实上它是两次相同的问题)。

首先,tint,通常是32位整数(至少16位)。所以2 ^ 54,不适合那里。您必须为t使用64位类型。但是你的问题会持续存在。

第二个问题比较棘手:1 << ((x % 10) * 6)对文字1执行轮班操作。但1int。因此1 << 54将返回0(一个移出32位内存,然后添加到t)。要解决此问题,您可以将文字1强制转换为int64_t或使用文字1LL(长long类型)。

所以你应该有这样的东西:

int count(int x)
{
    int64_t t = 0;
    while (x) t += 1LL << ((x % 10) * 6), x /= 10;
    return t;
}

答案 1 :(得分:3)

18014398509481984可能对您平台上的int来说太大了。

通过测试sizeof(int)来检查这一点。如果那是4那么你可以代表的最大数字是超过20亿。它甚至可能只有2(在这种情况下,最大的int将是32767)。

您可以使用int64_t代替64位(自C99起可用;虽然平台不被强制支持)。

不要忘记用LL表示64位字符的任何文字后缀。