ale_fixed.h: Revise so that 'long long' only appears when necessary for a given confi...
[Ale.git] / ale_fixed.h
blob8ef965f795bbabeb534ebd4afa8d2940a46a10b8
1 // Copyright 2007 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_fixed_h__
22 #define __ale_fixed_h__
24 #include <assert.h>
25 #include <stdio.h>
26 #include <stdlib.h>
28 #include "ale_math.h"
30 #define FIXED16 4
31 #define FIXED32 5
33 #define DEBUG_FIXED_POINT 0
36 * Define a fixed point data type.
39 class ale_fixed_16 {
40 public:
41 typedef short bits_t;
42 typedef int mulbits_t;
43 static bits_t posinf() {
44 return 32767;
46 static bits_t neginf() {
47 return -32766;
49 static bits_t nan() {
50 return -32767;
52 static bits_t rint(double d) {
53 return (bits_t) lrint(d);
57 class ale_fixed_16_calc {
58 public:
59 typedef int bits_t;
60 typedef int mulbits_t;
61 static bits_t posinf() {
62 return 2147483647;
64 static bits_t neginf() {
65 return -2147483646;
67 static bits_t nan() {
68 return -2147483647;
70 static bits_t rint(double d) {
71 return (bits_t) lrint(d);
75 #if ALE_COLORS == FIXED16
76 class ale_fixed_16_accum {
77 public:
78 typedef int bits_t;
79 typedef long long mulbits_t;
80 static bits_t posinf() {
81 return 2147483647;
83 static bits_t neginf() {
84 return -2147483646;
86 static bits_t nan() {
87 return -2147483647;
89 static bits_t rint(double d) {
90 return (bits_t) lrint(d);
93 #endif
95 #if ALE_COLORS == FIXED32 || ALE_COORDINATES == FIXED32
96 class ale_fixed_32 {
97 public:
98 typedef int bits_t;
99 typedef long long mulbits_t;
100 static bits_t posinf() {
101 return 2147483647;
103 static bits_t neginf() {
104 return -2147483646;
106 static bits_t nan() {
107 return -2147483647;
109 static bits_t rint(double d) {
110 return (bits_t) lrint(d);
113 #endif
115 #if ALE_COLORS == FIXED32
116 class ale_fixed_32_accum {
117 public:
118 typedef long long bits_t;
119 typedef long long mulbits_t;
120 static bits_t posinf() {
121 return 9223372036854775807LL;
123 static bits_t neginf() {
124 return -9223372036854775806LL;
126 static bits_t nan() {
127 return -9223372036854775807LL;
129 static bits_t rint(double d) {
130 return (bits_t) llrint(d);
133 #endif
135 #define ALE_FIXED_NAN (fixed_type::nan())
136 #define ALE_FIXED_POSINF (fixed_type::posinf())
137 #define ALE_FIXED_NEGINF (fixed_type::neginf())
139 template<class fixed_type, unsigned int N>
140 class ale_fixed {
141 static int casting_disabled;
143 public:
145 typedef typename fixed_type::bits_t bits_t;
146 typedef typename fixed_type::mulbits_t mulbits_t;
148 bits_t bits;
151 * Constructors.
153 ale_fixed() {
154 bits = 0;
157 ale_fixed(const ale_fixed &f) {
158 bits = f.bits;
161 ale_fixed& operator=(const ale_fixed &f) {
162 bits = f.bits;
164 return (*this);
168 * Disable casting
171 static void disable_casting() {
172 casting_disabled = 1;
176 * Enable casting
179 static void enable_casting() {
180 casting_disabled = 0;
184 * Casting status.
187 static int casting_status() {
188 return !casting_disabled;
192 * Cast to ordinary numbers
195 operator double() const {
196 #if DEBUG_FIXED_POINT
198 * Removed for performance reasons.
201 assert(!casting_disabled);
202 if (bits == ALE_FIXED_NAN) {
203 double zero = 0;
204 double nan = zero / zero;
205 assert (isnan(nan));
206 return nan;
207 } else if (bits == ALE_FIXED_NEGINF) {
208 double zero = 0;
209 double negone = -1;
210 double neginf = negone / zero;
211 assert (isinf(neginf));
212 assert (neginf < 0);
213 return neginf;
214 } else if (bits == ALE_FIXED_POSINF) {
215 double zero = 0;
216 double posone = +1;
217 double posinf = posone / zero;
218 assert (isinf(posinf));
219 assert (posinf > 0);
220 return posinf;
222 #endif
224 return (((double) bits) / (1 << N));
227 operator float() const {
228 #if DEBUG_FIXED_POINT
230 * Removed for performance reasons.
233 assert(!casting_disabled);
234 if (bits == ALE_FIXED_NAN) {
235 float zero = 0;
236 float nan = zero / zero;
237 assert (isnan(nan));
238 return nan;
239 } else if (bits == ALE_FIXED_NEGINF) {
240 float zero = 0;
241 float negone = -1;
242 float neginf = negone / zero;
243 assert (isinf(neginf));
244 assert (neginf < 0);
245 return neginf;
246 } else if (bits == ALE_FIXED_POSINF) {
247 float zero = 0;
248 float posone = +1;
249 float posinf = posone / zero;
250 assert (isinf(posinf));
251 assert (posinf > 0);
252 return posinf;
254 #endif
256 return (((float) bits) / (1 << N));
259 operator int() const {
260 #if DEBUG_FIXED_POINT
262 * Removed for performance reasons.
265 assert (bits != ALE_FIXED_NAN);
266 assert (bits != ALE_FIXED_POSINF);
267 assert (bits != ALE_FIXED_NEGINF);
268 #endif
270 return bits / (1 << N);
273 operator unsigned int() const {
274 #if DEBUG_FIXED_POINT
276 * Removed for performance reasons.
279 assert (bits != ALE_FIXED_NAN);
280 assert (bits != ALE_FIXED_POSINF);
281 assert (bits != ALE_FIXED_NEGINF);
282 assert (bits >= 0);
283 #endif
285 return (unsigned int) operator int();
288 #if 0
289 template<class fixed_type_2, unsigned int M>
290 operator ale_fixed<fixed_type_2, M>() const {
291 ale_fixed<fixed_type_2, M> result;
293 if (bits == ALE_FIXED_NAN) {
294 result.bits = fixed_type_2::nan();
295 return result;
298 if (bits == ALE_FIXED_POSINF) {
299 result.bits = fixed_type_2::posinf();
300 return result;
303 if (bits == ALE_FIXED_NEGINF) {
304 result.bits = fixed_type_2::neginf();
305 return result;
308 if (sizeof(ale_fixed<fixed_type_2,M>) > sizeof(ale_fixed<fixed_type,N>)) {
309 typedef typename fixed_type_2::bits_t bits_t_calc;
311 bits_t_calc type_result;
313 if (M >= N)
314 type_result = bits << (bits_t_calc) ((int) M - (int) N);
315 else
316 type_result = bits / ((bits_t_calc) 1 << (bits_t_calc) ((int) N - (int) M));
318 result.bits = type_result;
320 } else {
321 typedef bits_t bits_t_calc;
323 bits_t_calc type_result;
325 if (M >= N)
326 type_result = bits << (bits_t_calc) ((int) M - (int) N);
327 else
328 type_result = bits / ((bits_t_calc) 1 << (bits_t_calc) ((int) N - (int) M));
330 if (type_result > fixed_type_2::posinf())
331 result.bits = fixed_type_2::posinf();
332 else if (type_result < fixed_type_2::neginf())
333 result.bits = fixed_type_2::neginf();
334 else
335 result.bits = type_result;
338 return result;
340 #endif
343 * Cast from ordinary numbers
346 template<class fixed_type_2, unsigned int M>
347 ale_fixed(const ale_fixed<fixed_type_2,M> &d) {
350 * XXX: this shouldn't be necessary.
353 bits = 0;
355 if (d.bits == fixed_type_2::nan()) {
356 bits = ALE_FIXED_NAN;
357 return;
360 if (bits == fixed_type_2::posinf()) {
361 bits = ALE_FIXED_POSINF;
362 return;
365 if (bits == fixed_type_2::neginf()) {
366 bits = ALE_FIXED_NEGINF;
367 return;
370 if (sizeof(ale_fixed<fixed_type,N>) > sizeof(ale_fixed<fixed_type_2,M>)) {
371 if (N >= M)
372 bits = d.bits << (bits_t) ((int) N - (int) M);
373 else
374 bits = d.bits / ((bits_t) 1 << (bits_t) ((int) M - (int) N));
375 } else {
376 typedef typename ale_fixed<fixed_type_2,M>::bits_t bits_t_calc;
378 bits_t_calc type_result;
380 if (N >= M)
381 type_result = d.bits << (bits_t_calc) ((int) N - (int) M);
382 else
383 type_result = d.bits / ((bits_t_calc) 1 << (bits_t_calc) ((int) M - (int) N));
385 if (type_result > ALE_FIXED_POSINF)
386 bits = ALE_FIXED_POSINF;
387 else if (type_result < ALE_FIXED_NEGINF)
388 bits = ALE_FIXED_NEGINF;
389 else
390 bits = type_result;
394 ale_fixed(double d) {
395 assert(!casting_disabled);
397 if (isnan(d)) {
398 bits = ALE_FIXED_NAN;
399 } else if (isinf(d) && d > 0) {
400 bits = ALE_FIXED_POSINF;
401 } else if (isinf(d) && d < 0) {
402 bits = ALE_FIXED_NEGINF;
403 } else {
404 bits = (bits_t) fixed_type::rint(d * (1 << N));
406 #if DEBUG_FIXED_POINT
408 * Removed for performance reasons.
411 assert((double) *this > (d - (double) 1 / (1 << N)));
412 assert((double) *this < (d + (double) 1 / (1 << N)));
414 assert(bits < ALE_FIXED_POSINF);
415 assert(bits > ALE_FIXED_NEGINF);
416 #endif
420 ale_fixed(int d) {
421 bits = (bits_t) d << N;
422 #if DEBUG_FIXED_POINT
424 * Removed for performance reasons.
427 assert((d >= 0 && bits >> N == d)
428 || (d < 0 && (-bits) >> N == -d));
430 assert (bits < ALE_FIXED_POSINF);
431 assert (bits > ALE_FIXED_NEGINF);
432 #endif
435 ale_fixed(unsigned int d) {
436 bits = (bits_t) d << N;
438 assert((unsigned int) (bits >> N) == d);
440 assert (bits < ALE_FIXED_POSINF);
441 assert (bits > ALE_FIXED_NEGINF);
445 * Operators.
448 ale_fixed operator-() const {
450 ale_fixed result;
452 if (bits == ALE_FIXED_NAN || bits == 0)
453 return *this;
454 else if (bits == ALE_FIXED_POSINF)
455 result.bits = ALE_FIXED_NEGINF;
456 else if (bits == ALE_FIXED_NEGINF)
457 result.bits = ALE_FIXED_POSINF;
458 else
459 result.bits = -bits;
461 return result;
464 ale_fixed operator+(ale_fixed f) const {
465 ale_fixed result;
467 #if DEBUG_FIXED_POINT
469 * Removed for performance reasons.
472 if (bits == ALE_FIXED_NAN || f.bits == ALE_FIXED_NAN
473 || (bits == ALE_FIXED_POSINF && f.bits == ALE_FIXED_NEGINF)
474 || (bits == ALE_FIXED_NEGINF && f.bits == ALE_FIXED_POSINF)) {
475 result.bits = ALE_FIXED_NAN;
476 return result;
478 #endif
480 bits_t bits_result = bits + f.bits;
482 #if DEBUG_FIXED_POINT
484 * Removed for performance reasons.
487 if (bits_result >= ALE_FIXED_POSINF
488 || bits == ALE_FIXED_POSINF || f.bits == ALE_FIXED_POSINF
489 || bits > 0 && f.bits > 0 && bits_result < 0) {
490 result.bits = ALE_FIXED_POSINF;
491 return result;
492 } else if (bits_result <= ALE_FIXED_NEGINF
493 || bits == ALE_FIXED_NEGINF || f.bits == ALE_FIXED_NEGINF
494 || bits < 0 && f.bits < 0 && bits_result > 0) {
495 result.bits = ALE_FIXED_NEGINF;
496 return result;
498 #endif
500 result.bits = bits_result;
502 return result;
505 ale_fixed operator+(int i) const {
506 return operator+(ale_fixed(i));
509 ale_fixed operator+(unsigned int i) const {
510 return operator+(ale_fixed(i));
513 ale_fixed operator-(ale_fixed f) const {
514 ale_fixed result;
516 #if DEBUG_FIXED_POINT
518 * Removed for performance reasons.
521 if (bits == ALE_FIXED_NAN || f.bits == ALE_FIXED_NAN
522 || (bits == ALE_FIXED_POSINF && f.bits == ALE_FIXED_POSINF)
523 || (bits == ALE_FIXED_NEGINF && f.bits == ALE_FIXED_NEGINF)) {
524 result.bits = ALE_FIXED_NAN;
525 return result;
527 #endif
529 bits_t bits_result = bits - f.bits;
531 #if DEBUG_FIXED_POINT
533 * Removed for performance reasons.
536 if (bits_result >= ALE_FIXED_POSINF
537 || bits == ALE_FIXED_POSINF || f.bits == ALE_FIXED_NEGINF
538 || bits > 0 && f.bits < 0 && bits_result < 0) {
539 result.bits = ALE_FIXED_POSINF;
540 return result;
541 } else if (bits_result <= ALE_FIXED_NEGINF
542 || bits == ALE_FIXED_NEGINF || f.bits == ALE_FIXED_POSINF
543 || bits < 0 && f.bits > 0 && bits_result > 0) {
544 result.bits = ALE_FIXED_NEGINF;
545 return result;
547 #endif
549 result.bits = bits_result;
551 return result;
554 ale_fixed operator-(int i) const {
555 return operator-(ale_fixed(i));
558 ale_fixed operator-(unsigned int i) const {
559 return operator-(ale_fixed(i));
562 ale_fixed operator*(ale_fixed f) const {
563 ale_fixed result;
565 #if DEBUG_FIXED_POINT
567 * Removed for performance reasons.
570 if (bits == ALE_FIXED_NAN || f.bits == ALE_FIXED_NAN) {
571 result.bits = ALE_FIXED_NAN;
572 return result;
574 #endif
577 mulbits_t mul_result = ((mulbits_t) bits * (mulbits_t) f.bits) / (1 << N);
579 #if DEBUG_FIXED_POINT
581 * Removed for performance reasons.
584 if (mul_result > (mulbits_t) ALE_FIXED_POSINF
585 || mul_result < (mulbits_t) ALE_FIXED_NEGINF
586 || bits == ALE_FIXED_POSINF || f.bits == ALE_FIXED_POSINF
587 || bits == ALE_FIXED_NEGINF || f.bits == ALE_FIXED_NEGINF) {
588 if (mul_result > 0)
589 result.bits = ALE_FIXED_POSINF;
590 else if (mul_result < 0)
591 result.bits = ALE_FIXED_NEGINF;
592 else if (mul_result == 0)
593 result.bits = ALE_FIXED_NAN;
594 else
595 assert(0);
596 return result;
598 #endif
600 result.bits = mul_result;
601 return result;
604 ale_fixed operator*(int i) const {
605 return operator*(ale_fixed(i));
608 ale_fixed operator*(unsigned int i) const {
609 return operator*(ale_fixed(i));
612 ale_fixed operator/(ale_fixed f) const {
613 ale_fixed result;
616 * While this approach may not be suitable for all
617 * applications, it can be a convenient way to detect and
618 * manufacture non-finite values.
620 if ((bits == 0 && f.bits == 0)
621 #if DEBUG_FIXED_POINT
623 * Removed for performance reasons.
626 || bits == ALE_FIXED_NAN || f.bits == ALE_FIXED_NAN
627 || ((bits == ALE_FIXED_NEGINF || bits == ALE_FIXED_POSINF)
628 && (f.bits == ALE_FIXED_NEGINF || f.bits == ALE_FIXED_POSINF))
629 #endif
631 result.bits = ALE_FIXED_NAN;
632 return result;
633 } else if (f.bits == 0 && bits > 0) {
634 result.bits = ALE_FIXED_POSINF;
635 return result;
636 } else if (f.bits == 0 && bits < 0) {
637 result.bits = ALE_FIXED_NEGINF;
638 return result;
641 #if DEBUG_FIXED_POINT
643 * Removed for performance reasons.
646 else if (f.bits == ALE_FIXED_POSINF || f.bits == ALE_FIXED_NEGINF) {
647 result.bits = 0;
648 return result;
650 #endif
652 mulbits_t div_result = ((mulbits_t) bits << N) / f.bits;
654 #if DEBUG_FIXED_POINT
656 * Removed for performance reasons.
659 if (div_result > (mulbits_t) ALE_FIXED_POSINF) {
660 result.bits = ALE_FIXED_POSINF;
661 return result;
662 } else if (div_result < (mulbits_t) ALE_FIXED_NEGINF) {
663 result.bits = ALE_FIXED_NEGINF;
664 return result;
666 #endif
668 result.bits = (bits_t) div_result;
669 return result;
672 ale_fixed operator/(int i) const {
673 return operator/(ale_fixed(i));
676 ale_fixed operator/(unsigned int i) const {
677 return operator/(ale_fixed(i));
680 ale_fixed &operator+=(ale_fixed f) {
681 *this = *this + f;
682 return *this;
685 ale_fixed &operator-=(ale_fixed f) {
686 *this = *this - f;
687 return *this;
690 ale_fixed &operator*=(ale_fixed f) {
691 *this = *this * f;
692 return *this;
695 ale_fixed &operator/=(ale_fixed f) {
696 *this = *this / f;
697 return *this;
700 int operator!=(ale_fixed f) const {
701 if (bits == ALE_FIXED_NAN || f.bits == ALE_FIXED_NAN)
702 return 1;
704 if (bits == f.bits)
705 return 0;
707 return 1;
710 int operator==(ale_fixed f) const {
711 return !(operator!=(f));
714 int operator<=(ale_fixed f) const {
715 if (bits == ALE_FIXED_NAN || f.bits == ALE_FIXED_NAN)
716 return 0;
718 if (bits <= f.bits)
719 return 1;
721 return 0;
724 int operator>=(ale_fixed f) const {
725 if (bits == ALE_FIXED_NAN || f.bits == ALE_FIXED_NAN)
726 return 0;
728 if (bits >= f.bits)
729 return 1;
731 return 0;
734 int operator>(ale_fixed f) const {
735 if (bits == ALE_FIXED_NAN || f.bits == ALE_FIXED_NAN)
736 return 0;
738 if (bits > f.bits)
739 return 1;
741 return 0;
744 int operator<(ale_fixed f) const {
745 if (bits == ALE_FIXED_NAN || f.bits == ALE_FIXED_NAN)
746 return 0;
748 if (bits < f.bits)
749 return 1;
751 return 0;
754 int operator>=(int d) const {
755 return operator>=((ale_fixed) d);
758 int operator<=(int d) const {
759 return operator<=((ale_fixed) d);
762 int operator==(int d) const {
763 return operator==((ale_fixed) d);
766 int operator!=(int d) const {
767 return operator!=((ale_fixed) d);
770 int operator>(int d) const {
771 return operator>((ale_fixed) d);
774 int operator<(int d) const {
775 return operator<((ale_fixed) d);
778 int operator>=(double d) const {
779 return operator>=((ale_fixed) d);
782 int operator>=(float d) const {
783 return operator>=((ale_fixed) d);
786 int operator<=(double d) const {
787 return operator<=((ale_fixed) d);
790 int operator==(double d) const {
791 return operator==((ale_fixed) d);
794 int operator!=(double d) const {
795 return operator!=((ale_fixed) d);
798 int operator>(double d) const {
799 return operator>((ale_fixed) d);
802 int operator<(double d) const {
803 return operator<((ale_fixed) d);
806 int operator>=(unsigned int d) const {
807 return operator>=((ale_fixed) d);
810 int operator<=(unsigned int d) const {
811 return operator<=((ale_fixed) d);
814 int operator==(unsigned int d) const {
815 return operator==((ale_fixed) d);
818 int operator!=(unsigned int d) const {
819 return operator!=((ale_fixed) d);
822 int operator>(unsigned int d) const {
823 return operator>((ale_fixed) d);
826 int operator<(unsigned int d) const {
827 return operator<((ale_fixed) d);
832 #define ALE_FIXED_INCORPORATE_OPERATOR(return_value, op) \
833 template<class fixed_type, unsigned int N> \
834 return_value operator op(double a, const ale_fixed<fixed_type, N> &f) { \
835 ale_fixed<fixed_type, N> g(a); \
836 return g.operator op(f); \
839 template<class fixed_type, unsigned int N> \
840 return_value operator op(int a, const ale_fixed<fixed_type, N> &f) { \
841 return (ale_fixed<fixed_type, N>) a op f; \
844 template<class fixed_type, unsigned int N> \
845 return_value operator op(unsigned int a, const ale_fixed<fixed_type, N> &f) { \
846 return (ale_fixed<fixed_type, N>) a op f; \
849 #define STDARGS ale_fixed<fixed_type,N>
851 ALE_FIXED_INCORPORATE_OPERATOR(STDARGS, +);
852 ALE_FIXED_INCORPORATE_OPERATOR(STDARGS, -);
853 ALE_FIXED_INCORPORATE_OPERATOR(STDARGS, *);
854 ALE_FIXED_INCORPORATE_OPERATOR(STDARGS, /);
855 ALE_FIXED_INCORPORATE_OPERATOR(int, <=);
856 ALE_FIXED_INCORPORATE_OPERATOR(int, >=);
857 ALE_FIXED_INCORPORATE_OPERATOR(int, <);
858 ALE_FIXED_INCORPORATE_OPERATOR(int, >);
859 ALE_FIXED_INCORPORATE_OPERATOR(int, !=);
860 ALE_FIXED_INCORPORATE_OPERATOR(int, ==);
862 template<class fixed_type, unsigned int N>
863 ale_fixed<fixed_type, N> fabs(ale_fixed<fixed_type, N> f) {
864 if (f < ale_fixed<fixed_type, N>())
865 return -f;
866 return f;
869 template<class fixed_type, unsigned int N>
870 ale_fixed<fixed_type, N> pow(ale_fixed<fixed_type, N> f, double d) {
871 return pow((double) f, (double) d);
875 * sqrt() via the Babylonian method.
877 * http://en.wikipedia.org/wiki/Methods_of_computing_square_roots
880 template<class fixed_type, unsigned int N>
881 ale_fixed<fixed_type, N> sqrt(ale_fixed<fixed_type, N> f) {
882 ale_fixed<fixed_type, N> guess = f;
884 typedef typename ale_fixed<fixed_type, N>::mulbits_t mulbits_t;
886 for (int i = 0; i < 5; i++) {
887 guess.bits >>= 1;
889 if (guess.bits <= 0)
890 return 0;
892 mulbits_t sf = (mulbits_t) f.bits << (N - 2);
893 guess.bits = guess.bits + sf / guess.bits;
896 return guess;
899 template<class fixed_type, unsigned int N>
900 ale_fixed<fixed_type, N> pow(ale_fixed<fixed_type, N> f, ale_fixed<fixed_type, N> d) {
901 if (d == 2)
902 return f * f;
904 if (d == 1)
905 return f;
907 if (d == 0)
908 return ale_fixed<fixed_type,N>(1);
910 return pow((double) f, (double) d);
913 template<class fixed_type, unsigned int N>
914 ale_fixed<fixed_type, N> pow(ale_fixed<fixed_type, N> f, int d) {
915 if (d == 2)
916 return f * f;
918 if (d == 1)
919 return f;
921 if (d == 0)
922 return ale_fixed<fixed_type, N>(1);
924 if (d > 1)
925 return pow(f, d / 2) * pow(f, d - d / 2);
927 if (d < 0)
928 return 1 / pow(f, -d);
930 assert(0);
933 template<class fixed_type, unsigned int N>
934 ale_fixed<fixed_type, N> pow(ale_fixed<fixed_type, N> f, unsigned int d) {
935 if (d == 2)
936 return f * f;
938 if (d == 1)
939 return f;
941 if (d == 0)
942 return ale_fixed<fixed_type, N>(1);
944 return pow(f, d / 2) * pow(f, d - d / 2);
947 template<class fixed_type, unsigned int N>
948 ale_fixed<fixed_type, N> floor(ale_fixed<fixed_type, N> f) {
950 #if DEBUG_FIXED_POINT
952 * Removed for performance reasons.
955 if (N == 0
956 || f.bits == ALE_FIXED_POSINF
957 || f.bits == ALE_FIXED_NEGINF
958 || f.bits == ALE_FIXED_NAN)
959 return f;
960 #endif
962 ale_fixed<fixed_type, N> result;
964 result.bits = (f.bits & ~((1 << N) - 1));
967 * XXX: This isn't exactly right.
969 if (f.bits < 0)
970 result.bits -= 1;
972 return result;
975 template<class fixed_type, unsigned int N>
976 ale_fixed<fixed_type, N> lrintf(ale_fixed<fixed_type, N> f) {
978 #if DEBUG_FIXED_POINT
980 * Removed for performance reasons.
983 if (N == 0
984 || f.bits == ALE_FIXED_POSINF
985 || f.bits == ALE_FIXED_NEGINF
986 || f.bits == ALE_FIXED_NAN)
987 return f;
988 #endif
990 ale_fixed<fixed_type, N> result = floor(f);
992 if (f.bits - result.bits >= (1 << N - 1))
993 result.bits += (1 << N);
995 return result;
998 template<class fixed_type, unsigned int N>
999 ale_fixed<fixed_type, N> ceil(ale_fixed<fixed_type, N> f) {
1000 return -floor(-f);
1003 template<class fixed_type, unsigned int N>
1004 int ale_isinf(ale_fixed<fixed_type, N> f) {
1005 return (f.bits == ALE_FIXED_NEGINF || f.bits == ALE_FIXED_POSINF);
1008 template<class fixed_type, unsigned int N>
1009 int ale_isnan(ale_fixed<fixed_type, N> f) {
1010 return (f.bits == ALE_FIXED_NAN);
1013 template<class fixed_type, unsigned int N>
1014 int finite(ale_fixed<fixed_type, N> f) {
1015 return (f.bits < ALE_FIXED_POSINF && f.bits > ALE_FIXED_NEGINF);
1018 template<class fixed_type, unsigned int N, unsigned int M>
1019 ale_fixed<fixed_type, N> convert_precision(ale_fixed<fixed_type, M> m) {
1022 * XXX: Checks should be added that precision is not
1023 * lost from most-significant bits.
1026 if (N != M)
1027 assert (0);
1029 ale_fixed<fixed_type, N> n;
1031 n.bits = m.bits << (N - M);
1033 return n;
1036 template<class fixed_type, unsigned int N>
1037 int ale_fixed<fixed_type, N>::casting_disabled = 0;
1039 #undef FIXED16
1040 #undef FIXED32
1042 #endif