I'm trying to reverse engineer a game function, which takes an integer and returns a 64-bit integer, by writing a function which returns the original value before it was put through the game function. How do I achieve this?
I have only managed to reverse these steps:
x = ((1 - x) << 16)
I'm not sure how to reverse the addition without the original value.
Here is the game function:
int64_t convert(int x) {
if (x <= 0)
return (1 - ((((x + 1) >> 31) + x + 1) >> 16));
else
return 0;
}
For example, if the original value was -5175633 then the converted value would be 80, I need to get the original value from 80.
I don't think this is possible. When you right-shift an integer, bits are lost. This means there are multiple input values that would return the same output value.
Sorry Victor, but your solution doesn't work. You ought to be comparing r and i, not c and cc.
Let's assume, with the step (1 - ((((x + 1) >> 31) + x + 1) >> 16)), x has converted to y, the we get:
y = 1 - ((((x + 1) >> 31) + x + 1) >> 16)
1 - y = (((x + 1) >> 31) + x + 1) >> 16
(1 - y) << 16 = (x + 1) >> 31 + x + 1
If x <= 0, then x + 1 <= 1. However this can't decide the sign bit. So we should assume once more.
if x + 1 < 0, then (x + 1) >> 31 is -1, which x < -1, y which is 1 - ((((x + 1) >> 31) + x + 1) >> 16), is 1 - (x >> 16)
(1 - y) << 16 = -1 + x + 1
(1 - y) << 16 = x
if x + 1 >= 0, then (x + 1) >> 31 is 0, which x >= -1, and y, which is 1 - ((((x + 1) >> 31) + x + 1) >> 16), is 1. (Note: now x can only be 0 or -1)
(1 - y) << 16 = x + 1
(1 - y) << 16 - 1 = x
So, include these two results together, we can get:
int reverse_convert(int64_t y) {
if (y == 1)
return (1 - y) << 16 - 1; // However, either x = 0 or x = 1 can produce this result.
else
return (1 - y) << 16;
// the condition of y == 0, corresponding to the original "else return 0;", is ignored.
}
Besides, the convert function is a Surjective-only function, which means multiple input can get the same output, then it is impossible to reverse precise output into input.
I will assume sizeof(int) is 4. And all the operations are done on 32 bits.
#include <iostream>
using namespace std;
int64_t convert(int32_t x) {
if (x <= 0)
return (1 - ((((x + 1) >> 31) + x + 1) >> 16));
else
return 0;
}
int32_t revconvert(int64_t r) {
if (r == 0) return 0;
if (r == 1) return -1;
return (1-r) << 16;
}
int main()
{
int32_t i;
for (i=0;i>-10000000;--i) {
auto c = convert(i);
auto r = revconvert(c);
auto cc = convert(r);
if( c!=cc) break;
}
cout << i << endl; // just to see if we got to the end
cout << convert(-5175633) << endl; // Will give 80
cout << revconvert(80) << endl; // Will give -5177344
cout << convert(-5177344) << endl; // Will give 80
return 0;
}
Related
4 integers are given (all no more than 10^6): m, n, k, l. If m % n == k or m % n == l, then print 1, else any other number. Conditional operators cannot be used!
Examples:
12 8 3 4 // input
1 // output
0 5 1 2 // input
0 // output
I wrote this code:
#include <iostream>
using namespace std;
int main()
{
int m, n, k, l;
cin >> m >> n >> k >> l;
cout << ((1 / (((m % (n + 1 / (n + 1))) - k) * ((m % (n + 1 / (n + 1))) - k) + 1)) - 1) * ((1 / (((m % (n + 1 / (n + 1))) - l) * ((m % (n + 1 / (n + 1))) - l) + 1)) - 1) + 1;
return 0;
}
But it does not work for all cases. For example, 0, 0, 0, 0 gives 1, but should give any other number.
Please help.
Note that there is no answer for n == 0 because division by zero is undefined.
In the other cases, since true prints as "1" and false as "0" by default,
cout << (m % n == l || m % n == k);
should do it.
what i understand from your question you are checking for 2 conditions, so after taking the input from the user we can check those conditions and assign value of val integer to 1 if that condition is true, else it will be 0 as initialized.
int m, n, k, l;
int val =0;
cin >> m >> n >> k >> l;
if(m % n == k || m % n == l){
val = 1;
}
cout << val ;
From what I understand I think you are trying to compare the modulus of two numbers with the other two inputs and if the result matches you want 1 as output otherwise 0
this will help you achieve it
#include <iostream>
using namespace std;
int main()
{
int m, n, k, l;
cin >> m >> n >> k >> l;
if(m%n == k || m%n == l)
{
count << 1
}
else
{
count << 0
}
return 0;
}
I have a 2d char array, of which I am trying to retrieve the value of an opposite side while on the edge. Instead of retrieving that value, it keeps returning with null. Can't make heads or tails of what the problem is. Here is the code I traced the problem to.
int xO = x; int yO = y;
//reassigns to opposite side of array
if ((x == 0) && (xM == - 1)) { xM = mapSize - 1; }
if ((x == mapSize - 1) && (xM == 1)) { xM = 0 - (mapSize - 1); }
if ((y == 0) && (yM == - 1)) { yM = mapSize - 1; }
if ((y == mapSize - 1) && (yM == 1)) { yM = 0 - (mapSize - 1);
}
//Checks 9 chars around and assigns any found characters
if (mapPlates[x + xM][y + yM] == 0) {
std::cout << "//" + std::to_string(x + xM) + ", " + std::to_string(yM + y) + "; " + std::to_string(mapPlates[x + xM][y + yM]) + "//";
}
if (mapPlates[x + xM][y + yM] =! "%") {
remaining--;
mapPlates[xO][yO] = mapPlates[x + xM][y + yM];
std::cout << "{assigned " + std::to_string(mapPlates[xO][yO]) + " }";
}
return remaining;
}
Snippet of output(only returns values == null)(should be returning '%'):
```//14, 49; 0////14, 0; 0////14, 1; 0////19, 49; 0////20, 49; 0////19, 0;
I did a recursive function to calculate x*y with x and y are all integers (x and y >= 0). My formula is:
x * y =
0, if x is equal 0
(x >> 1)*(y << 1), if x is an even number
(x >> 1)*(y << 1) + y, if x is an odd number
"<<" and ">>" are Left Shift and Right Shift Bitwise Operator. Here is my code:
int multiply(int x, int y) {
int y1 = 0;
if (x == 0) return 0;
else if (x % 3 == 0) {
y1 = y;
x = x >> 1;
y = y << 1;
return (multiply(x, y) + y1);
}
else if (x % 2 == 0) {
x = x >> 1;
y = y << 1;
return multiply(x, y);
}
}
The recursive function above is supposed to return (x*y) value but they were all wrong when i tested and i don't know why. What did i do wrong? How can i fix this?
Your problem is wit x % 3, what happens if x = 5? you skip it. Here is improved version of your code.
int multiply(int x, int y) {
if (x == 0)
return 0;
else if (x % 2 == 1)
return (multiply(x >> 1, y << 1) + y);
return multiply(x >> 1, y << 1);
}
or maybe even this:
int multiply(int x, int y) {
if (x == 0)
return 0;
int m = multiply(x >> 1, y << 1);
if (x % 2 == 1)
m += y;
return m;
}
Here is super fast version suggested by Andy:
int multiply(int x, int y) {
if (x == 0)
return 0;
int m = multiply(x >> 1, y << 1);
if (x & 1)
m += y;
return m;
}
As a challenge of speed, here is non recursive version:
int multiply (int x, int y) {
int y1 = 0;
for (; x > 0; x = (x >> 1), y = (y << 1))
if (x&1)
y1 += y;
return y1;
}
NOTE: I know this question is about recursive method but just as a challenge I wrote non-recursive algorithm.
You are not checking if x is odd correctly here:
else if (x % 3 == 0) { // e.g. fails on x = 1
Instead, you need to do
else if (x % 2 == 1) {
Here's a demo.
Note that this makes the following else check for even values of x redundant:
else if (x % 2 == 0) { // can just be an unconditional else
Also, since you are returning from the x == 0, and x % 2 == 1 branches, the else conditions can be removed as well. You can also factor out the repeated code to make the function simpler, like this:
int multiply(int x, int y) {
if (x == 0) return 0;
if (x % 2 == 1)
return (multiply(x >> 1, y << 1) + y);
else
return multiply(x >> 1, y << 1);
}
Here's a demo.
This is what i feel is the simplest approach to carry out recursive multiplication.
Do let me know if its efficient enough for you.
#include<iostream>
using namespace std;
float multiply(float a, float b) {
//no zeros bro
if (b == 0)
return 0;
//let the recursion begin
if (b > 0)
return x + multiply(a, b - 1);
//negatives stay away pliz
if (y < 0)
return -multiply(a, -b);
}
int main() {
float a, b, result;
cout << "Enter the two numbers";
cin >> a >> b;
result = multiply(a, b);
//And the result is.................
cout << result;
return 0;
}
Recursive function related to multiplication of natural numbers:
int multCool(int a, int b)
{
return (b==1 ? a: a+ multCool(a,b-1));
}
I have to print 8 terms of the sequence as
1, 2, 4, 8, 16, 22, 26, 38, ....
I have completed my logic till 16 that every new term is the previous term multiplied by 2. And after 16 the logic is that we divide that part into two as
26 = 22 + (2 * 2)
Till now what I have done is
int x = 1, num, num1, n = 1;
while (n <= 10)
{
while (n <= 4)
{
if (n == 1)
{
cout << x << ", ";
}
num = x % 10;
num1 = num % 10;
x = x * 2;
cout << x << ", ";
n++;
}
if (x == 16)
{
num = x % 10;
num1 = num % 10;
x = x + (num * num1) - 30;
cout << x << ", ";
}
else
{
num = x % 10;
num1 = num % 10;
x = x + (num * num1);
cout << x << ", ";
}
n++;
}
Apparently we just add the product of all digits to current number. That works fine for 1, 2, 4, 8 as well (e. g. 4 = 2 + (2)), so no need to have any special handling. However, apparently we need to ignore zeros, otherwise we wouldn't change after 102 any more...
So we can simplify the altorithm quite a bit:
unsigned int number = 1; // start value
std::cout << number; // OK, would require special handling for n == 0...
while(n--) // you could ask the user to input n or just set it to 10
// (I consider this variant a bit more elegant)
{
unsigned int product = 1;
unsigned int tmp = number;
// now iterate as long as you have more digits!
while(tmp)
{
unsigned int modulo = tmp % 10;
tmp /= 10;
// neat little trick: if modulo != 0, comparison is false, which is
// converted to 0, which is neutral for OR operation; otherwise, we
// get 0 | 1, which is neutral for multiplication...
product *= modulo | (modulo == 0);
}
number += product;
std::cout << ", " << number;
}
This would work fine even for fare more numbers than just the first ten ones (until overflow of either the product or the sum occurs...).
There seems to be some kind of misconception that this is for a contest.
I'm trying to work through an assignment and I've been stuck on this for an hour now.
/*
* isLessOrEqual - if x <= y then return 1, else return 0
* Example: isLessOrEqual(4,5) = 1.
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 24
* Rating: 3
*/
int isLessOrEqual(int x, int y)
{
int greater = (x + (~y + 1))>>31 & 1;
return !(greater)|(!(x^y));
}
I'm only able to use bitwise operators, as instructed in the comments.
I cannot figure out how to solve x <= y;
My thought process is that I can set x as its two's complement (~x +1) and add it with Y. If it is negative, X is greater than Y. Therefore, by negating that I can get the opposite effect.
Similarly, I know that !(x^y) is equivalent to x==y.
However,
doing !(greater)|(!(x^y)) does not return the proper value.
Where am I messing up? I feel like I'm missing a small bit of logic.
Those functions don't fully work because of the overflow, so that's how I solved the problem. Eh...
int isLessOrEqual(int x, int y) {
int diff_sgn = !(x>>31)^!(y>>31); //is 1 when signs are different
int a = diff_sgn & (x>>31); //diff signs and x is neg, gives 1
int b = !diff_sgn & !((y+(~x+1))>>31); //same signs and difference is pos or = 0, gives 1
int f = a | b;
return f;
}
If x > y, then y - x or (y + (~x + 1)) will be negative, hence the high bit will be 1, otherwise it will be 0. But we want x <= y, which is the negation of this.
/*
* isLessOrEqual - if x <= y then return 1, else return 0
* Example: isLessOrEqual(4,5) = 1.
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 24
* Rating: 3
*/
int isLessOrEqual(int x, int y)
{
return !(((y + (~x + 1)) >> 31) & 1);
}
Even better, drop the shift operator and use a bit mask on the high bit:
int isLessOrEqual(int x, int y)
{
return !((y + (~x + 1)) & 0x80000000);
}
EDIT:
As a commenter pointer out, the above version is susceptible to arithmetic overflow errors. Here is another version that covers the edge cases.
#include <limits>
int isLessOrEqual(int x, int y)
{
static int const vm = std::numeric_limits<int>::max();
static int const sm = ~vm;
return !! ((x & ~y | ~(x ^ y) & ~((y & vm) + ~(x & vm) + 1)) & sm);
}
Explanation: the overall strategy is to treat the sign bit of the inputs as logically distinct from the rest of the bits, the "value bits," and perform the subtraction as in the previous example on just the value bits. In this case, we need only perform the subtraction where the two inputs are either both negative or both non-negative. This avoids the arithmetic overflow condition.
Since the size of int strictly speaking is unknown at run time, we use std::numeric_limits<int>::max() as a convenient mask for the value bits. The mask of the sign bit is simply the bit-wise negation of the value bits.
Turning to the actual expression for <=, we factor out the bit-wise mask sm of the sign bit in each of the sub-expressions and push the operation to the outside of the expression. The first term of the logical expression x & ~y is true when x is negative and y is non-negative. The first factor of the next term ~(x ^ Y) is true when both are negative or both are non-negative. The second factor ~((y & vm) + ~(x & vm) + 1)) is true when y - x is non-negative, in other words x <= y, ignoring the sign bit. The two terms are or'd, so using c++ logical expression syntax we have:
x < 0 && y >= 0 || (x < 0 && y < 0 || x >= 0 && y >= 0) && y - x >= 0
The !! outermost operators convert the raised sign bit to a 1. Finally, here is the Modern C++ templated constexpr version:
template<typename T>
constexpr T isLessOrEqual(T x, T y)
{
using namespace std;
// compile time check that type T makes sense for this function
static_assert(is_integral<T>::value && is_signed<T>::value, "isLessOrEqual requires signed integral params");
T vm = numeric_limits<T>::max();
T sm = ~vm;
return !! ((x & ~y | ~(x ^ y) & ~((y & vm) + ~(x & vm) + 1)) & sm);
}
Really enjoyed Yanagar1's answer, which is very easy to understand.
Actually we can remove those shift operators and use De Morgan's laws, which reduce the number of operators from 15 to 11.
long isLessOrEqual(long x, long y) {
long sign = (x ^ y); // highest bit will be 1 if different sign
long diff = sign & x; // highest bit will be 1 if diff sign and neg x
long same = sign | (y + (~x + 1)); // De Morgan's Law with the following ~same
// highest bit will be 0 if same sign and y >= x
long result = !!((diff | ~same) & 0x8000000000000000L); // take highest bit(sign) here
return result;
}
Here is my implementation(spend around 3 hours...)
int
isLessOrEqual(int x, int y)
{
int a = y + ~x + 1;
int b = a & 1 << 31 & a; // !b => y >= x, but maybe overflow
int c = !!(x & (1 << 31)) & !(y & (1 << 31)); // y > 0, x < 0
int d = !(x & (1 << 31)) & !!(y & (1 << 31)); // x > 0, y < 0
int mask1 = !c + ~0;
// if y > 0 && x < 0, return 1. else return !b
int ans = ~mask1 & !b | mask1 & 1;
int mask2 = !d + ~0;
// if y < 0 && x > 0, return 0, else return ans
return ~mask2 & ans | mask2 & 0;
}
y - x == y + ~x + 1
a & 1 << 31 & a is simplify from !(!(a & (1 << 31)) | !a)
The logic is:
if `y > 0 && x < 0`
return true
if `x > 0 && y < 0`
return false
return y >= x
Why not just y >= x directly? because overflow may happen. So I have to early return to avoid overflow.
Inspired by Yanagar1's answer, here's my implementation:
int isLessOrEqual(int x, int y) {
int indicator = !((y + (~x + 1)) >> 31); // negation of the result of y - x, 0 when y < x, -1 when y >= x
int xsign = x >> 31; // -1 when x < 0, 0 when x >= 0
int ysign = y >> 31; // -1 when y < 0, 0 when y >= 0
int xbool = !xsign; // 0 when x < 0, 1 when x >= 0
int ybool = !ysign; // 0 when y < 0, 1 when y >= 0
int result = (!(xbool ^ ybool)) & indicator;
return result | (ybool & !xbool);
}
Explanation: Adding 2's complement negation of x (~x + 1) to y is essentially calculating y - x, then logical negate the sign bit of the result, we can have 0 when y < x, and 1 when y >= x. But there are potential overflow cases (overflow cannot happen when y and -x have opposite signs, that is, when y and x have same signs):
|-----------|------------------------|------------------------|
| | y > 0 | y < 0 |
|-----------|------------------------|------------------------|
| x > 0 | ok | overflow when y = TMin |
|-----------|------------------------|------------------------|
| x < 0 | overflow when x = TMin | ok |
|-----------|------------------------|------------------------|
so we need to be careful when the signs are different.
Might my solution is stupid.
int isLessOrEqual(int x, int y) {
/*
* A: sign bit of x B: sign bit of y C:A == B Result Rearrange the result(Expeced)
* 0 0 1 y - x >= 0 (y + (~x+1) >= 0) & 1 | 0 => (y + (~x+1) >= 0) & C | !(B | C)
* 0 1 0 0 (y + (~x+1) >= 0) & 0 | 0 => (y + (~x+1) >= 0) & C | !(B | C)
* 1 0 0 1 (y + (~x+1) >= 0) & 0 | 1 => (y + (~x+1) >= 0) & C | !(B | C)
* 1 1 1 y - x >= 0 (y + (~x+1) >= 0) & 1 | 0 => (y + (~x+1) >= 0) & C | !(B | C)
* But, minus operator is illegal. So (y - x) placed by (y + (-x)).
* You know -x == (~x + 1).
* If we know *x* and *y* have different sign bits, the answer is determinated and the (y-x >= 0) was useless.
* finally, the work like designing digital circuit. produce a final expression.
*/
int A = (x >> 31) & 1;
int B = (y >> 31) & 1;
int C = !(A ^ B);
int greatOrEqual0 = (!(((y + (~x + 1)) >> 31) ^ 0));
return (greatOrEqual0 & C) | !(B | C);
}