www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - byte + single-bit-operations

reply "Alexander Panek" <alexander.panek brainsware.org> writes:
hello,

just wondered if there`s a common way to edit single bits in a byte? in C  
and C++ there were only crappy 'workarounds', but as D has a single-bit  
datatype it would be great to have an operator to read/write single bits  
in a byte-variable.

thanks for help,
alex

-- 
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
Mar 15 2005
parent reply =?ISO-8859-15?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Alexander Panek wrote:

 just wondered if there`s a common way to edit single bits in a byte? in 
 C  and C++ there were only crappy 'workarounds', but as D has a 
 single-bit  datatype it would be great to have an operator to read/write 
 single bits  in a byte-variable.

Use the bit[] type. Just be aware that it always aligns the memory used to even powers of 32 bits (4 bytes), if unioned with for instance byte. See http://www.prowiki.org/wiki4d/wiki.cgi?BitsAndBools --anders
Mar 15 2005
parent reply "Alexander Panek" <alexander.panek brainsware.org> writes:
On Tue, 15 Mar 2005 21:23:23 +0100, Anders F Björklund <afb algonet.se>  
wrote:

 Alexander Panek wrote:

 just wondered if there`s a common way to edit single bits in a byte? in  
 C  and C++ there were only crappy 'workarounds', but as D has a  
 single-bit  datatype it would be great to have an operator to  
 read/write single bits  in a byte-variable.

Use the bit[] type. Just be aware that it always aligns the memory used to even powers of 32 bits (4 bytes), if unioned with for instance byte. See http://www.prowiki.org/wiki4d/wiki.cgi?BitsAndBools --anders

Well, I use a bit-array. But it seems like the compiler does not want me to do this :o ! I use this code to copy a bit out of a byte into a bit-variable: [code] while(offset_ascii < 8) { result[offset_sms] = (b & (true << offset_ascii++)) << offset_sms++; // line 18 } [/code] DMD gives me this error: " smscode.d(18): cannot implicitly convert expression (cast(int)(b) & 1 << offset_ascii++) of type int to bit " Thanks, an hopefully Alex ;) -- Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
Mar 15 2005
next sibling parent reply =?ISO-8859-15?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Alexander Panek wrote:

 I use this code to copy a bit out of a byte into a bit-variable:
 
 [code]
 while(offset_ascii < 8) {
     result[offset_sms] = (b & (true << offset_ascii++)) << offset_sms++; 
 //  line 18
 }
 [/code]
 
 DMD gives me this error:
 " smscode.d(18): cannot implicitly convert expression (cast(int)(b) & 1 
 <<  offset_ascii++) of type int to bit "

Please pick either of bit-arrays or bit-shifting, but not both at once? That is, either: bit b; // value int bitno; // index bit[] array; array[bitno] = b; Or, alternatively: bit b; // value int bitno; // index byte[] array; if (b) array[bitno >> 3] &= ~(1 << (bitno & 7); // set bit else array[bitno >> 3] |= 1 << (bitno & 7); // clear bit HTH, --anders
Mar 15 2005
next sibling parent =?ISO-8859-15?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Anders F Björklund wrote:

 if (b)
   array[bitno >> 3] &= ~(1 << (bitno & 7); // set bit
 else
   array[bitno >> 3] |= 1 << (bitno & 7); // clear bit

Darnit. Seems to be typo-day today. :-( if (b) array[bitno >> 3] |= 1 << (bitno & 7); // set bit else array[bitno >> 3] &= ~(1 << (bitno & 7); // clear bit --anders
Mar 15 2005
prev sibling parent reply "Alexander Panek" <alexander.panek brainsware.org> writes:
On Tue, 15 Mar 2005 22:14:34 +0100, Anders F Björklund <afb algonet.se>  
wrote:

 Alexander Panek wrote:

 I use this code to copy a bit out of a byte into a bit-variable:
  [code]
 while(offset_ascii < 8) {
     result[offset_sms] = (b & (true << offset_ascii++)) <<  
 offset_sms++; //  line 18
 }
 [/code]
  DMD gives me this error:
 " smscode.d(18): cannot implicitly convert expression (cast(int)(b) & 1  
 <<  offset_ascii++) of type int to bit "

Please pick either of bit-arrays or bit-shifting, but not both at once? That is, either: bit b; // value int bitno; // index bit[] array; array[bitno] = b; Or, alternatively: bit b; // value int bitno; // index byte[] array; if (b) array[bitno >> 3] &= ~(1 << (bitno & 7); // set bit else array[bitno >> 3] |= 1 << (bitno & 7); // clear bit HTH, --anders

I have to use both, because I get a byte-array ( byte[] ) and I don`t know any other way to get the first 7 bits out of every byte. That`s the whole function: bit [] toSMSCode(byte[] ascii) { bit [] result; int offset_sms, offset_ascii; offset_sms = 0; offset_ascii = 0; foreach(byte b; ascii) { while(offset_ascii < 8) { result[offset_sms] = (b & (true << offset_ascii++)) << offset_sms++; } offset_ascii = 0; } return result; } It (should) converts ASCII-strings to SMS-coded-strings (only 7bits of 8 used, so the string gets smaller). Thanks for giving trouble, Alex -- Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
Mar 15 2005
parent =?ISO-8859-15?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Alexander Panek wrote:

 I have to use both, because I get a byte-array ( byte[] ) and I don`t 
 know  any other way to get the first 7 bits out of every byte.

OK, thanks for clearifying...
 That`s the whole function:

             result[offset_sms] = (b & (true << offset_ascii++)) << 
 offset_sms++;

Assuming the other logic is OK, this line should be: result[offset_sms++] = (b & (1 << offset_ascii++)) != 0; I think that you can take it from here, if it's not... (for instance, you need to set a result.length first) --anders
Mar 15 2005
prev sibling next sibling parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Tue, 15 Mar 2005 22:05:36 +0100, Alexander Panek  
<alexander.panek brainsware.org> wrote:
 On Tue, 15 Mar 2005 21:23:23 +0100, Anders F Björklund <afb algonet.se>  
 wrote:

 Alexander Panek wrote:

 just wondered if there`s a common way to edit single bits in a byte?  
 in C  and C++ there were only crappy 'workarounds', but as D has a  
 single-bit  datatype it would be great to have an operator to  
 read/write single bits  in a byte-variable.

Use the bit[] type. Just be aware that it always aligns the memory used to even powers of 32 bits (4 bytes), if unioned with for instance byte. See http://www.prowiki.org/wiki4d/wiki.cgi?BitsAndBools --anders

Well, I use a bit-array. But it seems like the compiler does not want me to do this :o ! I use this code to copy a bit out of a byte into a bit-variable: [code] while(offset_ascii < 8) { result[offset_sms] = (b & (true << offset_ascii++)) << offset_sms++; // line 18 } [/code] DMD gives me this error: " smscode.d(18): cannot implicitly convert expression (cast(int)(b) & 1 << offset_ascii++) of type int to bit " Thanks, an hopefully Alex ;)

You might find this helpful. # import std.stdio; # # void main() # { # byte b; # short s; # int i; # long l; # int[] ia; # bit[] a; # # //slice a byte # a = (cast(bit*)&b)[0..8]; # a[0] = 1; //2^0 == 1 # a[6] = 1; //2^6 == 64 # writefln("byte(",b,")"); //65 # # //slice a short # a = (cast(bit*)&s)[0..16]; # a[3] = 1; //2^3 == 8 # a[14] = 1; //2^14 == 16384 # writefln("short(",s,")"); //16392 # # //slice an int # a = (cast(bit*)&i)[0..32]; # a[5] = 1; //2^5 == 32 # a[22] = 1; //2^22 == 4194304 # writefln("int(",i,")"); //4194336 # # //slice a long # a = (cast(bit*)&l)[0..64]; # a[25] = 1; //2^25 == 33554432 # a[45] = 1; //2^45 == 35184372088832 # writefln("long(",l,")"); //35184405643264 # //WTF?! this prints 35184372088832 # writefln(a[25]); # writefln(a[45]); # # //or even slice an array of 10 ints # ia.length = 10; # //set each int to it's index # foreach(int i, inout int v; ia) v = i; # # a = (cast(bit*)ia.ptr)[0..32*ia.length]; # a[310] = 1; //ia[9] bit #22, 2^22 = 4194304 # foreach(int v; ia) writefln(v); //4194313 (2^22 + 9(it's index)) # } Basically you can create a bit[] by slicing any location in memory, you just have to know it's starting location and how big the memory is, in bits. Something I don't understand is happening with the 'long', can someone explain this to me please. :) Re-writing your code, assuming 'result' is a bit[] and 'b' is a byte: result = (cast(bit*)b)[0..8]; Regan
Mar 15 2005
parent reply "Alexander Panek" <alexander.panek brainsware.org> writes:
On Wed, 16 Mar 2005 10:17:11 +1300, Regan Heath <regan netwin.co.nz> wrote:
 # 	//slice a byte
 # 	a = (cast(bit*)&b)[0..8];
 # 	a[0] = 1; //2^0 == 1
 # 	a[6] = 1; //2^6 == 64
 # 	writefln("byte(",b,")"); //65

 Basically you can create a bit[] by slicing any location in memory, you  
 just have to know it's starting location and how big the memory is, in  
 bits.

 Something I don't understand is happening with the 'long', can someone  
 explain this to me please. :)

 Re-writing your code, assuming 'result' is a bit[] and 'b' is a byte:
    result = (cast(bit*)b)[0..8];

 Regan

You`re my hero! Saved my day! :) Thank you very much, Alex -- Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
Mar 15 2005
parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Tue, 15 Mar 2005 22:27:44 +0100, Alexander Panek  
<alexander.panek brainsware.org> wrote:
 On Wed, 16 Mar 2005 10:17:11 +1300, Regan Heath <regan netwin.co.nz>  
 wrote:
 # 	//slice a byte
 # 	a = (cast(bit*)&b)[0..8];
 # 	a[0] = 1; //2^0 == 1
 # 	a[6] = 1; //2^6 == 64
 # 	writefln("byte(",b,")"); //65

 Basically you can create a bit[] by slicing any location in memory, you  
 just have to know it's starting location and how big the memory is, in  
 bits.

 Something I don't understand is happening with the 'long', can someone  
 explain this to me please. :)

 Re-writing your code, assuming 'result' is a bit[] and 'b' is a byte:
    result = (cast(bit*)b)[0..8];

 Regan

You`re my hero! Saved my day! :) Thank you very much, Alex

After reading your other post, about "getting the first 7 bits" from each byte (I've written some sms decode/encode routines in C BTW) you could do something like... bit[] result; bit[] part; foreach(byte b; raw_data) { part = (cast(bit*)byte)[0..7]; result ~= part; } or similar to grab 7 bits from each byte (whether it's the correct 7 bits or not I haven't thought about, I'll leave that to you). Regan
Mar 15 2005
parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Wed, 16 Mar 2005 10:59:21 +1300, Regan Heath <regan netwin.co.nz> wrote:
 On Tue, 15 Mar 2005 22:27:44 +0100, Alexander Panek  
 <alexander.panek brainsware.org> wrote:
 On Wed, 16 Mar 2005 10:17:11 +1300, Regan Heath <regan netwin.co.nz>  
 wrote:
 # 	//slice a byte
 # 	a = (cast(bit*)&b)[0..8];
 # 	a[0] = 1; //2^0 == 1
 # 	a[6] = 1; //2^6 == 64
 # 	writefln("byte(",b,")"); //65

 Basically you can create a bit[] by slicing any location in memory,  
 you just have to know it's starting location and how big the memory  
 is, in bits.

 Something I don't understand is happening with the 'long', can someone  
 explain this to me please. :)

 Re-writing your code, assuming 'result' is a bit[] and 'b' is a byte:
    result = (cast(bit*)b)[0..8];

 Regan

You`re my hero! Saved my day! :) Thank you very much, Alex

After reading your other post, about "getting the first 7 bits" from each byte (I've written some sms decode/encode routines in C BTW) you could do something like... bit[] result; bit[] part; foreach(byte b; raw_data) { part = (cast(bit*)byte)[0..7]; result ~= part; } or similar to grab 7 bits from each byte (whether it's the correct 7 bits or not I haven't thought about, I'll leave that to you).

To be honest though I haven't tried the code above. bit[] is a strange beast, not like other array types in some situations... one would hope the above code works though it may not. Regan
Mar 15 2005
next sibling parent reply "Alexander Panek" <alexander.panek brainsware.org> writes:
On Wed, 16 Mar 2005 11:02:53 +1300, Regan Heath <regan netwin.co.nz> wrote:

 On Wed, 16 Mar 2005 10:59:21 +1300, Regan Heath <regan netwin.co.nz>  
 wrote:
 On Tue, 15 Mar 2005 22:27:44 +0100, Alexander Panek  
 <alexander.panek brainsware.org> wrote:
 On Wed, 16 Mar 2005 10:17:11 +1300, Regan Heath <regan netwin.co.nz>  
 wrote:
 # 	//slice a byte
 # 	a = (cast(bit*)&b)[0..8];
 # 	a[0] = 1; //2^0 == 1
 # 	a[6] = 1; //2^6 == 64
 # 	writefln("byte(",b,")"); //65

 Basically you can create a bit[] by slicing any location in memory,  
 you just have to know it's starting location and how big the memory  
 is, in bits.

 Something I don't understand is happening with the 'long', can  
 someone explain this to me please. :)

 Re-writing your code, assuming 'result' is a bit[] and 'b' is a byte:
    result = (cast(bit*)b)[0..8];

 Regan

You`re my hero! Saved my day! :) Thank you very much, Alex

After reading your other post, about "getting the first 7 bits" from each byte (I've written some sms decode/encode routines in C BTW) you could do something like... bit[] result; bit[] part; foreach(byte b; raw_data) { part = (cast(bit*)byte)[0..7]; result ~= part; } or similar to grab 7 bits from each byte (whether it's the correct 7 bits or not I haven't thought about, I'll leave that to you).

To be honest though I haven't tried the code above. bit[] is a strange beast, not like other array types in some situations... one would hope the above code works though it may not. Regan

My code is quite similar to yours:
 	foreach(byte b; ascii)
 	{
 		sms[offset_sms..(offset_sms + 6)] = (cast(bit*)&b)[0..6];
 		offset_sms += 7;
 	}

.. it *should* copy the first 7 bits of a byte into the bit-array, but it allways ends up either with an ArrayBoundsError, or something like that: "Error: lengths don't match for array copy". I already tried to modify the length of "bit [] sms" dynamically, so it`s allways big enough to get the next 7 bits -> same errors. (Well, the first 2 steps of the loop are working, but then it gives the ArrayBoundsError.) Alex -- Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
Mar 15 2005
parent reply "Alexander Panek" <alexander.panek brainsware.org> writes:
On Wed, 16 Mar 2005 07:16:00 +0100, Alexander Panek  
<alexander.panek brainsware.org> wrote:

 On Wed, 16 Mar 2005 11:02:53 +1300, Regan Heath <regan netwin.co.nz>  
 wrote:

 On Wed, 16 Mar 2005 10:59:21 +1300, Regan Heath <regan netwin.co.nz>  
 wrote:
 On Tue, 15 Mar 2005 22:27:44 +0100, Alexander Panek  
 <alexander.panek brainsware.org> wrote:
 On Wed, 16 Mar 2005 10:17:11 +1300, Regan Heath <regan netwin.co.nz>  
 wrote:
 # 	//slice a byte
 # 	a = (cast(bit*)&b)[0..8];
 # 	a[0] = 1; //2^0 == 1
 # 	a[6] = 1; //2^6 == 64
 # 	writefln("byte(",b,")"); //65

 Basically you can create a bit[] by slicing any location in memory,  
 you just have to know it's starting location and how big the memory  
 is, in bits.

 Something I don't understand is happening with the 'long', can  
 someone explain this to me please. :)

 Re-writing your code, assuming 'result' is a bit[] and 'b' is a byte:
    result = (cast(bit*)b)[0..8];

 Regan

You`re my hero! Saved my day! :) Thank you very much, Alex

After reading your other post, about "getting the first 7 bits" from each byte (I've written some sms decode/encode routines in C BTW) you could do something like... bit[] result; bit[] part; foreach(byte b; raw_data) { part = (cast(bit*)byte)[0..7]; result ~= part; } or similar to grab 7 bits from each byte (whether it's the correct 7 bits or not I haven't thought about, I'll leave that to you).

To be honest though I haven't tried the code above. bit[] is a strange beast, not like other array types in some situations... one would hope the above code works though it may not. Regan

My code is quite similar to yours:
 	foreach(byte b; ascii)
 	{
 		sms[offset_sms..(offset_sms + 6)] = (cast(bit*)&b)[0..6];
 		offset_sms += 7;
 	}

.. it *should* copy the first 7 bits of a byte into the bit-array, but it allways ends up either with an ArrayBoundsError, or something like that: "Error: lengths don't match for array copy". I already tried to modify the length of "bit [] sms" dynamically, so it`s allways big enough to get the next 7 bits -> same errors. (Well, the first 2 steps of the loop are working, but then it gives the ArrayBoundsError.) Alex

Rearranged my code:
 bit [] enSMS(byte [] ascii)
 {
 	bit [] sms;
 	uint i = 1;
 	//sms.length = (ascii.length * 7);

 	foreach(byte b; ascii)
 	{
 		writefln("encoding .. byte:", i);
 		if(i == ascii.length) {
 			writefln("last byte!");
 			return sms[];
 		}
 		sms ~= (cast(bit*)&b)[0..6];
 		i++;
 	}
 	
 	return sms[];
 }

Works fine .. until the loop is finished, or the return is made - I don`t know. Output: Y:\Programming\D\SMS Codierung>smscode encoding .. byte:1 encoding .. byte:2 encoding .. byte:3 encoding .. byte:4 encoding .. byte:5 encoding .. byte:6 encoding .. byte:7 encoding .. byte:8 encoding .. byte:9 encoding .. byte:10 encoding .. byte:11 encoding .. byte:12 encoding .. byte:13 encoding .. byte:14 encoding .. byte:15 encoding .. byte:16 encoding .. byte:17 encoding .. byte:18 encoding .. byte:19 encoding .. byte:20 encoding .. byte:21 encoding .. byte:22 encoding .. byte:23 encoding .. byte:24 encoding .. byte:25 last byte! Error: lengths don't match for array copy ..well, I`m helpless :) . Thanks, Alex -- Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
Mar 15 2005
parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Wed, 16 Mar 2005 07:33:18 +0100, Alexander Panek  
<alexander.panek brainsware.org> wrote:
 On Wed, 16 Mar 2005 07:16:00 +0100, Alexander Panek  
 <alexander.panek brainsware.org> wrote:

 On Wed, 16 Mar 2005 11:02:53 +1300, Regan Heath <regan netwin.co.nz>  
 wrote:

 On Wed, 16 Mar 2005 10:59:21 +1300, Regan Heath <regan netwin.co.nz>  
 wrote:
 On Tue, 15 Mar 2005 22:27:44 +0100, Alexander Panek  
 <alexander.panek brainsware.org> wrote:
 On Wed, 16 Mar 2005 10:17:11 +1300, Regan Heath <regan netwin.co.nz>  
 wrote:
 # 	//slice a byte
 # 	a = (cast(bit*)&b)[0..8];
 # 	a[0] = 1; //2^0 == 1
 # 	a[6] = 1; //2^6 == 64
 # 	writefln("byte(",b,")"); //65

 Basically you can create a bit[] by slicing any location in memory,  
 you just have to know it's starting location and how big the memory  
 is, in bits.

 Something I don't understand is happening with the 'long', can  
 someone explain this to me please. :)

 Re-writing your code, assuming 'result' is a bit[] and 'b' is a  
 byte:
    result = (cast(bit*)b)[0..8];

 Regan

You`re my hero! Saved my day! :) Thank you very much, Alex

After reading your other post, about "getting the first 7 bits" from each byte (I've written some sms decode/encode routines in C BTW) you could do something like... bit[] result; bit[] part; foreach(byte b; raw_data) { part = (cast(bit*)byte)[0..7]; result ~= part; } or similar to grab 7 bits from each byte (whether it's the correct 7 bits or not I haven't thought about, I'll leave that to you).

To be honest though I haven't tried the code above. bit[] is a strange beast, not like other array types in some situations... one would hope the above code works though it may not. Regan

My code is quite similar to yours:
 	foreach(byte b; ascii)
 	{
 		sms[offset_sms..(offset_sms + 6)] = (cast(bit*)&b)[0..6];
 		offset_sms += 7;
 	}

.. it *should* copy the first 7 bits of a byte into the bit-array, but it allways ends up either with an ArrayBoundsError, or something like that: "Error: lengths don't match for array copy". I already tried to modify the length of "bit [] sms" dynamically, so it`s allways big enough to get the next 7 bits -> same errors. (Well, the first 2 steps of the loop are working, but then it gives the ArrayBoundsError.) Alex

Rearranged my code:
 bit [] enSMS(byte [] ascii)
 {
 	bit [] sms;
 	uint i = 1;
 	//sms.length = (ascii.length * 7);

 	foreach(byte b; ascii)
 	{
 		writefln("encoding .. byte:", i);
 		if(i == ascii.length) {
 			writefln("last byte!");
 			return sms[];
 		}
 		sms ~= (cast(bit*)&b)[0..6];
 		i++;
 	}
 	
 	return sms[];
 }

Works fine .. until the loop is finished, or the return is made - I don`t know. Output: Y:\Programming\D\SMS Codierung>smscode encoding .. byte:1 encoding .. byte:2 encoding .. byte:3 encoding .. byte:4 encoding .. byte:5 encoding .. byte:6 encoding .. byte:7 encoding .. byte:8 encoding .. byte:9 encoding .. byte:10 encoding .. byte:11 encoding .. byte:12 encoding .. byte:13 encoding . byte:14 encoding .. byte:15 encoding .. byte:16 encoding .. byte:17 encoding .. byte:18 encoding .. byte:19 encoding .. byte:20 encoding .. byte:21 encoding .. byte:22 encoding .. byte:23 encoding .. byte:24 encoding .. byte:25 last byte! Error: lengths don't match for array copy ..well, I`m helpless :) .

Odd. What happes if you change "return sms[];" to "return sms;" ? I am having different trouble, no array bounds errors for me, but... import std.stdio; void main() { byte[] ascii = cast(byte[])"0000"; bit[] sms; bit[] tmp; writef("ASC:"); foreach(int i, bit bb; (cast(bit*)ascii.ptr)[0..32]) { if (i && i%8 == 0) writef(" "); writef("%d",bb); } writefln(""); foreach(int j, byte b; ascii) { tmp = (cast(bit*)&b)[0..7]; writef("TMP:"); for(int k = 0; k < j; k++) writef(" "); foreach(int i, bit b; tmp) writef("%d",b); writefln(""); sms ~= tmp; writef("SMS:"); foreach(int i, bit b; sms) { if (i && i%7 == 0) writef(" "); writef("%d",b); } writefln(""); } writefln(""); } output: ASC:00001100 00001100 00001100 00001100 TMP:0000110 SMS:0000110 TMP: 0000110 SMS:0000110 0010111 TMP: 0000110 SMS:0000110 0010111 0010000 TMP: 0000110 SMS:0000110 0010111 0010000 0100000 'tmp' is appended to 'sms' each time round the loop, but something is going very wrong. Anyone got any ideas? Regan
Mar 16 2005
parent "Alexander Panek" <alexander.panek brainsware.org> writes:
On Wed, 16 Mar 2005 22:10:30 +1300, Regan Heath <regan netwin.co.nz> wrote:

 Odd. What happes if you change "return sms[];" to "return sms;" ?

 I am having different trouble, no array bounds errors for me, but...

 import std.stdio;

 void main()
 {
 	byte[] ascii = cast(byte[])"0000";
 	bit[] sms;
 	bit[] tmp;
 	
 	writef("ASC:");
 	foreach(int i, bit bb; (cast(bit*)ascii.ptr)[0..32]) {
 		if (i && i%8 == 0) writef(" ");
 		writef("%d",bb);
 	}
 	writefln("");
 	
 	foreach(int j, byte b; ascii) {
 		tmp = (cast(bit*)&b)[0..7];		
 		
 		writef("TMP:");
 		for(int k = 0; k < j; k++) writef("         ");
 		foreach(int i, bit b; tmp) writef("%d",b);
 		writefln("");
 		
 		sms ~= tmp;
 		
 		writef("SMS:");
 		foreach(int i, bit b; sms) {
 			if (i && i%7 == 0) writef("  ");
 			writef("%d",b);
 		}
 		writefln("");
 	}
 	writefln("");
 }

 output:

 ASC:00001100 00001100 00001100 00001100
 TMP:0000110
 SMS:0000110
 TMP:         0000110
 SMS:0000110  0010111
 TMP:                  0000110
 SMS:0000110  0010111  0010000
 TMP:                           0000110
 SMS:0000110  0010111  0010000  0100000

 'tmp' is appended to 'sms' each time round the loop, but something is  
 going very wrong.

 Anyone got any ideas?

 Regan

It was "return sms;" before, just tried out if it helps. ;) For some reason the encoded string seems to be bigger than the ascii-string here: string has 6bytes encoding .. byte:1 0000110\ 0000110 encoding .. byte:2 1000110\ 00001100 000000 encoding .. byte:3 0000110\ 00001100 00000000 00000 encoding .. byte:4 1000110\ 00001100 00000000 00000000 0000 encoding .. byte:5 0000110\ 00001100 00000000 00000000 00000000 001 encoding .. byte:6 (last byte!) 1000110\ 00001100 00000000 00000000 00000000 00111111 01Error: lengths don't match for array copy <---------------------------------------------> = 5bytes + 2 bits current code: // ========================================================================= bit [] enSMS(byte [] ascii) { bit [] sms, tmp; uint i = 1; //sms.length = (ascii.length * 7); writef("string(", cast(char[])ascii, ") has ", ascii.length, "bytes"); foreach(byte by; ascii) { writef("\nencoding .. byte:", i); if(i == ascii.length) writefln(" (last byte!)"); else writefln(""); tmp = (cast(bit*)&by)[0..7]; foreach(bit b; tmp) { writef("%d",b); } sms ~= tmp; foreach(int j, bit b; sms) { if(j%50 == 0) writefln("\\"); if(j%8 == 0)writef(" "); writef("%d",b); } i++; } return sms; } // ========================================================================= So, as you see, I`ve got the same problem. Alex -- Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
Mar 16 2005
prev sibling parent Derek Parnell <derek psych.ward> writes:
On Wed, 16 Mar 2005 11:02:53 +1300, Regan Heath wrote:

 On Wed, 16 Mar 2005 10:59:21 +1300, Regan Heath <regan netwin.co.nz> wrote:
 On Tue, 15 Mar 2005 22:27:44 +0100, Alexander Panek  
 <alexander.panek brainsware.org> wrote:
 On Wed, 16 Mar 2005 10:17:11 +1300, Regan Heath <regan netwin.co.nz>  
 wrote:
 # 	//slice a byte
 # 	a = (cast(bit*)&b)[0..8];
 # 	a[0] = 1; //2^0 == 1
 # 	a[6] = 1; //2^6 == 64
 # 	writefln("byte(",b,")"); //65

 Basically you can create a bit[] by slicing any location in memory,  
 you just have to know it's starting location and how big the memory  
 is, in bits.

 Something I don't understand is happening with the 'long', can someone  
 explain this to me please. :)

 Re-writing your code, assuming 'result' is a bit[] and 'b' is a byte:
    result = (cast(bit*)b)[0..8];

 Regan

You`re my hero! Saved my day! :) Thank you very much, Alex

After reading your other post, about "getting the first 7 bits" from each byte (I've written some sms decode/encode routines in C BTW) you could do something like... bit[] result; bit[] part; foreach(byte b; raw_data) { part = (cast(bit*)byte)[0..7]; result ~= part; } or similar to grab 7 bits from each byte (whether it's the correct 7 bits or not I haven't thought about, I'll leave that to you).

To be honest though I haven't tried the code above. bit[] is a strange beast, not like other array types in some situations... one would hope the above code works though it may not. Regan

I think that one difference is that with non-bit arrays, element[x] has a lower RAM address than element[x+1], but it is the reverse with bit arrays. For example, if you have a bit array of 32 bits, the elements 0-7 inclusive might have an address of 0xFE78 (for one byte), elements 8-15 inclusive will have an address of 0xFE77, elements 16-23 will have the address 0xFE76, and the last octet will have the address 0xFE75. Such that if you set "element[31]=1", it means that the left-most bit at address 0xFE75 will be set, and "element[0]=1" will set the rightmost bit at address 0xFE78. -- Derek Parnell Melbourne, Australia 16/03/2005 9:43:04 PM
Mar 16 2005
prev sibling parent Nrgyzer <nrgyzer gmail.com> writes:
Alexander Panek Wrote:

 On Tue, 15 Mar 2005 21:23:23 +0100, Anders F Björklund <afb algonet.se>  
 wrote:
 
 Alexander Panek wrote:

 just wondered if there`s a common way to edit single bits in a byte? in  
 C  and C++ there were only crappy 'workarounds', but as D has a  
 single-bit  datatype it would be great to have an operator to  
 read/write single bits  in a byte-variable.

Use the bit[] type. Just be aware that it always aligns the memory used to even powers of 32 bits (4 bytes), if unioned with for instance byte. See http://www.prowiki.org/wiki4d/wiki.cgi?BitsAndBools --anders

Well, I use a bit-array. But it seems like the compiler does not want me to do this :o ! I use this code to copy a bit out of a byte into a bit-variable: [code] while(offset_ascii < 8) { result[offset_sms] = (b & (true << offset_ascii++)) << offset_sms++; // line 18 } [/code] DMD gives me this error: " smscode.d(18): cannot implicitly convert expression (cast(int)(b) & 1 << offset_ascii++) of type int to bit " Thanks, an hopefully Alex ;) -- Using Opera's revolutionary e-mail client: http://www.opera.com/mail/

I tried a bit... I can't get it to work with bud... only dmd will compile the source. When I first compile with dmd and then with bud, it works with bud, too - but only until I didn't use the -clean flag when I build the exe-file.
May 07 2010