【问题标题】:What is the value of a unsigned long long in hex十六进制无符号长长的值是多少
【发布时间】:2013-08-20 05:27:27
【问题描述】:

我有这个变量

unsigned long long latitude = 29.47667;

当我将此值转换为这样的数组时

    ar[7] = (uint8_t)((latitude >> 56) & 0xFF);
    ar[6] = (uint8_t)((latitude >> 48) & 0xFF);
    ar[5] = (uint8_t)((latitude >> 40) & 0xFF);
    ar[4] = (uint8_t)((latitude >> 32) & 0xFF);
    ar[3] = (uint8_t)((latitude >> 24) & 0xFF);
    ar[2] = (uint8_t)((latitude >> 16) & 0xFF);
    ar[1] = (uint8_t)((latitude >> 8) & 0xFF);
    ar[0] = (uint8_t)(latitude & 0xFF);

然后使用 tcp 套接字将其发送到服务器。当我发送时,我以十六进制打印值,然后我得到 0x1d 其余全为零。

如何在将 unsigned long long 转换为 int 时将准确的值发送到服务器。

【问题讨论】:

    标签: c floating-point embedded printf


    【解决方案1】:

    unsigned long long latitude = 29.47667 没有多大意义,unsigned long long 是整数类型。所以变量只得到截断的整数29

    这就是为什么你只得到0x1d,它只是十六进制的29

    【讨论】:

    • 我想要一个 64 位变量。我有 typedef 签名 long long int64_t,可以吗?
    • @Ishmeet long long 至少为 64 位,可能更长。因此,一种可移植的方式是在stdint.h 中使用int64_t(如果可用)。
    • 我尝试了intint64_t,仍然得到相同的答案,它没有工作。你能告诉我值 29.47667 是如何转换为十六进制的吗?这是自己发生的,还是我们需要做一些计算?
    • @Ishmeet 29.47667 是浮点值,为什么要用整数类型来存储呢?正如我在答案中所说,它将被截断。也许您正在寻找double
    • 好的,现在我有了double latitude = 29.47667;,我需要将这个值转换为8字节数组ar[8]的东西。
    【解决方案2】:

    逐字节读取双值:

    double val = 29.47667;
    double *ptr = &val;
    uint8_t bytes[8];
    register int i;
    
    for(i = 0; i < 8; ++i)
    {
       bytes[i] = *(((uint8_t*)ptr) + i);
       printf("%hhu", bytes[i]);
    }
    

    十进制值不要使用unsigned long long类型

    另一种方法(如果不修改源):

    double val = 29.47667;
    double *ptr = &val;
    uint8_t *cptr = (uint8_t*)ptr;
    

    现在使用 *(cptr + i) 直接访问/发送字节 i.

    的值

    【讨论】:

    • 或者你基本上可以做memcpy(bytes,&amp;val,8);,这对我有用:)。
    • +1 表示该方法,但我认为(不确定)memcpy() 在内部仅实现逐字节复制。
    • 建议在您的printf() ("%03hhu") 上固定宽度。
    【解决方案3】:

    将双精度转换为十六进制,然后将十六进制转换为双精度。

    double 覆盖一个 64 位整数。这假设双精度为 8 字节。如果double 不同,则可以轻松覆盖其他整数大小。

    通过您的 tcp 套接字发送整数并根据需要重新组合。

    // 29.47667
    403D7A070B8CFBFC
    2.94766699999999986e+01
    

    #include <stdio.h>
    #include <float.h>
    #include <inttypes.h>
    
    uint64_t MakeHex(double d) {
      union {
          double d;
          uint64_t u;
      } x;
      x.d = d;
      return x.u;
    }
    
    double MakeD(uint64_t u) {
      union {
          double d;
          uint64_t u;
      } x;
      x.u = u;
      return x.d;
    }
    int main() {
      uint64_t u = MakeHex(29.47667);
      printf("%0" PRIX64 "\n", u);
      double d = MakeD(u);
      printf("%.*le\n", DBL_DIG+2, d);
      return 0;
    }
    

    【讨论】:

    • 哇!太好了,但我不能使用 PRIX64 和 DBL_DIG+2,因为我使用的是 Stm32L 平台,并且使用 UART 作为调试消息。但我仍然会尝试不打印。
    【解决方案4】:

    您可以通过将其包含在任何头文件中来调用此函数

    void dec_hex(long int num)      // Function Definition
    {
    long int rem[50],i=0,length=0;
    while(num>0)
       {
          rem[i]=num%16;
          num=num/16;
          i++;
          length++;
       }
    
    printf("Hexadecimal number : ");
    
    for(i=length-1;i>=0;i--)
      {
        switch(rem[i])
        {
          case 10:
              printf("A");
              break;
    
          case 11:
              printf("B");
              break;
    
          case 12:
              printf("C");
              break;
    
          case 13:
              printf("D");
              break;
    
          case 14:
              printf("E");
              break;
    
          case 15:
              printf("F");
              break;
    
          default :
             printf("%ld",rem[i]);
        }
      }
    }
    

    【讨论】:

    • 它将采用我的double 值并将其转换为int,如long int num,因此不会提供所需的正确答案。
    • 这对使用十进制数字解决 OP 的问题没有任何帮助。
    猜你喜欢
    • 1970-01-01
    • 2014-10-22
    • 1970-01-01
    • 2011-08-09
    • 2012-03-22
    • 1970-01-01
    • 2013-06-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多