gpt4 book ai didi

C Hexadecimal Addition Incorrect Output(C十六进制加法输出不正确)

转载 作者:bug小助手 更新时间:2023-10-24 17:10:56 32 4
gpt4 key购买 nike



I've got this function that adds two hexadecimal numbers together one byte at a time by acessing the number stored in each object. However this sometimes results in the incorrect output, which I believe is due to an error with the carry value.

我有一个函数,它通过访问存储在每个对象中的数字,一次一个字节地将两个十六进制数相加。然而,这有时会导致不正确的输出,我认为这是由于进位值错误所致。


IntStatus_t intN_add(IntN_t opa, IntN_t opb, IntN_t* result)
{
uint8_t i = NBYTES;
uint8_t carry = 0;
uint16_t sum = 0;

do {
i--;
sum = opa.data[i] + opb.data[i] + carry;
if (sum > 255) {
result->data[i] = sum;
carry = (sum - 255);
} else {
result->data[i] = sum;
carry = 0;
}

} while (i > 0);

For example,

例如,


Provide an intN number in hex encoded form: 00 80 ff
Provide an intN number in hex encoded form: 01 80 01


The sum is:0x030100

Returns 0x030100 instead of 0x20100.

返回0x030100而不是0x20100。


更多回答

The first thing you need to do is to get rid of the custom integer types and switch to stdint.h everywhere. We can't really answer if there's an overflow or such without knowing the actual type of these variables - if there is integer promotion or not etc.

您需要做的第一件事是去掉定制的整数类型,并在任何地方都切换到stdint.h。在不知道这些变量的实际类型的情况下,我们无法真正回答是否存在溢出或诸如此类的问题--是否存在整数提升等等。

优秀答案推荐

This is wrong:

这是错误的:


carry = (sum - 255);

If you add 200 and 200, you'll get 400, which should be 400 - 256 = 144 with a carry of 1. However, your carry calculation would give you a number in the hundreds, which is clearly not what you want.

如果你把200和200相加,你会得到400,这应该是400-256=144,进位为1。然而,你的进位计算会给你一个数百位的数字,这显然不是你想要的。


Taking that into account would give you something like:

考虑到这一点,你会得到一些类似的东西:


sum = opa.data[i] + opb.data[i] + carry;
result->data[i] = sum % 256;
carry = sum / 256;
/*
if (sum > 255) {
result->data[i] = sum - 256;
carry = 1;
} else {
result->data[i] = sum;
carry = 0;
}
*/

You'll notice there I've replaced the if statement with a shorter snippet. The correct if-based solution is given in the comment that follows it, but the shorter form will give you the same result with less code, and also work if you expand your code to handle more than two input numbers at once(1).

您会注意到,我用一段较短的代码片段替换了if语句。正确的基于if的解决方案在后面的注释中给出,但较短的形式将用更少的代码给出相同的结果,如果您将代码扩展为同时处理两个以上的输入数字(1),也同样有效。


What's happening with your given example and code, 0x0080ff + 0x018001, is:

您的给定示例和代码0x0080ff+0x018001的情况如下:



  • Add 0xff and 0x01, with carry 0: 255 + 1 + 1 = 256 which gives you 0 and a carry of 1. That's the correct value and carry but more by accident than anything else :-)

  • Add 0x80 and 0x80, with carry 1: 128 + 128 + 1 = 257 which gives you 1 and a carry of 2.

  • Add 0x00 and 0x01, with carry 2: 0 + 1 + 2 = 3 which gives you 3 and a carry of 0.

  • Hence final result is 0x030100, rather than the correct 0x020100.




(1) Adding two "digits" with a valid carry can never give you more than 255 + 255 + 1 = 511, so the highest carry you can get from that would be 1. However, adding three numbers digit-wise could see 255 + 255 + 255 + 1 = 765, which would be 253 with carry 2.

(1)将两位数与有效进位相加永远不会得到超过255+255+1=511的进位,因此您可以从中获得的最高进位为1。然而,将三个数字按数字相加可以得到255+255+255+1=765,这将是进位2的253。


更多回答

(uint16_t)(opa.data[i]) What does this cast achieve? We know nothing about the types of the original integers and this cast is only meaningful in a system with 16 bit integer. On a 32 bit system, integer promotion will happen. You'd turn one operand unsigned even if it was negative but left the other as it was. Then everything gets promoted to int if it wasn't already int or larger.

(Uint16_T)(opa.data[i])此强制转换实现了什么?我们对原始整数的类型一无所知,此强制转换仅在具有16位整数的系统中有意义。在32位系统上,将发生整数提升。您会将一个操作数变成无符号的,即使它是负数,但让另一个操作数保持不变。然后,如果不是int或更大的话,所有内容都会升级为int。

@Lundin, the fact that the code is using uint8/16_t would suggest each digit is actually of the former type. But you're correct that there's no proof that this is the case (and also on the promotion of lesser-ranked integers to int) so I'll adjust the answer.

@lundin,代码使用uint8/16_t这一事实表明每个数字实际上都是前一种类型。但是您是正确的,没有证据表明是这种情况(以及将排名较低的整数提升为int),所以我会调整答案。

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com