Fog Creek Software
Discussion Board




Nibbles, Words, DWords, Pints, Quarts...


I've once again forgotten how bytes stick together to form words or how words stick to compose a dword. So I mused for a moment to arrive at this:

#include <stdio.h>

void WordToBytes(const int* Word,
                 int* LoByte,
                 int* HiByte)
{
    
    *LoByte= *Word & 255;
    *HiByte = *Word / 256;

}

void BytesToWord(const int* LoByte,
            const int* HiByte,
            int* Word)
{
    *Word =
        *HiByte*256|*LoByte;
}

int main(void)
{
    int Word, LoByte, HiByte;
    Word = 4951;
    LoByte=HiByte=0;
    WordToBytes(&Word, &LoByte, &HiByte);
    printf("%d %d %d\n",Word, LoByte, HiByte);
    Word=0;
    BytesToWord(&LoByte, &HiByte, &Word);
    printf("%d %d %d\n",Word, LoByte, HiByte);
}

Is the logic correct? <pedant>All of the integers are assumed to be unsigned<pedant/>.

Sathyaish Chakravarthy
Tuesday, June 15, 2004

<pedant>All of the integers are assumed to be unsigned<pedant/>.


<captious>So why don't you  declare them unsigned int?</captious>

René Nyffenegger
Tuesday, June 15, 2004


Because I took a specific number for this example, 4951, which was not a negative number.

Sathyaish Chakravarthy
Tuesday, June 15, 2004

Hey Sathyaish,

Where are your unit tests? :-P

Wisea**
Tuesday, June 15, 2004


No, I actually keep forgetting these things over a period of six months or so. I must have been over them for over a thousand times now. I guess I am getting old already.

Sathyaish Chakravarthy
Tuesday, June 15, 2004

Well, you need to think whether you are considering your bytes and words as bit strings or as numeric quantities.

In your example, you have used both a bit-wise operator (&) and an arithmetic operator (/).

If you are splitting and concatenating bytes and words as collections of bits, it might be safer and more transparent to use only bit-wise operators in your expressions. (Hint: You could use the bit shift operators << or >>)

Ian
Tuesday, June 15, 2004

Dear Whitewash Cheklaslovakia:

Do you have a degree?  Do you own a computer?  What the heck are you trying to prove?

Anon
Tuesday, June 15, 2004

Dear Anon:

Why you hatin' on Sathyaish?!

Anon 2.0
Tuesday, June 15, 2004


All the vets here, thanks for not thrashing me till now.

Ok, I just farted in a hurry. I was considering a bitwise shifting but then I thought I'd have to write an extra include for the power function or write one myself. I was just lazy. If I had to shift bits I'd to do a power, no?

    *HiByte = *Word>>power(2,8);

But am I sound on the logic?

Sathyaish Chakravarthy
Tuesday, June 15, 2004

Just imagine if we all posted our thoughts, ramblings and old comp sci 101 material to this board...

Anon 3.0
Tuesday, June 15, 2004

Why are you farting in a hurry? You really should fart slowly, so you can enjoy it. :-P

Wisea**
Tuesday, June 15, 2004


>Just imagine if we all posted our thoughts, ramblings and old comp sci 101 material to this board...

Is that not what everyone is doing, including your esteemed self?

Sathyaish Chakravarthy
Tuesday, June 15, 2004

Yea I shouldn't be poking fun of Sathyaish.

You might try looking up the HIBYTE/LOBYTE HIWORD/LOWORD macros in the windows header files.

Anon
Tuesday, June 15, 2004

Hey guys, I wanted to store two 8-bit numbers in a single 16 bit number so what I did was:

int x = 5;

which put 5 into x, then what I did next was

int y = (x << 8);
int z = 7;

then by ORing them together:
int w = y | z

now I have both numbers (5 and 7) stored in one variable (w), and what I do now is I take (w & 255) which gives me 7, then I take (w & 0xFF00) and then:

int a = ((w & 0xFF00) >> 8);

so now a is 5, or is my logic backward?

Anon 4.0
Tuesday, June 15, 2004

Do you feel better about yourself after making fun of Sathyaish?

Anon (Positive Infinity).0
Tuesday, June 15, 2004

What I'm asking is, can I say

if (a == w)

and will this be true always? So can I put more code underneath it, such as in brackets i.e.

if (a == w)
{
    ...more code here
}

and will this code get executed? for example can I say
if (a == w)
{
    cout << "a is equal to w";
}
else
{
  cout << "a is not equal to w";
}

so what I am asking dear JOS readers, will the result of my program say "a is equal to w" or "a is not equal to w?"

Anon 4.0
Tuesday, June 15, 2004


All right, I was being lazy. I knew about the macros and I knew about the web sites but I'd to dig, and I was just wrapping up for the day. Just while tidying things to leave for home, I had this idea and I unwrapped things to try this out and thought I'd get some confirmation.

Sathyaish Chakravarthy
Tuesday, June 15, 2004

"Do you feel better about yourself after making fun of Sathyaish? "

Dear flamer, I am not concerned with Saythiash or anybody else. I am only interested in the responses to my questions as I discover various bits and topics about computers, the internet, mathematics and computer science. Please answer my original questions only.

Anon 4.0
Tuesday, June 15, 2004

And raising to powers is not an arithmetic operation, no?

This reminds me of when I was at school (aged 11 as I recall), and we were being taught for the first time about different number bases from decimal:

Teacher: Count up from one in binary.
Me: 1, 10, 11, 20, 21, 30, 31, 40, 41, ... huh? Where did I go wrong?

:-)

Ian
Tuesday, June 15, 2004


Yea, yeah! And who asks things like, "write a program in C to detonate the atom bomb without using any of the following keywords:

void
int
main
symbols {,}, #, *(,)
define
char
long
short
...
....
..."

???

Sathyaish Chakravarthy
Tuesday, June 15, 2004

This thread cracks me up.

Dave B.
Tuesday, June 15, 2004

Yes, your logic is correct.

There is a 'simpler' way, but it is less portable.  The 'simpler' way depends on the way the native machine stores bytes, words, and dwords(longs).

struct myword
{
  char lowbyte;
  char highbyte;
}

struct mydword
{
  struct myword lowword;
  struct myword highword;
}

Etcetera.  You MUST insure that your platform stores low-byte first, for the above to work.  I believe that is correct for x86 platforms.

AllanL5
Tuesday, June 15, 2004

I propose an syntax addition to the C language for storing two one-byte values in a single two-byte integer.

byte b1 = 8;
byte b2 = 16;
int c = b1:b2;

byte b3 = c:;
byte b4 = :c;

b1 == b3, b2 == b4.  As you can see, the syntax b1:b2 indicates to the compiler that it should shift b1 and or with b2; c: indicates the high byte of c and :c indicates the low byte of c.

Simple, no?

Should be working
Tuesday, June 15, 2004

Why is his logic correct?

It certainly does not seem correct to me when I try Word = -100 as input data.

And introducing the struct stuff is like giving a scalpel to a 2 year old (sorry Sathyaish).

Why introduce something that needs expert understanding of how data is stored in memory, when the original questioner is still clearly working on getting a basic grasp of the subject?

Ian
Tuesday, June 15, 2004

I think it would be really cool to have something like 32 bytes = 1 quart.

The I could brag that my computer has over 7800 gallons of RAM!

My Cousin Vinniwashtharam
Tuesday, June 15, 2004

No...32 syps = 1 quart.

But there are probably 32 bytes in a floppy disk (especially one covered with cheese).

Ian
Tuesday, June 15, 2004


>And introducing the struct stuff is like giving a scalpel to a 2 year old (sorry Sathyaish).

Not really Ian, I've programmed Win32 extensively so I do know all about the structures and the macros that pack words and dwords. I know I could've achieved what I set out for with just a structure as AllanL5 described and used just one CopyMemory (aka RtlMoveMemory) instruction to give me what I needed:

CopyMemory structWord, ByVal VarPtr(LngWord), 2

However, what I didn't grasp was Should Be Working's solution. Any pointers on that one?

But thanks for giving me the soft ear though.

Sathyaish Chakravarthy
Wednesday, June 16, 2004


To add to that, I'll repeat: most of the times I am asking these elementary type questions, I am not really trying to learn something new. Instead, I dig them out of memory to relearn them and to dig deeper because I have this sneaking feeling that there is more profound depth to these concepts that I am probably overlooking. And I _enjoy_ them. Another reason is that I want to break loose out of the fetter of being labelled a "VB _programmer_".

I have this feeling that there's so much I can learn from my books and in the company of you guys, both of which are a pleasure to be with.

Thanks!

Sathyaish Chakravarthy
Wednesday, June 16, 2004

Sathyaish,

You protest you are not trying to learn something new, but in fact your writings tell a different story. They are showing that you don't really _understand_ these concepts of how bytes and words and numbers are stored in memory.

A case in point: you said you did not grasp Should Be Working's solution. But this solution was identical to AllanL5's struct solution, except done in such a way the compiler would guarantee the right result regardless of the layout of internal storage. You said you understand about structs, and about macros for packing and unpacking, yet you did not follow what Should Be Working proposed?

You see, really, you need to change your mindset. Instead of thinking you have learned things and you are just looking for deeper understanding, you need to acknowledge that you really have not learned them yet, and you still need to work on your basic understanding.

Ian
Wednesday, June 16, 2004


>you need to acknowledge that you really have not learned them yet, and you still need to work on your basic understanding.

True! I must tell you I didn't understand Should be working's solution. I am not ever trying to say that I know _everything_ that there is to know about C, data structures and algorithms. I don't know many things, and I know some things.

Sathyaish Chakravarthy
Wednesday, June 16, 2004

Well, you see, VB is trying to hide from you the gory details of how the machines work underneath, so you can concentrate on getting work done rapidly. On the other hand, C is trying to let you have direct access to the gory details of how the machines work underneath, assuming that you are very familiar with such things.

So trying to leap from VB to C, if you have not already got some knowledge of machine architecture and assembly language programming, is a very big leap.

I think you should find an introductory book about the nuts and bolts of computer hardware, how CPUs are organized, how numbers and other data are represented in memory, and how computers are programmed in machine code and assembly language. Such a book will be an invaluable reference to have to hand when you are learning C.

Ian
Wednesday, June 16, 2004


Yeah, you are right. Learning the assembly language is also on my agenda. I do have a book for the Intel 8085 assembly but I don't know if that is going to do me any good. Would you think it would be a good thing to learn assembly before learning C (when I say learning C again, it doesn't mean I am completely new to C).

I've had mostly a second-hand acquiantance with the API but I've also done some direct API programming in C. Besides that I am trying to learn some low-level stuff some of which I already know but most of which I do not.

You see when I ask these questions, some people say learn this, learn that first, buy a good book on this and that. I ask questions because I am already reading a book or two. And it is somewhat confusing to encounter a response like read a good book on this thing, and not what you are already reading. Some guys told me, do C++ because you'll have a hard time abandoning the bad habits that come with C.

To those, I wish to say, I've had enough of good habits. In fact, I've had so much of good habits only with VB that it they were just too good for me. Its time I wanna learn the bad ones so I can appreciate the good ones I already got in posterity from VB.

Sathyaish Chakravarthy
Wednesday, June 16, 2004

Sorry to be extending this thread, but....

One of the best books on using 'C' (and explaining lots of gotcha's built in to the language, AND explaining how to avoid them) is Thomas Plum's "Reliable Data Structures in C".

You can find it in the used-books section of Ebay or Amazon. 

I went from a Pascal programmer, to a 'C' programmer under Unix, to a 'C' programmer under MSDOS, to a VB programmer under Windows, to a 'C' or 'C++' programmer under Windows.  So I understand your concern, and some of your confusion. 

One of the continuing issues with C++ is that it IS 'C' underneath.  All the gotchas and warts are STILL THERE.  It is possible to write C++ code that avoids the gotchas, but to do that you need to know what they are.

Telling someone to learn C++, and expect them to know nothing about C, is as productive as telling them to learn C without knowing anything about the standard libraries.  It can be done, but their knowledge will be forever limited.

AllanL5
Wednesday, June 16, 2004

Oh, and I would not recommend learning x86 assembly before learning 'C'.  'C' provides a very nice 'layer' one step above assembly.  It is a 'layer' that people have been using since 1978.  It is a 'layer' with really-really nice compilers which translate to whatever assembly code you need.

True, it is a 'layer' which has some gotchas, mostly because it IS only one level above assembly.  But the assembly has more, and greater gotchas.

The sooner you learn this simplified, portable 'layer', the better off you will be.  Knowing all the complexities of x86 assembly is not going to help you write good 'C' code.  There is a very small subset of x86 (like how it stores bytes to make up a word) which has any effect on your 'C' code at all.  You can learn that stuff as needed, if it is ever needed.

AllanL5
Wednesday, June 16, 2004

AllanL5,

Do you have some knowledge of machine architecture and instruction sets and assembly language programming?

And do you believe that knowledge does not help you understand what you are doing when you program?

And if so, would you be happy for all that knowledge to be erased from your mind, and you would not miss it in any way?

I did not advise Sathyaish to learn x86 assembly (there are surely better processors to use as a first introduction than that one). But I did and do advise him that he will find some general knowledge of machine level topics helpful.

Ian
Wednesday, June 16, 2004

P.S. to Sathyaish:

Much of the technical advice offered in this forum is wrong or inaccurate. It is really not a good place to seek wisdom or enlightenment I am afraid. To learn well, you do need to take college courses or study good textbooks.

Ian
Wednesday, June 16, 2004

Ian:

Yes, I have spent some time in the assembly level for x86, 6502, Z80, 68000, PICs, etc.  And yes, I think my experience with that informs my use of 'C'.  However, connecting my 'C' experience to the underlying assembly happened when I was studying 'C', not when I studied assembly.

And even then, most of the assembly I knew was worthless in understanding the 'C' run-time environment.  Only a very little of it was useful.

And that was his question -- which to learn first.
And I also very strongly agree with your recommendation that the books are the place to go.  This Forum hopefully can at least point to which books are most helpful, given a person's starting point and the goal they wish to reach.

AllanL5
Wednesday, June 16, 2004

*  Recent Topics

*  Fog Creek Home