/*	
 *	clipfp16.h
 *
 *	16bit浮動小数点形式
 *
 *	CLiP - Common Library for P/ECE
 *	Copyright (C) 2001-2009 Naoyuki Sawa
 *
 *	* Mon Jul 27 18:33:57 JST 2009 Naoyuki Sawa
 *	- 1st リリース。
 */
#ifndef __CLIP_FP16_H__
#define __CLIP_FP16_H__

/****************************************************************************
 *	
 ****************************************************************************/

/*	===================
 *	16bit浮動小数点形式
 *	===================
 *
 *	seeeeemm mmmmmmmm
 *	||||||++-++++++++- 仮数部 10bit + 暗黙の 1bit
 *	|+++++------------ 指数部  5bit   バイアス 15
 *	+----------------- 符号
 *
 *	表現可能な最小の絶対値 約 0.00006103515625 これよりも小さいと0になります
 *	表現可能な最大の絶対値 約 131008           これよりも大きいとオーバーフローエラーになります
 *
 *	DirectXのFP16と同じビット構造です。
 *	DirectXのFP16と、本ライブラリのfp16で、異なる点は、以下のとおりです。
 *
 *	・DirectXのFP16は、指数部が0、かつ、仮数部が0でないときに、非正規化数と見なします。
 *	  本ライブラリのfp16は、指数部が0の場合は、仮数部の値にかかわらず、+0と見なします。
 *
 *	・DirectXのFP16は、指数部が31の場合に、NaN、または、無限大と見なします。
 *	  本ライブラリのfp16は、指数部が31の場合も、指数部が1〜32の場合と同じ扱いとします。
 *
 *	本ライブラリのfp16は、メモリやファイル容量節約の目的で作成したものです。
 *	fp16を直接演算する関数は、用意していません。
 *	演算は、float形式で行なってください。
 *
 *	<例>
 *		fp16 data[1000];
 *		fread(data, sizeof(fp16), 1000, fp);     // ファイルからfp16形式でロード
 *		for(i = 0; i < 1000; i++) {
 *			float tmp = fp16_read(&data[i]); // fp16形式 -> float形式に変換
 *			tmp = sqrtf(tmp);                // float形式で演算
 *			fp16_write(&data[i], tmp);       // float形式 -> fp1形式に変換して格納
 *		}
 */
typedef struct _fp16 {
	unsigned short m : 10;	/* mantissa */
	unsigned short e :  5;	/* exponent */
	unsigned short s :  1;	/* sign */
} fp16;

/****************************************************************************
 *	グローバル関数
 ****************************************************************************/

/* メモリ上のfp16データを読み出し、float値に変換します。
 * [in]
 *	p		読み出すfp16データのアドレス。
 * [out]
 *	戻り値		変換したfloat値。
 */
float fp16_read(const fp16* p);

/* float値を変換し、メモリ上にfp16データとして格納します。
 * [in]
 *	p		格納先のfp16データのアドレス。
 *	f		変換するfloat値。
 */
void fp16_write(fp16* p, float f);

#endif /*__CLIP_FP16_H__*/

