C# help
#21
Posted 09 March 2011 - 08:43 AM
Mario
#22
Posted 09 March 2011 - 10:01 AM
Unfortunately, the current implementation of .NET Micro Framework does not contain neither BitArray nor BitVector32 (they may be considered for future versions), but you can use &,|,~,^ bitwise operators as you know them from C/C++:But I could't find any useful implementation or API to get or set binary values like I can do in C.
if((bits & 0x01) == 0x01) // Test 0. bit { bits |= 0x80; // Set 7. bit } else { bits &= ~0x02; // Clear 1. bit }
You can pack up to 32 bits in 'int', resp. 64 bits in 'long' variables, and you can use byte/int/long array to store more bits or emulate bit matrices.
byte[] array100bits = new byte[(100+7)/8]; // Round up to whole bytes void SetBit(byte[] bits, int index, bool value = true) { var byteIndex = index/8; var mask = (byte)(1 << (index % 8)); if(value) { bits[byteIndex] |= mask; } else { bits[byteIndex] &= (byte)~mask; // Note: ~ operator converts to int } } const int M = 10; const int N = 10; byte[] matrix = new byte[(M*N + 7)/8]; void SetBit(int x, int y, bool value = true) { // TODO: Parameter validation (omitted for the sake of clarity) SetBit(matrix, x + y*M, value); }Note: The actual formulas may vary depending on the size of array element, padding, 'coordinate system' etc.
#23
Posted 09 March 2011 - 03:29 PM
#24
Posted 09 March 2011 - 03:41 PM
ok, this is clear enaugh now. How I can solve my Problem with the Debugger showing '?' as values for my Bytes?
Sorry, but I did not understand where the debugger shows you "?" instead of the byte value.
Mario
#25
Posted 09 March 2011 - 05:14 PM
In my Code if I'm debugging arrays of arrays of Byte. Looks for example like thisSorry, but I did not understand where the debugger shows you "?" instead of the byte value.
Mario
http://img845.images.../debuggerc.png/
seems, that I'm not allowed to uplad Image Data, so I insert the link
#26
Posted 10 March 2011 - 06:39 AM
About the (jagged) array.
I checked the picture and your code. It seems that you have placed a breakpoint just *before* the evaluation of "shiftPattern": the break stops *before* executing that line. So far, the debugger shows an undefined jagged array.
IMHO, jagged arrays are something confusing, without strong rule: there's very few compile-time checking support. I'd prefer 1000 times better somethink like this:
public class PatternRow { private static int[] ColumnMask = new int[] { 0x01, 0x010, 0x0100, 0x01000, 0x010000, } public PatternRow(params int[] rows) { this._rows = rows; } private int[] _rows; public bool GetCell(int row, int column) { int row = this._rows[row]; return (row & ColumnMask[column]) != 0; } } public class FiveToSevenPattern : DotMatrixPattern { // ... public PatternRow A = new PatternRow( 0x11111, 0x10001, 0x10001, 0x10001, 0x11111, 0x10001, 0x10001); // ... }Thus your code should be different than now, but it looks much more elegant and error-proof.
I guess that eats much less memory because there are lots of array missing. However you may avoid even the array in the PatternRow class.
About VS Express, the answer is "NO". Basically, the difference between Express and $$$ versions, are on the quantity of satellite tools, plugins and whatever else. For home work I use Express and I've done very huge professional apps too. $$$ version (I'm using at office) is more straightforward for certain functions...Anyway, as far I know, there is *NO* less core functionality in the Express edition.
IL-Disassembler.
The disassembly could be easily done via MSIL Disassebler tool, that comes free with the Windows SDK. Search in the internet for the download.
http://msdn.microsof...1k1(VS.80).aspx
NOTE: these are *NOT* the native CPU opcodes, but the portable-instructions generated by the C# compiler. In the .Net framework there is a Just-in-time (JIT) compiling of these opcodes to native code. In the Net Micro that post-compilation is made at the deploy phase, I think.
var.
The reason for the "var" statement is quite confusing if you have few friendship with C#. There's *NO* relation with Javascript.
I'd suggest to avoid using "var", until you have enough experience with the language.
By the way, "var" is the "lazy programmers" shortcut to the generics.
Cheers
#27
Posted 10 March 2011 - 04:25 PM
public class Program { public static void Main(string[] args) { } public class PatternRow { public PatternRow(params int[] rows) { this._rows = rows; } private int[] _rows; } public static class FiveToSevenPattern { public static PatternRow A=new PatternRow( 0x11111, 0x10001, 0x10001, 0x10001, 0x11111, 0x10001, 0x10001); #if false public static PatternRow B=new PatternRow( 0x11110, 0x10001, 0x10001, 0x10010, 0x10001, 0x10001, 0x11110); #endif #if false public static PatternRow C=new PatternRow( 0x01111, 0x10000, 0x10000, 0x10000, 0x10000, 0x10000, 0x01111); #endif #if false public static PatternRow D=new PatternRow( 0x11110, 0x10001, 0x10001, 0x10001, 0x10001, 0x10001, 0x11110); #endif } }
- As shown: 504 bytes
- With B enabled: 580 bytes
- With B and C enabled: 660 bytes
- With B,C,D enabled: 736 bytes
(For all the measurements I'm referring to the size of the .pe file which is what gets deployed to the device)
You probably really ought to compile the binary data offline and store it in an embedded resource. However, if you really want to pack it into a nice-looking C# source array, I believe that the following is the best you can do:
public class Program { public static void Main(string[] args) { } public static class AllPatterns { //note that at the moment most of these constants are currently unused //but I include them here for completeness private const byte _____=0x00; private const byte ____X=0x01; private const byte ___X_=0x02; private const byte ___XX=0x03; private const byte __X__=0x04; private const byte __X_X=0x05; private const byte __XX_=0x06; private const byte __XXX=0x07; private const byte _X___=0x08; private const byte _X__X=0x09; private const byte _X_X_=0x0A; private const byte _X_XX=0x0B; private const byte _XX__=0x0C; private const byte _XX_X=0x0D; private const byte _XXX_=0x0E; private const byte _XXXX=0x0F; private const byte X____=0x10; private const byte X___X=0x11; private const byte X__X_=0x12; private const byte X__XX=0x13; private const byte X_X__=0x14; private const byte X_X_X=0x15; private const byte X_XX_=0x16; private const byte X_XXX=0x17; private const byte XX___=0x18; private const byte XX__X=0x19; private const byte XX_X_=0x1A; private const byte XX_XX=0x1B; private const byte XXX__=0x1C; private const byte XXX_X=0x1D; private const byte XXXX_=0x1E; private const byte XXXXX=0x1F; public static readonly byte[] data= { _XXX_ , X___X , X___X , X___X , XXXXX , X___X , X___X , #if false XXXX_ , X___X , X___X , XXXX_ , X___X , X___X , XXXX_ , #endif #if false _XXXX , X____ , X____ , X____ , X____ , X____ , _XXXX , #endif #if false XXXX_ , X___X , X___X , X___X , X___X , X___X , XXXX_ , #endif }; }; }Here are the stats for this representation:
- As shown (with only A enabled): 588 bytes
- With B enabled: 600 bytes
- With B and C enabled: 604 bytes
- With B,C,D enabled: 612 bytes
- ...
- With 101 character entries: 1292 bytes
...which averages out to 7 bytes per character which is what you would expect. You can find a given character at an array offset = (7 times its index)
I disagree with both points. var is a very intuitive and productivity-enhancing language feature which has nothing in common with generics. If you're in a situation where you're uncertain about what type your variable has, just hover your mouse pointer over the word "var". Using var is not a sign of laziness but instead an acknowledgement of the fact that computers are supposed to work for humans, rather than the other way around.I'd suggest to avoid using "var", until you have enough experience with the language.
By the way, "var" is the "lazy programmers" shortcut to the generics.
#28
Posted 10 March 2011 - 04:54 PM
I agree totally on the solution pre-compiled: it would be the best. Your solution is somewhere elegant though.
About "var".
I know how/when use the "var", but a novice programmer could fall easily to confusion: that is what I have noticed among my friends.
Let's take an example:
var b = false; var d = 12; var i = 3.14; var t = "Hello!";Here is pretty straightforward that "b is boolean" and "t is string". Maybe you may also understand that "i is real"...but float, double or decimal?
You *must* know that is a double, otherwise there'll be a suffix.
Another common question about "var" is:
class C { var id = "ciao"; //no doubt that is a string! }why can not I write that, but inside a routine do?
http://blogs.msdn.co...-on-fields.aspx
That's confusing for novice people, so I'd prefer to unsuggest to Ruff (he's comparing to Javascript "var"...)
By other hands, when I write:
var result = from item in collection group item by item.Key into g select new { Id=g.Key, Items=g }...it's *not* straightforward to understand what is the type of result and -more- it would be less readable.
That is *my* opinion and your's is fully respectable indeed.
Cheers
Mario
#29
Posted 13 March 2011 - 10:39 PM
#30
Posted 13 March 2011 - 11:32 PM
You just need to do some simple bit manipulations. Does this program help you to see what needs to be done?I see no real correlation of these Values or how to get the next 'X' or '_' from column[x] of B to calculate what will be the next row const to show.
using Microsoft.SPOT; public class Program { public static void Main(string[] args) { for(var j=0; j<7; ++j) { Show(0x0E, 0x1E, j); } } private static void Show(int byte0, int byte1, int shift) { var leftByte=byte0<<shift; var rightByte=byte1>>(6-shift); var result=(leftByte|rightByte)&0x1f; Debug.Print("0x"+MakeHex((byte)result)); } private static string MakeHex(byte b ) { const string digits="0123456789ABCDEF"; return ""+digits[b>>4]+digits[b&0xf]; } }
Output:
0x0E 0x1C 0x19 0x13 0x07 0x0F 0x1E
#31
Posted 14 March 2011 - 02:28 PM
#32
Posted 15 March 2011 - 02:10 AM
Let's see if I can demystify it. I'm probably being too verbose here, but probably better to provide too much rather than too little detail.
I can only look at it, and feel frustrated.
byte0 is some 5-bit sequence of bits, say, abcde
byte1 is also a 5-bit sequence of bits, say, vwxyz
Your goal is to display some 5-bit subsequence of abcde0vwxyz (notice the 0 in there because you want a 'space' between them)
As a first step, we can form abcde0vwxyz with this expression
var temp=(byte0<<6) | byte1;
Now, to extract the proper 5-bit subsequence we want to shift abcde0vwxyz in such a way that the 5 bits we want are in the five rightmost positions:
- if shift is 0, we want to shift our pattern right 6 (forming abcde)
- if shift is 1, we want to shift it right 5 (forming abcde0, whose 5 rightmost bits are bcde0)
- if shift is 2, we want to shift it right 4 (forming abcde0v, whose 5 rightmost bits are cde0v)
- etc...
Now, since 0 goes to 6, 1 goes to 5, etc, the formula for the amount to shift right is (6-shift)
Therefore we need to shift temp to the right by this amount:
var temp2=temp>>(6-shift);...and finally we want to mask off the low 5 bits
var result=temp2&0x1f;
Putting it all together:
var temp=(byte0<<6) | byte1; var temp2=temp>>(6-shift); var result=temp2&0x1f;Now we can try to 'optimize' this code by combining temp and temp2:
var temp2=(byte0<<6 | byte1) >> (6-shift)
expands to
var temp2=(byte0<<6) >> (6-shift) | byte1 >> (6-shift)which expands to
var temp2=((byte0 << 6) >> 6) >> -shift | byte1 >> (6-shift)
which finally simplifies to (because the 6's cancel and because a negative shift reverses the direction of the >> operator)
var temp2=(byte0 << shift) | (byte1>>(6-shift))which should look enough like my code that you can take it from there (don't forget to mask with 0x1f at the end).
Regarding var, most of the time you want to use 'byte' is to save space (e.g. because you have an array of 1000 bytes. It usually isn't very useful to use byte as a local variable type (unless you really care about the numerical behavior of 8-bit unsigned math operations) because ints are at least as fast, if not faster, and generally won't take up any more space when used as local variables. So in this case I use var so the language can default to whatever it wants to do and I do the casting to 'byte' at the end if my program needs it.
- Ruff likes this
#33
Posted 15 March 2011 - 02:17 AM
...
what is the benefit in THIS example to use
'var leftByte=byte0<<shift;'
than:
'byte leftByte=byte0<<shift;'
isn't it really clear that we will get a byte as return value? Or is the 'real' result of leftByte=0x0E<<1 == 000111000, so one bit too much for byte and we have to sign it as var instead of converting it?
It is clear that the values are bytes, but the use of "var" is harder to read (i.e. not as obvious to someone who didn't write the code as reading the more specific "byte"). The compiler may or may not see the overflow in your last example. My guess is that it wouldn't, but I've been surprised before.
So, in THIS example, it's not a good use of var. In fact, there may not be a good reason for using var in the Compact Framework. If you get involved with the full-blown .Net Framework, however, there are cases where the use of var can save some significant typing. (If you're curious, look up LINQ and anonymous types.)
#34
Posted 15 March 2011 - 02:55 AM
It is clear that the values are bytes,
In fact the types are ints. I don't use the byte type until the very end of the routine where I need it. I daresay this makes the code clearer since there isn't any monkey business with any type other than int until the end.
The reluctance to use var seems to be a cultural thing that I don't understand. In case there is any doubt about my own vote, it is wholeheartedly on the side of using it everywhere that one can. The IDE stands ready to tell you what type a variable is simply by hovering your mouse over the word 'var'. Anyway, maybe someone wants to start a separate 'var' thread on this forum where we can argue the point.
private static void Show(int byte0, int byte1, int shift) { var leftByte=byte0<<shift; var rightByte=byte1>>(6-shift); var result=(leftByte|rightByte)&0x1f; Debug.Print("0x"+MakeHex((byte)result)); }
#35
Posted 15 March 2011 - 05:09 AM
Corey, we both know that wasn't a byte but an int instead. The "problem" is about the reader, especially when he doesn't know so well the language and what's behind.In fact the types are ints. I don't use the byte type until the very end of the routine where I need it. I daresay this makes the code clearer since there isn't any monkey business with any type other than int until the end.
From my viewpoint, the absolute priority on a program source is the readiness. .Net allows to build huge applications keeping well-ordered your work even with hundreds of modules. When I take a peek to a function, I'd like to understand at a glance what it does.
As for me this sounds like why Linq is usually preferable than a simple foreach: Linq is a lot slower, eats more memory, etc.
But...it's *very* clear!...
It is not a reluctance, but some good practice says that you should keep always clear the data involved in whatever operation.The reluctance to use var seems to be a cultural thing that I don't understand.
The IDE could be an help, but not a "must". If you were posting a code in this forum, what kind of tip may I have?The IDE stands ready to tell you what type a variable is simply by hovering your mouse over the word 'var'.
Anyway, I fully respect your viewpoints: my habit is just to use "var" wherever is clear and/or convenient.
Tell me, if you were a student learning C#, don't you wonder why these lines are not legal?
class Foo { private var _name = "Corey"; //not legal private string _country = "USA"; //OK void DoWork(var optionalField = 3.14159d) //not legal { // ... } }Cheers
Mario
0 user(s) are reading this topic
0 members, 0 guests, 0 anonymous users