c ++将十进制转换为二进制并存储在unsigned char中
c++ convert decimal into binary and stores in unsigned char
我需要能够将带符号的十进制值(不大于 -200 到 +200)存储到无符号字符 [4] 中。
起初我想用
union
{
float f;
unsigned char u[4];
}
因为 float 也是 4 字节。
但它生成的二进制值与它的值不匹配(即 7 不显示 0111)。 << 我错了,希望浮点数能起作用。
我正在考虑使用 double 并通过按位运算仅将 LSB 4 字节存储到 unsigned char 中。
有什么 "best solution" 可以解决我的问题吗?请在某处提供提示,以便我进行调查!谢谢!
您的评论表明意图是将此值发送到另一个程序。
为此,首先将值变成正值(例如加 200),然后在必要时使用 htons
(or 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
.
的值相同
I need to [...] store a signed decimal value (no larger than -200 to
+200) into an unsigned char[4].
在嵌入式世界中,以下函数 "int16ToStr()" 工作正常,但在此上下文中仅用于说明该技术。 (注意,我使用bitset只是为了方便用二进制显示,否则不需要)。
此代码提取 8 位字节(从值中)并按相应顺序将它们写入字符。
如果需要其他顺序,请使用htonl或ntohl反转int16ToStr()开头的参数'value'。
如果每个无符号字符都必须是可打印字符,那么您需要在问题描述中阐明这一想法。
在这里,原始的 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 到 +200)存储到无符号字符 [4] 中。
起初我想用
union
{
float f;
unsigned char u[4];
}
因为 float 也是 4 字节。
但它生成的二进制值与它的值不匹配(即 7 不显示 0111)。 << 我错了,希望浮点数能起作用。
我正在考虑使用 double 并通过按位运算仅将 LSB 4 字节存储到 unsigned char 中。
有什么 "best solution" 可以解决我的问题吗?请在某处提供提示,以便我进行调查!谢谢!
您的评论表明意图是将此值发送到另一个程序。
为此,首先将值变成正值(例如加 200),然后在必要时使用 htons
(or 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
.
I need to [...] store a signed decimal value (no larger than -200 to +200) into an unsigned char[4].
在嵌入式世界中,以下函数 "int16ToStr()" 工作正常,但在此上下文中仅用于说明该技术。 (注意,我使用bitset只是为了方便用二进制显示,否则不需要)。
此代码提取 8 位字节(从值中)并按相应顺序将它们写入字符。
如果需要其他顺序,请使用htonl或ntohl反转int16ToStr()开头的参数'value'。
如果每个无符号字符都必须是可打印字符,那么您需要在问题描述中阐明这一想法。
在这里,原始的 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],它比需要的要大。
也许您还打算设置一些其他限制条件?