The trick 'ABC'-'A' is that good programming style?
--- edit ---
"tag: goto" alludes to Edsger Dijkstra's famous letter ;-)
"tag: answer" is a trace of the reason why I submitted the question. I've seen questions by "new to Matlab", which have received answers including not so obvious code with "'ABC'-'A'" embedded for no good reason.
No products are associated with this question.
Adding or subtracting '0' is the most efficient method of converting between decimal-coded binary and character-coded binary.
Subtracting 'A' or 'a' (and then adding 10) is a well known and efficient conversion from character-encoded hexadecimal to binary.
Adding or subtracting ' ' (space) is used often in base64 encoding/decoding (e.g., MIME) [though you do need to special-case that binary 0 is coded as period instead of as space)
Adding or subtracting 32 used to be very common magic for converting between upper and lower-case ASCII. So common that it became a problem when dealing with EBCDIC and then later with ISO-8896-* and UNICODE. So common that this bug was hard to find, because programmers would read the 32, know that it was upper/lower case conversion, and then be puzzled that letters weren't being converted properly...
The characters '1' through '9' have been in consecutive coding positions since the ITA2 code of 1930. Any program that is not required to work with Baudot or Murray or older codes may assume that for a fact. Any program written the ASCII / ANSI / ISO / UNICODE line may assume that upper-case "Latin" (English) characters are consecutive, and that the lower-case "Latin" (English) characters are consecutive: this is a fundamental standardization no worse than assuming that all of the MATLAB operator characters are present in the character set. As best I know, MATLAB has never been supported on any EBCDIC-based system on which the assumption is not true.
To explicitly convert to numeric before doing arithmetic is faster. (Real reason: I find 'abc'-'a' confusing.:)
>> [ t1, t2 ] = cssm( 1e5 ) n1==n2 is true t1 = 0.3252 t2 = 0.0838 >>
function [ t1, t2 ] = cssm( N ) str = char(49:120); id1 = tic; for ii = 1 : N n1 = str - 'A'; end t1 = toc( id1 ); id2 = tic; for ii = 1 : N n2 = double( str ) - double('A'); end t2 = toc( id2 ); if all( n1 == n2 ) disp( 'n1==n2 is true' ) else disp( 'n1==n2 is false' ) end end
2016-07-18, Rerun of the test with R2016a. The first run was done with R2011a(?) and on the same old vanilla desktop.
>> [ t1, t2 ] = cssm( 1e5 ) n1==n2 is true t1 = 0.0327 t2 = 0.0214 >>
The new "JIT-engine" seems to be more efficient in this case. And the effect of using double is smaller.
Testing is tricky! In contrary to Jammes Tursa I see some advantage of the double() at the command line.
>> S = char('A'+floor(rand(1,1e7)*25)); >> clear a; tic; a = S - '0'; toc Elapsed time is 0.137705 seconds. >> clear a; tic; a = S - '0'; toc Elapsed time is 0.125812 seconds. >> >> clear a; tic; a = double(S) - double('0'); toc Elapsed time is 0.082686 seconds. >> clear a; tic; a = double(S) - double('0'); toc Elapsed time is 0.081962 seconds. >> clear a; tic; a = double(S) - double('0'); toc Elapsed time is 0.078693 seconds.
It depends. The result is clear and well defined, but not obvious. If you store large arrays in an M-file, char occupies less memory in the RAM than double arrays. But storing large data sets in M-files is a bad programming style already, because this mixes data and program.
I use 'abc' - 'a' only to encode icons in M-files, because it allows a vague view of the result.
color = ['CCCCCHFFHCCCCC'; ... 'CDFNBFFFFFFFDC'; ... 'DPGGGGGGGGGGBH'; ... 'DPDMMMMOOAADPD'; ... 'DFFFNFFFFFFFIH'; ... 'CILLKJGEKNGEIC'; ... 'CILBKJLGKFNKIC'; ... 'CILBKJLGKFIKIC'; ... 'CILBKJLGKFIKIC'; ... 'CDLBKJLGKFIKDC'; ... 'CDLBKJLGKFIKDC'; ... 'CDLBKJLGKFIKDC'; ... 'CDLBKJLGKFNKDC'; ... 'CDLLKJGEKNGEDC'; ... 'CHBGEEEGGLPNHC'; ... 'CMDDIIDDDDDHMC'] - ('A' - 1);
map = [28, 26, 36; ... 116, 118, 132; ... NaN, NaN, NaN; ... 73, 74, 89; ... 177, 176, 193; ... 96, 98, 112; ... 151, 152, 167; ... 60, 63, 76; ... 84, 84, 96; ... 220, 222, 236; ... 191, 193, 206; ... 135, 133, 143; ... 39, 41, 55; ... 108, 107, 118; ... 36, 34, 44; ... 124, 126, 140];
[x, y] = size(color); Icon = reshape(map(color, :) / 255, x, y, 3);
uicontrol('Position', [10, 10, 32, 32], 'CData', Icon);
This is, in my opinion, the best way to store an icon in an M-file. But icons can be stored and edited much more comfortable in graphic files.
I beleive that coding styles that sacrifice readibility for efficiency are generally bad style. It is possible that under some circumstances the gain in efficiency can offset the loss in readability. For example, in MATLAB loops used to be so slow that that we had to sacrifice readability for performance all the time by vectorizing everything. Thankfully that is not the case anymore.