cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Choose Language Hide Translation Bar
docrossus
Level I

How does one perform Bitwise operations in JMP formulas?

Hi, I imagine this is simply an issue in which I am not finding the correct formula option but how does one perform basic bitwise operations in a JMP formula?

 

e.g. Here's an example Python example that I would like to replicate in JMP: lambda x: ((((x>>1)&0x1))<<2)

 

thanks, Ross

4 REPLIES 4
Craige_Hales
Super User

Re: How does one perform Bitwise operations in JMP formulas?

JMP has no native bitwise operators. In your example, I'd try this

 

// untested code for  (((x>>1)&0x1))<<2
f = function( { x },
    ( mod( floor( x / 2 ), 2 ) == 1 ) * 4
}

x>>1 (right shift 1) divides x by 2, &1 keeps only the least bit (zero/one, even/odd), and <<2 (left shift 2) multiplies by 4. (Assuming python works like C and I haven't forgotten...)

 

 

If you have a lot of these, with peculiar bit positions, etc, you might want to look for a bit manipulation library. The only one I'm aware of is in 7 things to know about Twitter and may not be very friendly (BITS.jsl file in the zip file). I don't remember exactly what it does, but it looks like it is solving the problem by turning a number into a character string of 32 ones and zeros, then combining the strings using AND/OR/etc logic rules. It is probably missing any operations that were not needed. And I'm pretty sure the HTTPRequest function would make that code much easier now.

 

Negative numbers can be really weird when doing right shifts. The sign bit can be trouble.

Craige
hogi
Level XI

Re: How does one perform Bitwise operations in JMP formulas?

hm ...
I added a request to the wishlist: JSL bit operations 
(@jthi already requested in 2020)

 

For now, (Jmp18), what is the fastest way to extract the 32 bits of a 32bit number?

... for 10 mio rows?

 

n_rows = 100000;
dt = New Table( "test", Add Rows( n_rows ), New Column( "rand int", Set each value( Random Integer( 0, 4294967295 ) ) ) );

checkBit = Function( {x, bit},
	(Mod( Floor( x / 2 ^ (0 + bit) ), 2 ) == 1)
);


t0 = HP Time();
For( i = 1, i <= 32, i++,
	dt << New Column( "bit" || Char(i), Set each value( checkBit( :rand int, i ) ) )
);
Show( (HP Time() - t0) / 1000000 ); // references

//BITS:NUMTOBITS from https://community.jmp.com/t5/Uncharted/7-things-to-know-about-Twitter/ba-p/21000
// faster
getBits = Function( {x},
	{result = {}, i},
	For( i = 4294967296 / 2, i >= 1, i /= 2,
		Insert Into(
			result,
			If( x >= i,
				x = x - i;
				1;
			,
				0
			)
		)
	);
	Transpose(Matrix(result));
);

// ~ factor 10 faster
getBits = Function( {x},
Transpose(Matrix(Transform Each({bit}, Words(Hex( x, Base( 2 ), Pad To( 32 ) ),""),Num(bit))));
);

//getBits(4294967295);

For( i = 1, i <= 32, i++,
	New Column( "bit" || Char( i ) )
);

t0 = HP Time();
mat = J( n_rows, 32, 0 );
For( myrow = 1, myrow <= n_rows, myrow++,
	mat[myrow, 0] = getBits( :rand int[myrow] )
);

dt[0, N Cols( dt ) - 31 :: N Cols( dt )] = mat;
Show( (HP Time() - t0) / 1000000 );
Craige_Hales
Super User

Re: How does one perform Bitwise operations in JMP formulas?

n_rows = 100000;
dt = New Table( "test", Add Rows( n_rows ), New Column( "rand int", Set each value( Random Integer( 0, 4294967295 ) ) ) );

t0 = HP Time();
data = dt[0, 1];
For( i = 1, i <= 32, i++,
	dt << New Column( "bit" || Char( i ) );
	dt[0,i + 1] = Mod( data, 2 );
	data = Floor( data / 2 );
);
Show( (HP Time() - t0) / 1000000 ); 

This moves most of the looping into C++ code. If you can figure out how to do it with one divide, you might speed it up some more. You might want to use b0 rather than b1 for the least significant bit's name so its value is 2^0==1. Depends what the bits represent.

Craige
hogi
Level XI

Re: How does one perform Bitwise operations in JMP formulas?

wow, great