【问题标题】:How do I bit shift unsigned long in C?如何在 C 中对 unsigned long 进行位移?
【发布时间】:2018-11-01 07:25:52
【问题描述】:

我已经尝试了一切来解决这个问题,但我不明白我做错了什么。转换为有符号会使所有内容都超过数字十六进制值,我知道如果我有一个整数,我可以直接使用“ULL”来转换它并移位但我不知道

基本上

void   tick(unsigned long* tmp) { //input as a parameter
   signed long temp = tmp;

   printf("%x\n", temp >> 16 & 0xff);

   tmp = (signed) temp;

   return;
}

编辑:所以我很愚蠢,我应该使用 %lu 而不是 %x,现在我可以看到我的结果,但我看不到时钟发生任何变化,即使对 temp 进行位移

【问题讨论】:

  • 首先,初始化signed long temp = tmp很可疑。其次,对于一些指定的输入,预期和实际输出是多少?请阅读how to ask good questionsthis question checklist。最后学习如何创建Minimal, Complete, and Verifiable Example
  • 这甚至不是有效的 C 语言,也不会干净地编译。
  • 你为什么混合指针和非指针,你的意思是signed long temp = (signed long)*tmp;?如果你想使用tmp的地址使用intptr_t而不是long
  • 那你为什么要转换成有符号的呢?
  • 问题不是你做错了什么,而是你想要达到什么目标?

标签: c long-integer bit-shift unsigned


【解决方案1】:
  • 函数参数是一个指针,因此您需要取消引用它才能访问它的值。
  • 如果要存储变量,则需要将位移后的值分配给它。
  • 而如果要改变指针下的值,则需要将新值赋给取消引用的指针
  • 您还需要使用长格式选项才能正确显示。 (这里,lux -> long unsigned hexadecimal)

这是修改后的版本:

#include <stdio.h>

void    tick(unsigned long* input)
{
  unsigned long temp;

  temp = ((*input) >> 16) & 0xff;
  printf("%lux\n", temp);

  *input = temp;
}

int main()
{
  long test = 1;
  tick(&test);
  test = 0b100000000000000000;
  tick(&test);
  test = 0b111111111111111111;
  tick(&test);
}

【讨论】:

    【解决方案2】:

    根据 cmets 中的信息,您实际上将整数布局为小时/分钟/秒/am-pm,每个字段都有 2 个字节(确保您的意思是 2 个字节,而不是 2 个半字节),例如这个:

    +--+--+--+--+--+--+--+--+
    |H |H |M |M |S |S |AM PM|
    +--+--+--+--+--+--+--+--+
    

    而您想提取包含秒数的 2 个字节并将它们加 1。

    您需要 8 个字节(64 位)来表示该值,因此我将使用 uint64_t 类型而不是 unsigned long 类型,您可以通过 #include &lt;stdint.h&gt; 获得 uint64_t 类型

    void tick(uint64_t *value) { //input as a parameter
      //extract seconds 
      unsigned int seconds ((*value) >> 16) & 0xffff
    
      printf("seconds = %u\n", seconds);
    
     //add 1 second and pack the value back:
     seconds += 1;
     *value = (value & 0xffffffff0000ffff) | ((seconds & 0xffff) << 16);
    
     return; //returns void
    }
    

    (现在,您可能还需要处理换行,例如,当秒数达到 60 时增加分钟等)

    【讨论】:

    • 不幸的是,我需要使用 unsigned long,我可以转换为 uint64_t 吗?
    • 如果您知道您的平台上的 unsigned long 是 64 位的,只需使用 unsigned long 而不是 uint64_t。但请确保您的意思是每个字段(例如一秒)是 16 位(2 个字节)而不是 8 位(1 个字节)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-08-01
    • 2013-09-22
    • 1970-01-01
    • 1970-01-01
    • 2011-03-13
    • 1970-01-01
    相关资源
    最近更新 更多