Solved

How do I convert the comp_t data type to a float in C, given its encoding?

Posted on 2009-02-18
405 Views
I need to convert the Linux C comp_t data type to a float, or something else I can print out. The description of this type is

/*
*  comp_t is a 16-bit "floating" point number with a 3-bit base 8
*  exponent and a 13-bit fraction. See linux/kernel/acct.c for the
*  specific encoding system used.
*/

typedef __u16   comp_t;

I have looked up the encoding function, but still do not know how I can decode it (i.e., convert to a standard data type):

224 /*
225  *  encode an unsigned long into a comp_t
226  *
227  *  This routine has been adopted from the encode_comp_t() function in
228  *  the kern_acct.c file of the FreeBSD operating system. The encoding
229  *  is a 13-bit fraction with a 3-bit (base 8) exponent.
230  */
231
232 #define MANTSIZE        13                      /* 13 bit mantissa. */
233 #define EXPSIZE         3                       /* Base 8 (3 bit) exponent. */
234 #define MAXFRACT        ((1 << MANTSIZE) - 1)   /* Maximum fractional value. */
235
236 static comp_t encode_comp_t(unsigned long value)
237 {
238         int exp, rnd;
239
240         exp = rnd = 0;
241         while (value > MAXFRACT) {
242                 rnd = value & (1 << (EXPSIZE - 1));     /* Round up? */
243                 value >>= EXPSIZE;      /* Base 8 exponent == 3 bit shift. */
244                 exp++;
245         }
246
247         /*
248          * If we need to round up, do it (and handle overflow correctly).
249          */
250         if (rnd && (++value > MAXFRACT)) {
251                 value >>= EXPSIZE;
252                 exp++;
253         }
254
255         /*
256          * Clean it up and polish it off.
257          */
258         exp <<= MANTSIZE;               /* Shift the exponent into place */
259         exp += value;                   /* and add on the mantissa. */
260         return exp;
261 }

What would be a function to convert it back? THANKS!
0
Question by:CoolJFN

Expert Comment

A possible solution is to extract the fractional components for the mantissa and the exponent from the bits encoded in the comp_t value supplied and to create a double number from these fractional components. This algorithm is coded in the function comp_t_to_double() as given below.

``````

/* This function converts from comp_t to double value for exponent base 10. */

double comp_t_to_double(comp_t value)

{

double dval = 0;

int exp = 0;

/*

* Get the fraction components.

*/

exp = value >> MANTSIZE;        /* Get the exponent (first 3 bits). */

dval = (value & MAXFRACT);        /* Get the mantissa (last 13 bits). */

for(int i=0; i < exp; i++) {

dval /= 10;

}

return dval;

}
``````
0

LVL 53

Expert Comment

>> What would be a function to convert it back?

Right from the docs :

comp_t c;
unsigned long v = (c & 0x1fff) << (((c >> 13) & 0x7) * 3);

converts the comp_t value c to an unsigned long value v.
0

LVL 53

Accepted Solution

0

Featured Post

Suggested Solutions

zeroFront challenge 7 58
java constructor error 8 66
scoreUp challenge 14 40
VBA color chart bars 12 51
This is an explanation of a simple data model to help parse a JSON feed
Since upgrading to Office 2013 or higher installing the Smart Indenter addin will fail. This article will explain how to install it so it will work regardless of the Office version installed.
Viewers will learn how to properly install Eclipse with the necessary JDK, and will take a look at an introductory Java program. Download Eclipse installation zip file: Extract files from zip file: Download and install JDK 8: Open Eclipse and …
In this fourth video of the Xpdf series, we discuss and demonstrate the PDFinfo utility, which retrieves the contents of a PDF's Info Dictionary, as well as some other information, including the page count. We show how to isolate the page count in a…