我正在从硬件设备的串口读取数据,我需要将其递增1然后发送回设备,但是我需要将其递增,就像它是一个base10数字一样。
例如,如果我读取0x09,我需要发回0x10而不是0x0a。或者,如果我收到0x89,我应该发回0x90。如果我收到0x99,我会发送回0x00并将1传送到前一个字节。它实际上总共需要5个字节。
我按以下方式使用此增量。我想知道是否有更好的方式通过一些独特的移位和/或和/或位。
感谢您提供的任何指示!
有状态
#include <stdio.h>
#include <stdlib.h>
int main()
{
//start with 0x09 as byte
char input = 0x09;
printf("input is: 0x%02x\n", input);
//increment it by one
input++;
//turn it into a two char array as a base10 value, ignore overflow for now
char asString[3];
sprintf(asString, "%d", input);
//convert back to byte
unsigned char newI = ((asString[0]-0x30)*16)+((asString[1]-0x30));
printf ("newI is 0x%02x\n", newI);
return 0;
}
答案 0 :(得分:5)
您计算收到的数字的模16。 如果是9,则添加7,否则为1。
答案 1 :(得分:1)
将整个字节序列从BCD转换为整数类型,添加,然后转换回来。像这些函数这样的东西应该适用于转换,但要注意,如果你需要支持完全任意的5字节BCD序列,你可能需要比unsigned
更长的类型(但是5个字节的BCD可疑地与一个32位整数。)
/*
* Decodes a BCD byte sequence to an unsigned integer. The bytes are assumed to be in
* order from most- to least-significant.
*/
unsigned bcd_to_int(unsigned char bytes[], int byte_count) {
unsigned result = 0;
int counter;
for (counter = 0; counter < byte_count; counter += 1) {
result = result * 100 + (bytes[counter] & 0xf0) * 10 + (bytes[counter] & 0x0f);
}
return result;
}
/*
* Encodes an unsigned integer into a BCD byte sequence. The bytes will be ordered
* from most- to least-significant.
*/
void int_to_bcd(unsigned char bytes[], int byte_count, unsigned value) {
int counter;
for (counter = byte_count; counter-- > 0; ) {
unsigned chunk = value % 100;
bytes[counter] = (chunk / 10) * 0x10 + (chunk % 10);
value /= 100;
}
}
您还可以直接在字节序列上实现长格式加法;可能表现得更好或更好,但如果你想执行比单个添加/增量更多或不同的操作,那么使用本机算法对你有利。