我做了以下操作:
uint8_t input = 10;
uint8_t output = ((0x190 - (input * 8)) & 0xFF);
// newInput should be 10 again, but is 255
uint8_t newInput = (((output * 8) + 0x190) | 0xFF);
如何更正操作设置newInput
以使其返回10?
答案 0 :(得分:2)
您想要反转从output
获得input
的转换,但遗憾的是逻辑存在缺陷。 |
不是&
的倒数,* 8
绝对不与另一个* 8
相反。另外,如果您想要撤销y = 0x190 - x
的操作,它不是+
而是另一个x = 0x190 - y
(在纸上试试!)最后,如果您拥有所有操作可以,操作的顺序需要反转才能撤消它们(先进先出)。
实际上,您的转换不能被反转,因为它会丢失定义input
的部分信息。 (从数学上讲,它不是单射的。)考虑一下:
uint8_t input = 10;
uint8_t output = ((0x190 - (input * 8)) & 0xFF); /* 0x40 */
uint8_t input2 = 42;
uint8_t output2 = ((0x190 - (input2 * 8)) & 0xFF); /* also 0x40! */
如果你有一个可以撤消操作的函数,那么output
0x40
,10或42的返回值是多少?这没有解决方案。如果您想要原始input
,则需要在某处保留该变量的副本。
无符号8位计算中可以撤消的操作示例是
y = x + a
⇔x = y - a
,y = c - x
⇔x = c - y
,包括明显否定(c
= 0),y = x ^ p
⇔x = y ^ p
,包括~x
(' s x ^ 0xFF
),对像y = -((x + 0x17) ^ 0x15)
这样的化合物的逆操作看起来像x = ((-y) ^ 0x15) - 0x17
,请注意步骤撤消的相反顺序。
另一方面,这些不可逆转:
有时你可以找到 逆,如果这对你有用的话。在此,如果您保证input
介于0
和18
之间(即0x90 / 8
),则可以尝试
uint8_t input = 10;
uint8_t output = 0x90 - (input * 8); // spot two differences
uint8_t newInput = (0x90 - output) / 8;
但如果input
较大,例如20,则它会提供一些其他值来生成相同的output
。