I recently saw Steve Baker's web site while searching for something. It contains some cute (Steve's word) programming tricks and I thought I would show how to do a couple of these in MATLAB.
Contents
Power of Two Test
Here's the C code:
b = ((n&(n-1))==0) ;
and now the M code:
n = 1:8 ispow2 = bitand(n,n-1) == 0
n =
1 2 3 4 5 6 7 8
ispow2 =
1 1 0 1 0 0 0 1
Swap Two Integer Values
C code to swap integers x and y x = x ^ y ; y = x ^ y ; x = x ^ y ;
x = 3 y = 17 x = bitxor(x,y) y = bitxor(x,y) x = bitxor(x,y)
x =
3
y =
17
x =
18
y =
3
x =
17
Of course, I showed how to do this more easily a while ago using an anonymous function:
swap=@(varargin)varargin{nargin:-1:1};
x = 3
y = 17
[x,y] = swap(x,y)x =
3
y =
17
x =
17
y =
3
Force All Non-zeros to 1
The C code:
b = !!a ;
and the MATLAB code:
a = [0 1 3 0 5 7 9 0 -3 0 0]
b = +(a~=0) % use leading + to make result double instead of logical.a =
0 1 3 0 5 7 9 0 -3 0 0
b =
0 1 1 0 1 1 1 0 1 0 0
What Byte Order is My Computer?
The C code:
int i = 1 ;
little_endian = *((char *) &i ) ;and the MATLAB code:
a = uint16(1); b = typecast(a,'uint8') little = [1 0]; % big = [0 1]; islittle = isequal(b,little)
b =
1 0
islittle =
1
or
[omit, omit, endian] = computer
omit = 2.1475e+009 omit = 2.1475e+009 endian = L
Set Different Bits
Set the least significant bit to 0. Here's the C code.
n&(n-1)
and the M code:
n = uint8(0:7) lb1 = bitset(n,1,0)
n =
0 1 2 3 4 5 6 7
lb1 =
0 0 2 2 4 4 6 6
Other Tricks?
Share your MATLAB tricks with me.
Acknowledgment
Steve Eddins, famous for many things, including his blog on image processing, just updated one of our blog publishing tools, allowing you to see the code behind most of our posts with the push of a mouse button. Pretty cool, huh! Be sure to read his recent blog article about the default MATLAB image.
Get
the MATLAB code
Published with MATLAB® 7.3

I think we have talked about the tricks I used to use before (like using “if 2==a” instead of “if a==2″) I don’t use it anymore since it confuses other programmers and causes inconsistency but it is a little faster, and I also try to avoid division calculations in my code and use multiplication by the inverse of the number instead, I think I have described them in your “What Are You Really Measuring?” post
By the way, this “Get MATLAB code” is really cool but I think it has a bug and needs improvement,
in the browser it looks okay (I use Firefox) but I use your RSS feed most of the times to read Mathwork’s blogs and the problem is, the javascript behind the code is also shown in the RSS channel and makes the post ugly
For users with the same grabcode issue as Siamak about the RSS reader: there are readers without this issue, for example, Thunderbird or Sage.
–Loren
Hi Loren.
Swapping two integer values can be made through the deal function
[x,y] = deal(y,x);
But the deal function is probably slower.
Petr
I think there is a typo under section “Set Different Bits”, the give C code actually sets the least significant bit to 0. This is correct in Steve’s website.
Kevin-
Thanks! I fixed the typo.
–Loren
Force non-zeros to 1
On my AMD XP system at least the “C”-like code is faster. Does it have a worse memory overhead?
>> a = full(sprand(1000,1000,0.1));
>> tic;+(a~=0);toc
Elapsed time is 0.052537 seconds.
>> tic;~~a;toc
Elapsed time is 0.016447 seconds.
Richard-
If I put your statements in a function, I get different results and they are much closer on my laptop. The size calculation may be too small to be completely meaningful.
Elapsed time is 0.019397 seconds.
Elapsed time is 0.012486 seconds.
By the way, I wasn’t making any speed claims in this blog, just noting different ways one might compute certain logical and bitwise functions in MATLAB vs. C.
–Loren
Richard-
Actually, your two expressions aren’t the same. The first converts to double and the second stays logical (less memory allocation). I think the C code was trying to keep the datatype the same as well.
–Loren
Loren,
Great topic. Interesting stuff to this ‘non-programmer’.
May still be a problem in the “Set Different Bits” section tho. Typo in comment is fixed, but I think the MATLAB code shown is still setting the LSB to 1.
Should be “lb1 = bitset(n,1,0)”?
Thanks,
Jeff
Jeff-
Right you are again. Sorry I was so sloppy. It should be fixed now.
–Loren
A 40+ year programmer that I work with frequently says, “If it is clever, likely you shouldn’t use it.” Of course, this overstates it to make the point. Which is that the primary objective of code is to demonstrate clearly that it is doing the proper things. Dykstra advocated this approach some 40 years ago. We’ve found that clever coding is frequently less clear than other techniques.
When my co-worker & I reviewed this column, we had trouble understanding how these tricks were useful. e.g., we couldn’t easily see what function they were doing, or how it was useful.
However, I did learn something very useful and that was how to convert a logical MatLab variable to a number by preceding it with the “+”. This leads to the question, “Where is the MatLab function that does this? Something like, “logic2num”
Oliver-
If you want to convert it to double, just say double(x). Using the “constructor” is generally the way to do the conversion as well in MATLAB.
–Loren
I agree with Oliver that these clever tricks are interesting and fun, but unless you well document their use they can be confusing.
By the way, Oliver, the function that is run when you do +x is uplus (as in uplus(x)), but I agree with Loren that you should use the constructor and make the conversion explicit.
Loren,
one of the main reasons for writing such apparently obscure code in languages such as C is that it compiles to only one or two machine instructions on most processors and is therefore very fast - however, this is not at all the case with MATLAB’s bit… functions, which I perceive as painfully slow in comparison, unfortunately.
I did note your comment above that you’re not making any speed claims here - this isn’t meant in any way as a criticism of your blog, which I very much enjoy reading, thank you!
David
How about a leap year test?
isleap = @(x) isodd(sum(0 == mod(x, [4 100 400])));
where
isodd = @(x) mod(x,2);
and x has to be scalar due to dimension restriction in mod().
This comes from J, an array oriented language. In native J it looks like:
isleap =. 0: ~:/ .= 4 100 400 |/ ]
Here the input need not be scalar.
The interesting trick in J is when trying to determine if the result of mod() contains and even or odd number of zeros. It does this by “inserting” a not-equal in the output of the comparision test.
Inserting a function is a generalisation of summation where +/ 1 2 3 is the same as 1 + 2 + 3 ie insert a ‘+’ between the elements of the array. In our case we have ~:/ which says insert a “not equal” between the elements of the array. So we have one of the following cases:
1 ~: 1 ~: 1 => 1
0 ~: 1 ~: 1 => 0
1 ~: 0 ~: 1 => 0
1 ~: 1 ~: 0 => 0
1 ~: 0 ~: 0 => 1
0 ~: 1 ~: 0 => 1
0 ~: 0 ~: 1 => 1
0 ~: 0 ~: 0 => 0
where ~: is the same as ~= in matlab
/m
I should add that expressions in J are evaluated from right to left. Apart from the parans there are no operator precedence rules. So
1 ~: 1 ~: 1 is the same as (1 ~: (1 ~: 1))
/m
sir,
the codes mentioned above are very nice.i need matlab code for comparision of an image with another image that has already been stored in database.
Please make a shell extension and/or browser plug-in to right click and execute MATLAB code. Thank you. Feel free to contact me by email if needed.
David-
Here’s what we have in MATLAB now:
http://www.mathworks.com/access/helpdesk/help/techdoc/learn_matlab/f1-23058.html
the ability to evaluate selected code in the MATLAB supplied browser. See also
this page and look for “Evaluate a Selection”
I’ll pass along your suggestion.
–Loren
Thanks. More to the point I meant evaluating a selection from a web page. Unsure of how you would handle this if multiple instances of MATLAB were running, but I am sure you guys will think of something. Cheers.
One More Comment before I disappear…
>>data’
ans =
[1×74 char]
[1×82 char]
[1×80 char]
[1×81 char]
it would be nice if when displaying ans, the command window would have the index next to the data (e.g. 1,2,3,4 to the left of 1×74, 1×82,etc…). Thanks.
Hello!
I have another question, sorry if this is not a right blog.
I have to convert uint8 iamges to uint16 images by setting upper byte to 0. how can this be done? Is there any function, which opeates on whole image matrix or i have to convert each number/pixel value?
Thank…
Marko—Use the uint16 function.
but this function really does the upper (most important byte) equal to 0? i found that for example you can do this with “typecast” function, which combine 2 uint8 values to one uint16 and you have control on byte value and byte order…
Marko—uint16 does the operation you describe. typecast does not.
OK! very nice! Thank you for you help…but i have another questions, if you dont mind: how can i matlab open and save raw image files (iamge.raw)?
Marko-
Perhaps you could take this discussion off-line or with technical support as it is not on-topic for this blog article. Thank you.
-Loren