Hello! I write a script in php. There are numbers:
16359391
15382371
7177275
15318085
16431130

An example of numbers from the program, with each number, occurs >> 8 and it turns out that the number is smaller, and when doing a bitwise shift with a result of only 8, the value with the initial does not converge. Tell me how to make a bitwise shift without losing numbers and so that when shifting to one of the sides the number was 2 digits less long? or maybe there is some other option? The most important thing in the task is to reduce this number by 2 digits and so that it can be transferred back to the initial number. It should be something like this for different numbers:
16359391
63903
16359391

UPD:

Here is an example code: There is a table

$table = array( 0x003b6c1c, 0x002def61, 0x006effa2, 0x0013045f, 0x00873358, 0x0039e1fd, 0x0061491a, 0x002608bf, 0x00254ed0, 0x004fc7dd, 0x00721a32, 0x0018dce3, 0x001328bc, 0x003e288d, 0x0084387e, 0x004c11e3); $table_index = 13; $b = 16359391; $result = $b ^ $table[$table_index]; $resultfinal = ($result >> 8).$table_index; 

And with $ resultfinal you need to get 16359391, given that the initial value and the index in the table are unknown, only the last value is known.

  • How do you imagine it? If you reduce the length of the number, then how to return the lost numbers? - pavel
  • What is it not for you to divide by 100, and if necessary, output the whole part? It is better to describe the essence of the problem, why do you need it at all? - teran
  • lossless shift - cyclic shift. Arithmetic and cyclic - the concepts are different, the numbers will come out quite different. - nick_n_a
  • Corrected your question. I understand that you do not know $table_index and $b , but only $result is known from which you need to get the initial number? There you have $ result via XOR is calculated, right? - rjhdby
  • a bit of an error in the code instead of $ resultfinal = ($ b >> 8). $ table_index; you need $ resultfinal = ($ result >> 8). $ table_index; and so true, yes, it's just that $ result >> 8 is written to the $ resultfinal variable and 2 digits are added (value index in the table) - Aleks

1 answer 1

How the bit shift works.

Consider a very simple case, for a single unsigned byte and without overflows.

Suppose we have 1 byte equal to FF . In binary representation it will be 11111111

Shift it to the right 11111111 >> 1 = 0111111 . The extreme right unit is lost. All right. How nebylo. Now let's 01111111 << 1 = 11111110 resulting number back to the left 01111111 << 1 = 11111110

If the first operation is shifted to the left, then absolutely the same principle will lose the initial bit.

Now about your case. Since PHP operates with dynamic type conversion, it is possible (within reasonable limits) to take advantage of the knowledge that a bit left shift is equivalent to multiplying by 2 (on an infinite number of bits), and a right shift is equivalent to dividing by two.

Those. To solve your problem, you need to use not the shift, but the mathematical operations of multiplication and division.

 $a = 16359391; $a_shifted = $a / (2*2*2*2*2*2*2*2); // аналогично $a >> 8 $a_unshifted = $a_shifted * (2*2*2*2*2*2*2*2); // аналогично $a_shifted << 8 

But here we must understand that in this case you may have an int to float conversion with a possible loss of accuracy.

  • may still have any options to perform this task? can try to translate the number into a binary number system and, using some algorithm, compress the binary number, and then convert to decimal, and the output will be an integer but less. Do not know about such algorithms? - Aleks
  • @Aleks I have a suspicion that you are trying to tighten the nails with a screwdriver instead of using a hammer. What is the ultimate goal? Why do you need a shift? - rjhdby
  • I need not necessarily a shift, any operations with a number, the main thing is that it can be used to get the number 2 less numbers and without losses back to get the initial value from this number - Aleks
  • one
    @Aleks in the formulation of the problem, as you describe it, it has no solution. Try still to describe a more global goal. For example, why do you need two digits less? On the screen to display? Store in DB? for what? - rjhdby
  • Here is a sample of the code: there is a table $ table_index = 13; $ b = 16359391; $ result = $ b ^ $ table [$ table_index]; $ resultfinal = ($ b >> 8). $ table_index; And with $ resultfinal you need to get 16359391, given that the initial value and the index in the table are unknown, only the last value is known. - Aleks