0
\$\begingroup\$

i have two binary number

u8 buf[2];
buf[0] = 0001 1110; In dec it's 30 ; it is  High Byte and means 30 C;
buf[1] = 1100 0000; In dec it's 192 ; but its Low byte and means 0.75 C;

How i can return 30.75 C value?

\$\endgroup\$
  • \$\begingroup\$ What language are you coding in? Your example doesn't match any programming language I know. \$\endgroup\$ – The Photon Mar 6 '16 at 17:06
0
\$\begingroup\$

The radix point is between the two bytes, as jippie points out. If you want to convert it to floating point you can do something like this (C code)

int nint; 
float num; 
nint = buf[0] << 8 | buf[1]; 
num = nint/256.0; 

But only if the number is unsigned Edit: a positive number in 2's complement, iow the msb of buf[0] is 0 as in your example.

If the number is 2's complement signed, then you'll have to sign-extend the integer using something like this:

int nint; 
float num; 
nint = buf[0] << 8 | buf[1]; 
if (nint & (0x01 << 15))
   {
   nint = (~0 ^ 0xFFFF) | nint;  // sign extend 
   } 
num = nint/256.0;
\$\endgroup\$
  • \$\begingroup\$ If it is signed, you could simply do int16_t nint; (portable c type) that way when it converts from integer to float the sign extension will be done automatically. \$\endgroup\$ – Tom Carpenter Mar 6 '16 at 18:18
  • 1
    \$\begingroup\$ Be aware that because of implicit integer promotion, buf[0] << 8 invokes undefined behavior on systems where int is 16 bits, that is, this code will not work on any 8 or 16 MCU. Fix this subtle but severe bug by casting the operand in advance, for example (uint16_t)buf[0] << 8. \$\endgroup\$ – Lundin Mar 7 '16 at 12:04
  • \$\begingroup\$ @Lundin If msb buf[0] is not zero then there is, I believe, implementation-defined behavior (on the assignment- the integer conversion is defined by the ANSI standard- it will be signed or unsigned if it cannot be represented by a signed), however it does work in practice with both PIC compilers I tried it with (8 bit targets - HT and XC8). To be sure, I've modified the answer to avoid the case where the msb is not zero. \$\endgroup\$ – Spehro Pefhany Mar 7 '16 at 13:34
  • \$\begingroup\$ No, if the sign bits get their value altered by a left shift, then you invoke undefined behavior (6.5.7/4). Implementation-defined behavior is what happens if you right shift a negative integer - you could get either arithmetic shift or logical shift (or possibly something unorthodox like rotate). In practice, many compilers have some manner of defined behavior for both cases - at best the code is merely non-portable. But potentially, problems can arise if the compiler makes aggressive optimizations based on the assumption that you will never left shift negative integers. Best to avoid UB. \$\endgroup\$ – Lundin Mar 7 '16 at 13:59
2
\$\begingroup\$

Your number has a fixed binary point. This means the low byte is to be divided by 256 to get the right fraction What it actually means is:

30 + 192 / 256 = 30 + 0.75 = 30.75

This is a great format because you can simply use the CPU's integer math with it, which is simple and fast. Only when needed to print, you have to convert it in a way the (binary) point is respected. Only for multiplications and divisions you need to shift the result for correct magnitude. Think about it, this is exactly the same as you learned in primary school with the decimal numbers.

With the high byte, the rightmost bit, bit0 has a weight of 20=1. The bit to the left has weight 21=2 and the bit next to that 22=4 ... etc.

The bits to the right, the low byte have weigths 2-1=0.5 and the bit to the right of that 2-2=0.25 ... etc. up to 2-8=1/256.

\$\endgroup\$
  • \$\begingroup\$ Yes i inderstand this, but i dont really sure that if we devide binary number on 256 we get 0.75 (maybe we get 0?) \$\endgroup\$ – user3826752 Mar 6 '16 at 17:16
  • \$\begingroup\$ In integer math you get 0, but you are converting integer to printable with a fixed point. Deliberately not saying conversion to float as this is again an internal non-printable format. \$\endgroup\$ – jippie Mar 6 '16 at 17:24
  • \$\begingroup\$ yes i know it, i wont to ask you does it depends what we devide on 256.0?(if we devide ineger number, fow example 195/256.0 we get 0.75)(but i return temperarure in decimal with accurancy 0.25 from low byte format like 1100 0000(in dec 192)(which means 0.75) and if i devide this on 256.0 i also return 0.75?) \$\endgroup\$ – user3826752 Mar 6 '16 at 17:32
  • \$\begingroup\$ I think I lost you @user3826752 \$\endgroup\$ – jippie Mar 6 '16 at 17:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.