英文:
Unsigned char overflow on byte operations
问题
我正在尝试创建一个函数,它可以将任何类型(float、int、double等)的两个数字相加,并将结果保存到另一个相同类型的数字中。
我研究了void *
,并了解到通过将其强制转换为unsigned char *
,我可以获得每个数字的每个字节。
我面临的问题是,当我添加的数字大于unsigned char
的范围时,它会发生包装。所以在我的情况下,255 + 1 = 0
。
这是我目前的代码,
typedef unsigned char byte;
// add two numbers (of any type) of size abc_size and save in c
void add(void *a, void *b, void *c, size_t abc_size) {
byte *a_bytes = (byte *) a;
byte *b_bytes = (byte *) b;
byte *c_bytes = (byte *) c;
for (size_t i = 0; i < abc_size; i++) {
byte a_byte = a_bytes[i];
byte b_byte = b_bytes[i];
byte sum = a_byte + b_byte; // do i have to account for carry or endianess?
c_bytes[i] = sum;
}
}
以及我用于测试的主要函数,
#include <stdio.h>
int main(void) {
int a = 255;
int b = 1;
int c = 0;
add(&a, &b, &c, sizeof(int));
printf("%d + %d = %d\n", a, b, c);
}
上面的输出是,
255 + 1 = 0
当我尝试添加floats
或doubles
时,我也面临问题,结果完全出乎意料,并且我想这可能又是因为溢出。
这种方法对于任何数字和任何类型都能工作吗?如果可以,我需要做哪些改变?
提前感谢您的帮助。
英文:
I am trying to make a function that adds two numbers of any type (float, int, double etc), and saves the result into another number of the same type.
I was looking into void *
and learned that by casting to unsigned char *
, I can get each byte of each number.
The problem I am facing is, that when I add something greater than the range of an unsigned char
, it wraps around. So in my case 255 + 1 = 0
.
This my code so far,
typedef unsigned char byte;
// add two numbers (of any type) of size abc_size and save in c
void add(void *a, void *b, void *c, size_t abc_size) {
byte *a_bytes = (byte *) a;
byte *b_bytes = (byte *) b;
byte *c_bytes = (byte *) c;
for (size_t i = 0; i < abc_size; i++) {
byte a_byte = a_bytes[i];
byte b_byte = b_bytes[i];
byte sum = a_byte + b_byte; // do i have to account for carry or endianess?
c_bytes[i] = sum;
}
}
and the main I used for testing,
#include <stdio.h>
int main(void) {
int a = 255;
int b = 1;
int c = 0;
add(&a, &b, &c, sizeof(int));
printf("%d + %d = %d\n", a, b, c);
}
The output of the above is,
255 + 1 = 0
I am also facing a problem when I am trying to add floats
or doubles
, which the result is completely unexpected, and I would image is again because of the overflow.
Can this method work at all for any number and any type? If so, what do I need to change?
Thank you in advance.
答案1
得分: 4
你正在试图重复造轮子,而你的简单方法将无法处理任何浮点数。使用通用选择。
#define add(a,b) _Generic((a), \
double: addd, \
default: addu, \
float: addf, \
int: addi \
)(a,b)
double addd(double a, double b)
{
return a+b;
}
float addf(float a, float b)
{
return a+b;
}
unsigned addu(unsigned a, unsigned b)
{
return a+b;
}
int addi(int a, int b)
{
return a+b;
}
int main(void)
{
printf("%u %i %f\n", add(1u, 4u), add(-3,1), add(3.0, 1.5));
}
你可以在这个链接中查看代码:https://godbolt.org/z/T3nsdvKn1
英文:
You are trying to reinvent the wheel and your naive method will not work with any floating point numbers. use generic selection
#define add(a,b) _Generic((a), \
double: addd, \
default: addu, \
float: addf, \
int: addi \
)(a,b)
double addd(double a, double b)
{
return a+b;
}
float addf(float a, float b)
{
return a+b;
}
unsigned addu(unsigned a, unsigned b)
{
return a+b;
}
int addi(int a, int b)
{
return a+b;
}
int main(void)
{
printf("%u %i %f\n", add(1u, 4u), add(-3,1), add(3.0, 1.5));
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论