3

My question is in the following example what does val = val >> 2; do? That is I believe it is division by 4.

int val = 12345678;
val = val >> 2;

Here is the background to this question.

I have a read from a water meter, say 12345678. The way our water meters work is the two right-hand digits are thrown away for the read, so 123456 is really the read. (There are reasons for throwing away the two right hand digits that have to do with how water flow makes the registers turn. That really has nothing to do with my question, though.)

Currently, we are taking 12345678 and dividing it by 100, using 4GL integer variables, so I'm not getting a decimal number. We are getting truncation we do not expect, and I am trying to determine if bit shift would be better.

After the read is truncated to 123456, a delta is calculated using the last read (also truncated), and from that the consumption is generated.

I have C available to me in Informix 4GL, and I believe the best way to remove the lowest two digits would be to bit-shift right by 2. I believe that is the only way I am going to obtain -- for example --

5 digit meter   12345 --> 123
6  "     "     123456 --> 1234
7  "     "    1234567 --> 12345

Thank you for tolerating a simplistic question. We're trying to figure out a problem of how are endpoints -- which talk to the meters -- are programmed and what the data really means coming out of the endpoints.

octopusgrabbus
  • 10,555
  • 15
  • 68
  • 131
  • 1
    Shifting is only for powers of two. If you want to shift *decimal* digits, you need to divide. – Mysticial Jul 13 '12 at 18:28
  • 1
    @mystical that's not true - you can shift float values and receive very similar results under certain conditions, because of how they're stored. A classic example is http://en.wikipedia.org/wiki/Fast_inverse_square_root – corsiKa Jul 13 '12 at 18:31
  • 1
    @corsiKa "under certain conditions" - well yeah. You can use shifts for almost anything it isn't meant for "under certain conditions". – Mysticial Jul 13 '12 at 18:32
  • @Mysticial how is using it for floats "under certain conditions" but saying it's "only for powers of 2" not for certain conditions? The idea of using shifting for multiplication and division most definitely falls under the "certain conditions" you denounce. – corsiKa Jul 13 '12 at 18:39
  • @corsiKa There's no point in arguing over terminology. Since we clearly have different thresholds for "certain conditions". – Mysticial Jul 13 '12 at 18:41
  • @Mysticial I edited the question to include what the truncation method being used currently. I use integer variables, instead of decimal variables, and I should be taking away 123456 from 12345678 without the 78. I believe in the case our water department showed me today, one of the electronic endpoints is programmed incorrectly, and the read is coming through truncated before our software does anything with it. – octopusgrabbus Jul 13 '12 at 20:31
  • I4GL does not have a `>>` operator built-in; you'd have to call C code to do the job. As others have noted, you are wanting to divide by 100, but a right shift would divide by a power of two. You should just need to do `LET int_var = raw_data / 100` in your I4GL code; that should yield the correct value with the last two (decimal) digits dropped. – Jonathan Leffler Jul 15 '12 at 22:52

4 Answers4

10

Bit-shifting throws away the last two binary digits, not decimal digits. It is equivalent to integer division by four. You need to int-divide by 100 to throw away the last two decimal digits.

101111000110000101001110bin = 12345678dec

101111000110000101001110bin >> 2dec = 1011110001100001010011bin

1011110001100001010011bin = 3086419dec

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
4

'>>' performs a bitwise shift operation.

To understand what it does, you'd first convert 12345678 to binary.

12345678 = 100101101011010000111

'>>' means you shift each bit to the right, and in your example, 2 places. (<< shifts to the left)

100101101011010000111 >> 2 = 001001011010110100001

Then convert back to decimal: 308641

James
  • 2,823
  • 22
  • 17
1
12345678       : 101111000110000101001110
12345678 >> 2  : 1011110001100001010011
12345678 / 4   : 1011110001100001010011
Robbie Rosati
  • 1,205
  • 1
  • 9
  • 23
1

Within i4gl, you can easily cast the digits into a CHAR, truncate it [1,6], then cast it back to INT.

EDIT: See Type conversion in i4gl

Community
  • 1
  • 1
Joe R.
  • 2,032
  • 4
  • 36
  • 72
  • 1
    upvote for being the only answer that appears to actually solve the OP's problem :) – zwol Jul 14 '12 at 10:37
  • No need to call a cfunc, it can be done within your .4gl module. What version of i4gl and platform are you running on? – Joe R. Jul 14 '12 at 16:14