【问题标题】:c++ convert decimal into binary and stores in unsigned charc ++将十进制转换为二进制并存储在无符号字符中
【发布时间】:2015-12-14 13:54:15
【问题描述】:

我需要能够将带符号的十进制值(不大于 -200 到 +200)存储到 unsigned char[4] 中。

一开始我想用

union
{
 float f;
 unsigned char u[4];
}

因为浮点数也是 4 字节。

但它生成的二进制值与其值不匹配(即 7 不显示 0111)。

我正在考虑使用 double 并且仅通过使用按位运算将 LSB 4 字节存储到 unsigned char 中。

我的问题有什么“最佳解决方案”吗?请在某处提供提示,以便我可以调查它!谢谢!

【问题讨论】:

  • 是什么让您认为float 表示中的7 实际上应该产生0111
  • 为什么需要将其存储在 unsigned char[4] 中?这里的一些背景信息可能会有用。
  • 这是您要存储的整数还是浮点数?如果是整数,请在您的机器上使用 4 个字节的整数类型。如果是浮点,请注意浮点使用模糊的二进制表示(参见上面发布的链接)。即使您存储整数,也要注意字节顺序问题。
  • 我需要将它存储到 unsigned char[4] 以发送到另一个程序并“保存字节”,因为范围是 -200 ~ +200,4 个字节绰绰有余(限制由于要求),接收程序对值的作用不是我关心的问题,但我必须遵守给定的要求:(我希望 7 是 0111 .n 是的,结果并没有像我希望的那样对于浮点数.. @SimonB 我需要能够以存储在 unsigned char 中的二进制形式发送例如 -0.125,并能够在接收端将其读回为 -0.125

标签: c++ binary decimal


【解决方案1】:

我需要 [...] 存储一个带符号的十进制值(不大于 -200 到 +200) 转换为无符号字符[4]。

在嵌入式世界中,以下函数“int16ToStr()”可以正常工作,但在此上下文中仅用于说明该技术。 (请注意,我使用 bitset 只是为了方便以二进制显示,否则不需要)。

此代码从值中提取 8 位字节,并按相应顺序将它们写入字符中。

如果需要其他顺序,使用 htonl 或 ntohl 将 int16ToStr() 开头的参数 'value' 反转。

如果每个 unsigned char 都必须是可打印的 char,那么您需要在问题描述中阐明这个想法。

在这里,原始的 16 位(因为范围小)十进制整数被简单地转换为原始的无符号字符。

请注意,“unsigned char str[4]”的前两个字节总是 0x00 或 0xff,因为十进制范围只需要两个字节 == 两个字符。

#include  <bitset>
#include <iomanip>
#include <iostream>

// transfers 16 bit content of value to 4 chars
void int16ToStr(int16_t       value,
                unsigned char str[4])
{
   std::cout << "\n  value: " << std::dec << value << "  " << std::endl;
   std::bitset<16> bset(value);
   std::cout << " bitset: " << bset << std::endl;

   // leastSignificant Nibble - last to print
   str[3] = static_cast<unsigned char>(( value >>  0) & 0xff); // lsNibl 
   str[2] = static_cast<unsigned char>(( value >>  8) & 0xff); 
   str[1] = static_cast<unsigned char>(( value >> 16) & 0xff); 
   str[0] = static_cast<unsigned char>(( value >> 24) & 0xff); // msNibl 
   // mostSignificant Nibbl - 1st

   std::cout << "  uchar: ";
   for (int i=0; i<4; ++i) std::cout  << std::setfill ('0') 
                                      << std::hex  << std::setw(2) 
                                      << static_cast<int>(str[i]) << " ";
   std::cout << std::endl;
}

// test 244 invoked from main
int t244(void)
{
   for (int16_t val0 = -200; val0 <= -199; ++val0)
   {
      unsigned char    str0[4];
      int16ToStr(val0, str0);
   }

   for (int16_t val1 = -2; val1 <= 2; ++val1)
   {
      unsigned char str1[4] ;
      int16ToStr(val1, str1);
   }

   for (int16_t val2 = 199; val2 <= 200; ++val2)
   {
      unsigned char str2[4] ;
      int16ToStr(val2, str2);
   }

   return (0);
}

输出:

  value: -200  
 bitset: 1111111100111000
  uchar: ff ff ff 38 

  value: -199  
 bitset: 1111111100111001
  uchar: ff ff ff 39 

  value: -2  
 bitset: 1111111111111110
  uchar: ff ff ff fe 

  value: -1  
 bitset: 1111111111111111
  uchar: ff ff ff ff 

  value: 0  
 bitset: 0000000000000000
  uchar: 00 00 00 00 

  value: 1  
 bitset: 0000000000000001
  uchar: 00 00 00 01 

  value: 2  
 bitset: 0000000000000010
  uchar: 00 00 00 02 

  value: 199  
 bitset: 0000000011000111
  uchar: 00 00 00 c7 

  value: 200  
 bitset: 0000000011001000
  uchar: 00 00 00 c8 

-200 到 +200 是 400,大于单个字符(1 字节 => 256),但可以放入两个字符(2 字节 == 16 位)。您特别指出了 char[4],它比必要的要大。

也许您打算使用其他一些限制条件?

【讨论】:

  • 我很抱歉,因为我认为我造成了一些误解。要求应该是 -200.0 到 +200.0 最多 2 位精度小数,即要转换为二进制的值可以是 150.59 或 -20.48 等。因此我认为我应该先将值乘以 100,然后再执行您的建议..yea 似乎即使在扩大价值之后,2^16 仍然足够。我将建议减少此参数所需的大小。谢谢!
  • @user1693492 - 我很少使用 float 或 double,尽管如今大多数硬件都支持这两种方法。但是,为了您的努力,您需要查看浮点数(或双精度数)的内存布局......我似乎记得尾数,指数,而不是简单的布局。 Sizeof(float) 是 4 个字节,Sizeof(double) 是 8 个字节。但是 shift 和 mask 对 int 起作用。请务必研究浮点(或双精度)中位的布局。布局可能会影响如何使用遮罩和移位技术,但可能有更好的方法。
【解决方案2】:

您的评论表明意图是将此值发送到另一个程序。

为此,首先将值转换为正值(例如通过添加 200),然后使用htons(或htonl,如果需要)以网络字节顺序重新排列字节:

int32_t input = /*your value between -200 and 200 */;
uint16_t value = htons((uint16_t) (input + 200));

然后可以将这个值发送到其他程序,例如。 :

write(sock, &value, sizeof(value));

然后接收者将通过使用ntohs (resp. ntohl) 对接收到的值执行相反的操作:

uint16_t value = 0;
read(sock, &value, sizeof(value));
int32_t output = ((int32_t) ntohs(value)) - 200;

并且output 将具有与input 相同的值。

【讨论】:

    猜你喜欢
    • 2014-07-26
    • 2022-09-22
    • 2015-01-11
    • 2014-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-23
    相关资源
    最近更新 更多