Will this converstion to/from fixed point cause me to lose precision?

I have a situation where I have a fixed point number that I want to convert to and from a floating point number. Specifically it is the SANE_Fixed type from the SANE API. Here is the what the documentation says (I grabbed the bits I think are relavant):

SANE_Fixed is used for variables that can take fixed point values in the range -32768 to 32767.9999 with a resolution of 1/65535.

#define SANE_FIXED_SCALE_SHIFT  16
typedef SANE_Word SANE_Fixed;

The macro SANE_FIXED_SCALE_SHIFT gives the location of the fixed binary point. This standard defines that value to be 16, which yields a resolution of 1/65536.

SANE_Word: A word is encoded as 4 bytes (32 bits). The bytes are ordered from most-significant to least-significant byte (big-endian byte-order).

So, over the wire I get 4 bytes which I convert into a .Net int like this (you can guess what GetByte and SendByte do):

public int GetWord()
{
int value = 0;
value += (GetByte() << 24);
value += (GetByte() << 16);
value += (GetByte() << 8);
value += (GetByte() << 0);
return value;
}

Then I want to convert that int into a floating point number (I went for decimal) like this:

public decimal ToFloating(int source)
{
decimal value = source / ((decimal)(1 << 16));
return value;
}

And I will also need to go back the other way so I would convert to fixed like this:

public int ToFixed(decimal source)
{
decimal value = source * ((decimal)(1 << 16));
return (int)value;
}

And then convert to four bytes like this to send it like so:

public void SendWord(int word)
{
SendByte((word >> 24) & 0xff);
SendByte((word >> 16) & 0xff);
SendByte((word >> 8) & 0xff);
SendByte((word >> 0) & 0xff);
}

So, here is my question:

This seems a pretty simplistic implementation to me and I read lots of stuff on the internet about creating custom fixed point classes and whatnot but, given the constraints of my scenario, is this a safe approach to take? Could I lose precision and is the maths correct?

• Have you tried it? Does it seem to work? – svick Mar 8 '13 at 9:17
• Yes, I have tried it and it does seem to work – kmp Mar 8 '13 at 10:13