Я застрял, пытаясь изменить эту формулу - PullRequest
0 голосов
/ 15 января 2019

Я пытаюсь перепроектировать игровую функцию, которая берет целое число и возвращает 64-битное целое число, написав функцию, которая возвращает исходное значение до того, как оно было передано через игровую функцию. Как мне этого добиться?

Мне удалось только отменить эти шаги:

x = ((1 - x) << 16)

Я не уверен, как отменить добавление без исходного значения.

Вот функция игры:

int64_t convert(int x) {
  if (x <= 0)
    return (1 - ((((x + 1) >> 31) + x + 1) >> 16));
  else
    return 0;
}

Например, если исходное значение было -5175633, то преобразованное значение было бы 80, мне нужно получить исходное значение из 80.

Ответы [ 3 ]

0 голосов
/ 15 января 2019

Я предполагаю, что sizeof (int) равен 4. И все операции выполняются на 32 битах.

#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;
}
0 голосов
/ 15 января 2019

Предположим, с шагом (1 - ((((x + 1) >> 31) + x + 1) >> 16)), x преобразованным в y, получаем:

y = 1 - ((((x + 1) >> 31) + x + 1) >> 16)
1 - y = (((x + 1) >> 31) + x + 1) >> 16
(1 - y) << 16 = (x + 1) >> 31 + x + 1

Если x <= 0, то <code>x + 1 <=1. Однако это не может решить бит знака.Таким образом, мы должны предположить еще раз. </p>

, если x + 1 <0, то <code>(x + 1) >> 31 равно -1, что x <-1, <code>y, что 1 - ((((x + 1) >> 31) + x + 1) >> 16), равно 1 - (x >> 16)

(1 - y) << 16 = -1 + x + 1
(1 - y) << 16 = x

если x + 1> = 0, то (x + 1) >> 31 равно 0, что x> = -1, а y, что составляет 1 - ((((x + 1) >> 31) + x + 1) >> 16), равно 1. (Примечание: теперь x может быть только 0 или -1 )

(1 - y) << 16 = x + 1
(1 - y) << 16 - 1 = x

Итак, включив эти два результата вместе, мы можем получить:

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.
}

Кроме того, convert функция - это только для сюръективной функции , что означает, что несколько входов могут получить один и тот же выход, и тогда невозможно обратить точный выходной сигнал на вход.

0 голосов
/ 15 января 2019

Я не думаю, что это возможно. Когда вы сдвигаете целое число вправо, биты будут потеряны. Это означает, что есть несколько входных значений, которые возвращали бы одно и то же выходное значение.

Извините, Виктор, но ваше решение не работает. Вы должны сравнивать r и i, а не c и cc.

...