Sponsored Content
Full Discussion: Is there a floatN_t type ?
Top Forums Programming Is there a floatN_t type ? Post 302323883 by fpmurphy on Tuesday 9th of June 2009 09:31:58 AM
Old 06-09-2009
Emitrax, you can do what you want to do but it is going to take significant work on your part. The relevant standard is IEEE 754-2008 (previously known as IEEE 754r) which was published in August of 2008.

Floating point formats defined by this standard are classified as either interchange or non-interchange. In the standard, storage formats are narrow interchange formats, i.e. the set of floating point values that can be stored by the specified binary encoding is a proper subset of wider floating point formats such as the 32-bit float and 64-bit double.

For example here is how to encode and decode a half-precision (i.e. 16-bit) binary encoded floating point number.
Code:
/*
**  This program is free software; you can redistribute it and/or modify it under
**  the terms of the GNU Lesser General Public License, as published by the Free 
**  Software Foundation; either version 2 of the License, or (at your option) any
**  later version.
**
**   IEEE 758-2008 Half-precision Floating Point Format
**   --------------------------------------------------
**
**   | Field    | Last | First | Note
**   |----------|------|-------|----------
**   | Sign     | 15   | 15    |
**   | Exponent | 14   | 10    | Bias = 15
**   | Fraction | 9    | 0     |
*/

#include <stdio.h>
#include <inttypes.h>

typedef uint16_t HALF;

/* ----- prototypes ------ */
float HALFToFloat(HALF);
HALF floatToHALF(float);
static uint32_t halfToFloatI(HALF);
static HALF floatToHalfI(uint32_t);

float
HALFToFloat(HALF y)
{
    union { float f; uint32_t i; } v;
    v.i = halfToFloatI(y);
    return v.f;
}

uint32_t
static halfToFloatI(HALF y)
{
    int s = (y >> 15) & 0x00000001;                            // sign
    int e = (y >> 10) & 0x0000001f;                            // exponent
    int f =  y        & 0x000003ff;                            // fraction

    // need to handle 7c00 INF and fc00 -INF?
    if (e == 0) {
        // need to handle +-0 case f==0 or f=0x8000?
        if (f == 0)                                            // Plus or minus zero
            return s << 31;
        else {                                                 // Denormalized number -- renormalize it
            while (!(f & 0x00000400)) {
                f <<= 1;
                e -=  1;
            }
            e += 1;
            f &= ~0x00000400;
        }
    } else if (e == 31) {
        if (f == 0)                                             // Inf
            return (s << 31) | 0x7f800000;
        else                                                    // NaN
            return (s << 31) | 0x7f800000 | (f << 13);
    }

    e = e + (127 - 15);
    f = f << 13;

    return ((s << 31) | (e << 23) | f);
}

HALF
floatToHALF(float i)
{
    union { float f; uint32_t i; } v;
    v.f = i;
    return floatToHalfI(v.i);
}

HALF
static floatToHalfI(uint32_t i)
{
    register int s =  (i >> 16) & 0x00008000;                   // sign
    register int e = ((i >> 23) & 0x000000ff) - (127 - 15);     // exponent
    register int f =   i        & 0x007fffff;                   // fraction

    // need to handle NaNs and Inf?
    if (e <= 0) {
        if (e < -10) {
            if (s)                                              // handle -0.0
               return 0x8000;
            else
               return 0;
        }
        f = (f | 0x00800000) >> (1 - e);
        return s | (f >> 13);
    } else if (e == 0xff - (127 - 15)) {
        if (f == 0)                                             // Inf
            return s | 0x7c00;
        else {                                                  // NAN
            f >>= 13;
            return s | 0x7c00 | f | (f == 0);
        }
    } else {
        if (e > 30)                                             // Overflow
            return s | 0x7c00;
        return s | (e << 10) | (f >> 13);
    }
}

int
main(int argc, char *argv[])
{
   float f1, f2;
   HALF h;

   printf("Please enter a floating point number: ");
   scanf("%f", &f1);

   h = floatToHALF(f1);
   f2 = HALFToFloat(h);

   printf("Results are: %f %f %#lx\n", f1, f2, h);
}

See the blog entry Half-Precision Floating Point Format for further information and an example of how to do the same thing using Python.
 

9 More Discussions You Might Find Interesting

1. UNIX for Dummies Questions & Answers

you have more and one unix type?

As a formem unix newbe I Just wanted to tell you about this cool site for all you confused people. If you need to support more than one unix type: Use this one. It's a life saver. http://www.unixguide.net/unixguide.shtml here (4 Replies)
Discussion started by: sunbird
4 Replies

2. Shell Programming and Scripting

Different type of shells?

Hello there, i just want to know what are the different type of shells and the main difference betwee them. The problem is that if you try to search over the net you will find a lot of information and hence you will have no enough time to read all of them.....Anyone can help with this?? (1 Reply)
Discussion started by: charbel
1 Replies

3. Shell Programming and Scripting

String type to date type

Can one string type variable changed into the date type variable. (1 Reply)
Discussion started by: rinku
1 Replies

4. Programming

array type has incomplete element type

Dear colleagues, One of my friend have a problem with c code. While compiling a c program it displays a message like "array type has incomplete element type". Any body can provide a solution for it. Jaganadh.G (1 Reply)
Discussion started by: jaganadh
1 Replies

5. Solaris

raid type

how to get the raid type of a mount if I am using solaris disksuite? thanks (1 Reply)
Discussion started by: melanie_pfefer
1 Replies

6. UNIX for Dummies Questions & Answers

Encoding Type

Hi, Where can I find the encoding type in a unix server ? Thanks in advance !!! (1 Reply)
Discussion started by: risshanth
1 Replies

7. UNIX for Dummies Questions & Answers

key_t type

I would like to print value of key generate like this.... key_t k = ftok(".",'c'); printf("key is %d \n" , k); Is there other way to print this type. I dont think I am getting right output which is key is 1662074913 (shouldn't it be 6362074913) since 'c' is 63 in hex (ascii table).... (2 Replies)
Discussion started by: joker40
2 Replies

8. Windows & DOS: Issues & Discussions

Type of RAM

Hello All Is there a way I can find out the type of RAM (DDR1 or DDR2 or DDR3), I'm using withoout opening the cabinet? Any Windows command? Thanks in advance. (5 Replies)
Discussion started by: tenderfoot
5 Replies

9. Programming

Changing type name

In C++, how can I change the type with another name For example How can I declaring an object real which would be the same as declaring it float (5 Replies)
Discussion started by: kristinu
5 Replies
All times are GMT -4. The time now is 04:39 AM.
Unix & Linux Forums Content Copyright 1993-2022. All Rights Reserved.
Privacy Policy