1 // Copyright 2002, 2004 David Hilvert <dhilvert@auricle.dyndns.org>,
2 // <dhilvert@ugcs.caltech.edu>
4 /* This file is part of the Anti-Lamenessing Engine.
6 The Anti-Lamenessing Engine is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 The Anti-Lamenessing Engine is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with the Anti-Lamenessing Engine; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #ifndef __ale_real_h__
22 #define __ale_real_h__
29 * Real-valued type used to represent the range of an image (colors, weights,
32 * ale_real is used in computation.
33 * ale_sreal is used for storage.
36 #if ALE_COLORS == SINGLE
38 typedef float ale_real
;
39 typedef float ale_sreal
;
41 #define ALE_REAL_PRECISION_STRING "SINGLE"
43 #elif ALE_COLORS == DOUBLE
45 typedef double ale_real
;
46 typedef double ale_sreal
;
48 #define ALE_REAL_PRECISION_STRING "DOUBLE"
50 #elif ALE_COLORS == HALF
53 * What follows is one approach to packing a floating point
54 * number into 16 bits. This implementation is very slow.
57 #define MANTISSA_BITS (9)
58 #define EXP_BITS (15 - MANTISSA_BITS)
59 #define EXP_SPECIAL (1 << (EXP_BITS - 1))
60 #define EXP_MAX (EXP_SPECIAL - 1)
61 #define EXP_MIN (-EXP_MAX)
63 typedef float ale_real
;
71 uint16_t mant
:MANTISSA_BITS
;
72 int16_t exp
:EXP_BITS
;
79 ale_sreal
operator=(float v
) {
82 } else if (isnan(v
)) {
83 u
.fpr
.exp
= EXP_SPECIAL
;
99 int log2
= (int) floor (log(v
) / log(2));
102 * Test the exponent against the largest expressible
103 * exponent for ale_sreal.
106 if (log2
> EXP_MAX
) {
111 u
.fpr
.exp
= EXP_SPECIAL
;
118 * Test the exponent against the smallest expressible
119 * exponent for ale_sreal.
122 if (log2
< EXP_MIN
) {
134 * The exponent is in range, so use it.
139 u
.fpr
.mant
= (uint16_t) floor(v
/ pow(2, log2
) * (1 << (MANTISSA_BITS
- 1)));
145 operator float() const {
146 float result
= 3.14159;
148 if (((uint16_t) u
.fpr
.exp
== EXP_SPECIAL
) && (u
.fpr
.mant
== 1)) {
159 } else if (((uint16_t) u
.fpr
.exp
== EXP_SPECIAL
) && (u
.fpr
.mant
== 0)) {
170 } else if ((uint16_t) u
.fpr
.exp
!= EXP_SPECIAL
) {
176 result
= u
.fpr
.mant
/ ((double) (1 << (MANTISSA_BITS
- 1)))
188 ale_sreal
operator-=(float r
) {
189 *this = (float) *this - (float) r
;
192 ale_sreal
operator/=(float r
) {
193 *this = (float) *this / (float) r
;
196 ale_sreal
operator*=(float r
) {
197 *this = (float) *this * (float) r
;
200 ale_sreal
operator+=(float r
) {
201 *this = (float) *this + (float) r
;
212 #define ALE_REAL_PRECISION_STRING "HALF"
216 #warning Unknown precision in ale_real.h: Choosing PRECISION=SINGLE.
218 typedef float ale_real
;
219 typedef float ale_sreal
;
221 #define ALE_REAL_PRECISION_STRING "SINGLE"