作者s6414073 ()
看板C_and_CPP
标题[问题] uint32阵列每笔资料多一个bit当flag转换
时间Mon Apr 15 18:46:08 2024
开发平台(Platform): (Ex: Win10, Linux, ...)
Linux
编译器(Ex: GCC, clang, VC++...)+目标环境(跟开发平台不同的话需列出)
gcc
额外使用到的函数库(Library Used): (Ex: OpenGL, ...)
无
问题(Question):
在每一笔数据的第31bit加入flag,0表示後面还有元素,1表示後面没有元素,
也就是最後一笔元素;
每一笔的0-30bit为数据,第31bit原本的资料会放到第二笔数据的bit0,
原本第二笔的数据0~29bit要做right shift
也就是原来第一笔数据的bit31跑到第二笔数据的的bit0,
原本第二笔数据的0-29bit变成1-30bit,第二笔的bit31仍为flag,
要设计出n个元素都能通用的函数
喂入的资料(Input):
unsigned int input_data[3] = {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF};
预期的正确结果(Expected Output):
unsigned int output_data[4] = {0x7FFFFFFF,0x7FFFFFFF,0x7FFFFFFF,0x80000007};
错误结果(Wrong Output):
最後一笔应为0x80000007
实际上跑出来是0x80000000
程式码(Code):(请善用置底文网页, 记得排版,禁止使用图档)
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
// Define the flag bit value
#define FLAG_BIT 0x80000000
// Function to convert array of unsigned integers
unsigned int* convert_data(unsigned int* input_data, int len) {
// Allocate memory for the output data
unsigned int* output_data = (unsigned int*)malloc((len + 1) *
sizeof(unsigned int));
if (output_data == NULL) {
perror("Failed to allocate memory");
exit(EXIT_FAILURE);
}
// Convert each element
for (int i = 0; i < len; i++) {
// Extract the data part (lower 31 bits) of the current input element
unsigned int data = input_data[i] & 0x7FFFFFFF;
// Extract the flag bit of the current input element
unsigned int flag = (input_data[i] >> 31) & 0x1;
// Combine data and flag to form the output element
output_data[i] = data;
// Set the flag bit of the next element if this is not the last
element
if (i < len - 1) {
output_data[i + 1] = (flag << 31) | (output_data[i + 1] >> 1);
}
}
// Set the flag bit of the last element to indicate the end
output_data[len] = FLAG_BIT | (output_data[len] >> 1);
return output_data;
}
int main() {
unsigned int input_data[3] = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF};
int len = sizeof(input_data) / sizeof(input_data[0]);
// Convert the data
unsigned int* output_data = convert_data(input_data, len);
// Print the converted data
for (int i = 0; i < len + 1; i++) {
printf("output_data[%d] = 0x%08X\n", i, output_data[i]);
}
// Free the allocated memory
free(output_data);
return 0;
}
补充说明(Supplement):
或是有没有现成的library可以做这件事?
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 220.133.94.2 (台湾)
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/C_and_CPP/M.1713177972.A.3E9.html
1F:推 wulouise: 不懂为什麽要这样设计,header直接给长度不是更简单? 04/15 19:27
2F:推 wulouise: 而且你的程式根本没考虑到input的carry over吧.. 04/15 19:47
3F:→ stupid0319: 这麽简单,还要找library? 04/15 20:41
4F:推 ssdoz2sk: 输出的长度应该为(len*32+30)/31,再来carry的长度会因 04/16 02:31
5F:→ ssdoz2sk: 为你缩减储存空间越来越长,i=1 carry 1bit,i=2 carry 04/16 02:31
6F:→ ssdoz2sk: 2bit,直到 31bytes data 扩展成 32bytes。你 code 考 04/16 02:31
7F:→ ssdoz2sk: 虑的 carry 长度不应该是固定的,况且你在 i++ 後又用 i 04/16 02:31
8F:→ ssdoz2sk: nput 的 bit 0-31 盖掉是在?? 04/16 02:31
9F:推 johnjohnlin: c bit field是你要的吗 04/16 07:41
10F:推 akasan: leb128 04/16 23:50
11F:推 Qbsuran: 类似作法在nginx有做到 他是利用malloc/calloc的最後一个 05/16 00:32
12F:→ Qbsuran: bit一定会对齐偶数, 所以就可以利用最後一个bit做flag 05/16 00:33
13F:→ Qbsuran: nginx自己实作的memory pool也是会对齐偶数 05/16 00:34
15F:→ Lipraxde: 这种 tricky 的玩法在真的很计较空间的时候再用就好了 05/16 22:40
16F:→ Lipraxde: 啦,没事用这招瞎搞,秀完技巧後剩下的就是麻烦 05/16 22:40