【问题标题】:How to convert epoch decimal time to 64 bit binary and back to decimal in C如何在 C 中将纪元十进制时间转换为 64 位二进制并返回十进制
【发布时间】:2014-11-09 09:28:00
【问题描述】:

我正在尝试创建一个脚本,该脚本将根据指定的大小将小数转换为二进制,然后反转该过程,即从二进制转换为十进制。到目前为止,从我的角度来看(初学者)的脚本和输出脚本看起来是正确的。我可以将所有数字从十进制转换为二进制,反之亦然。我是最后一部分的堆栈,我正在尝试将纪元时间从 64 位二进制数转换为十进制数。我不明白我哪里出错了,因为其余的数字似乎恢复正确。我发现我正在使用的脚本的源点是Binary to DecimalDecimal to Binary

更新:将代码修改为短版本:

我已经修改了代码来简单地演示问题。该代码可以正常工作到 32 位二进制转换。但由于我需要转换到 64,所以我不知道该怎么做。我注意到因为我之前使用int 达到了最大限制32 位,所以我将其修改为long long int 以达到64 位。

我提供了一个简单的十进制转换示例,即 32 位格式的 1 和演示问题的 64。纪元时间是所需的输出,但我需要在尝试转换之前验证代码是否有效。

代码示例:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <inttypes.h>

#define MAX_CHARACTERS 65

typedef struct rec {
  char transmit[MAX_CHARACTERS];
  char receive[MAX_CHARACTERS];
}RECORD;

char *decimal_to_binary(int n , int num); /* Define function */

char *decimal_to_binary(int n , int num) {

  long long int c, d, count;
  char *pointer;

  count = 0;

  pointer = (char*) malloc( num + 1 );

  if ( pointer == NULL )
    exit(EXIT_FAILURE);

  for ( c = num - 1; c >= 0; c-- ) {

    d = n >> c;

    if ( d & 1 )
      *( pointer + count ) = 1 + '0';
    else
      *( pointer + count ) = 0 + '0';

     count++;
  }
  *( pointer + count ) = '\0';

  return pointer;
}

int binary_decimal(long long int n); /* Define function */

int binary_decimal(long long int n) { /* Function to convert binary to decimal.*/

  int decimal=0, i=0, rem;

  while (n!=0) {

    rem = n%10;
    n/=10;
    decimal += rem*pow(2,i);
    ++i;

  }

  return decimal;

}

int main(void) {

   RECORD *ptr_record;

   ptr_record = (RECORD *) malloc (sizeof(RECORD));

   if (ptr_record == NULL) {
     printf("Out of memmory!\nExit!\n");
     exit(0);
   }

   int LI_d = 1;
   char *LI_b = decimal_to_binary(LI_d,32);

   memset( (*ptr_record).transmit , '\0' , sizeof((*ptr_record).transmit) );
   strncat((*ptr_record).transmit , LI_b , strlen(LI_b) );

   printf("LI: %s\n",(*ptr_record).transmit);

   //transmit and receive

   memset( (*ptr_record).receive , '\0' , sizeof((*ptr_record).receive) );
   strncpy( (*ptr_record).receive , (*ptr_record).transmit , strlen((*ptr_record).transmit) );

   char *LI_rcv_b = strndup( (*ptr_record).receive , 64 );
   int LI_rcv_i = atoi (LI_rcv_b);
   int final_LI = binary_decimal(LI_rcv_i);
   printf("Final_LI: %i\n",final_LI);

   free( ptr_record );

   return 0;

}

32 位转换的输出示例:

LI: 00000000000000000000000000000001
Final_LI: 1

64 位转换的输出示例:

LI: 0000000000000000000000000000000100000000000000000000000000000001
Final_LI: -1

【问题讨论】:

  • 注意:strncat((*ptr_record).transmit , VN_b , strlen(VN_b)); 似乎使用不正确。你想要的是strncat((*ptr_record).transmit , VN_b , sizeof ((*ptr_record).transmit ) - 1); 这将确保目标永远不会溢出,并且当你用全0初始化缓冲区时,最后一个位置总是'\0'
  • @chux 感谢您的评论和宝贵的反馈。看来我的印象是错误的。我试图将 32 位整数转换为 64 位的值。结果是完全错误的。我已经更新了问题和代码,所以我希望现在它更容易理解。再次感谢您的时间和精力。

标签: c binary epoch


【解决方案1】:
  1. decimal_to_binary(int n, ...): 最好使用无符号数学

    //char *decimal_to_binary(int n, int num) {
    char *decimal_to_binary(unsigned long long n, int num) {
      //  long long int c, d, count;
      unsigned long long int d;
      int c, count;
      char *pointer;
    
      count = 0;
      pointer = malloc(num + 1);  // drop cast
      if (pointer == NULL)
        exit(EXIT_FAILURE);
    
      for (c = num - 1; c >= 0; c--) {
        d = n >> c;
        if (d & 1)
          *(pointer + count) = 1 + '0';
        else
          *(pointer + count) = 0 + '0';
        count++;
      }
      *(pointer + count) = '\0';
      return pointer;
    }
    
  2. 简化binary_decimal()。再次使用无符号数学,删除pow()

    /* Function to convert binary to decimal.*/
    unsigned long binary_decimal(unsigned long long int n) { 
      unsigned long decimal = 0;
      while (n != 0) {
        decimal *= 2;
        decimal += n % 10;
        n /= 10;
      }
      return decimal;
    }
    
  3. main() 有很多问题

    int main(void) {
      RECORD *ptr_record;
    
      ptr_record = malloc(sizeof(RECORD));  // drop cast
      if (ptr_record == NULL) {
        printf("Out of memory!\nExit!\n"); // spelling fix
        exit(0);
      }
      // use unsigned long long
      unsigned long long LI_d = 1;
      LI_d = (unsigned long long) -1;
      char *LI_b = decimal_to_binary(LI_d, 32);
    
      memset((*ptr_record).transmit, '\0', sizeof((*ptr_record).transmit));
      // strncat((*ptr_record).transmit, LI_b, strlen(LI_b));
      strncat((*ptr_record).transmit, LI_b, sizeof((*ptr_record).transmit) - 1);
    
      printf("LI: %s\n", (*ptr_record).transmit);
    
      //transmit and receive
    
      memset((*ptr_record).receive, '\0', sizeof((*ptr_record).receive));
      // strncpy((*ptr_record).receive, (*ptr_record).transmit, strlen((*ptr_record).transmit));
      strncpy((*ptr_record).receive, (*ptr_record).transmit, sizeof((*ptr_record).transmit) - 1);
    
      // char *LI_rcv_b = strndup((*ptr_record).receive, 64);
      char *LI_rcv_b = strndup((*ptr_record).receive, MAX_CHARACTERS);
    
      // At this point, approach is in error
      // Cannot take a 64-decimal digit string and convert to a typical long long.
      // int LI_rcv_i = atoi(LI_rcv_b);
      // int final_LI = binary_decimal(LI_rcv_i);
      // printf("Final_LI: %i\n", final_LI);
    
      // Suspect you want to convert 64-binary digit string to a 64-bit integer
      // maybe by somehow using binary_decimal - suggest re-write of that function
      unsigned long long LI_rcv_i = strtoull(LI_rcv_b, NULL, 2);
      printf("Final_LI: %llu\n", LI_rcv_i);
    
      free(ptr_record);
      return 0;
    }
    

输出

李:1111111111111111111111111111111
Final_LI​​:4294967295

【讨论】:

    猜你喜欢
    • 2017-08-08
    • 1970-01-01
    • 1970-01-01
    • 2018-07-12
    • 1970-01-01
    • 1970-01-01
    • 2012-06-26
    • 1970-01-01
    • 2015-12-02
    相关资源
    最近更新 更多