--tk-median --> --track-median, etc.
[Ale.git] / ale_fixed.h
blobe6f99aaeb26adff9d15932ce589b8e26086573d6
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 * Bit-conversion facilities.
154 static ale_fixed bits_to_fixed(bits_t b) {
155 ale_fixed result;
156 result.bits = b;
157 return result;
160 static bits_t fixed_to_bits(ale_fixed f) {
162 if (f.bits >= 1 << N)
163 return ((1 << N) - 1);
165 return f.bits;
170 * Constructors.
172 ale_fixed() {
173 bits = 0;
176 ale_fixed(const ale_fixed &f) {
177 bits = f.bits;
180 ale_fixed& operator=(const ale_fixed &f) {
181 bits = f.bits;
183 return (*this);
187 * Disable casting
190 static void disable_casting() {
191 casting_disabled = 1;
195 * Enable casting
198 static void enable_casting() {
199 casting_disabled = 0;
203 * Casting status.
206 static int casting_status() {
207 return !casting_disabled;
211 * Cast to ordinary numbers
214 operator double() const {
215 #if DEBUG_FIXED_POINT
217 * Removed for performance reasons.
220 assert(!casting_disabled);
221 if (bits == ALE_FIXED_NAN) {
222 double zero = 0;
223 double nan = zero / zero;
224 assert (isnan(nan));
225 return nan;
226 } else if (bits == ALE_FIXED_NEGINF) {
227 double zero = 0;
228 double negone = -1;
229 double neginf = negone / zero;
230 assert (isinf(neginf));
231 assert (neginf < 0);
232 return neginf;
233 } else if (bits == ALE_FIXED_POSINF) {
234 double zero = 0;
235 double posone = +1;
236 double posinf = posone / zero;
237 assert (isinf(posinf));
238 assert (posinf > 0);
239 return posinf;
241 #endif
243 return (((double) bits) / (1 << N));
246 operator float() const {
247 #if DEBUG_FIXED_POINT
249 * Removed for performance reasons.
252 assert(!casting_disabled);
253 if (bits == ALE_FIXED_NAN) {
254 float zero = 0;
255 float nan = zero / zero;
256 assert (isnan(nan));
257 return nan;
258 } else if (bits == ALE_FIXED_NEGINF) {
259 float zero = 0;
260 float negone = -1;
261 float neginf = negone / zero;
262 assert (isinf(neginf));
263 assert (neginf < 0);
264 return neginf;
265 } else if (bits == ALE_FIXED_POSINF) {
266 float zero = 0;
267 float posone = +1;
268 float posinf = posone / zero;
269 assert (isinf(posinf));
270 assert (posinf > 0);
271 return posinf;
273 #endif
275 return (((float) bits) / (1 << N));
278 operator int() const {
279 #if DEBUG_FIXED_POINT
281 * Removed for performance reasons.
284 assert (bits != ALE_FIXED_NAN);
285 assert (bits != ALE_FIXED_POSINF);
286 assert (bits != ALE_FIXED_NEGINF);
287 #endif
289 return bits / (1 << N);
292 operator unsigned int() const {
293 #if DEBUG_FIXED_POINT
295 * Removed for performance reasons.
298 assert (bits != ALE_FIXED_NAN);
299 assert (bits != ALE_FIXED_POSINF);
300 assert (bits != ALE_FIXED_NEGINF);
301 assert (bits >= 0);
302 #endif
304 return (unsigned int) operator int();
307 #if 0
308 template<class fixed_type_2, unsigned int M>
309 operator ale_fixed<fixed_type_2, M>() const {
310 ale_fixed<fixed_type_2, M> result;
312 if (bits == ALE_FIXED_NAN) {
313 result.bits = fixed_type_2::nan();
314 return result;
317 if (bits == ALE_FIXED_POSINF) {
318 result.bits = fixed_type_2::posinf();
319 return result;
322 if (bits == ALE_FIXED_NEGINF) {
323 result.bits = fixed_type_2::neginf();
324 return result;
327 if (sizeof(ale_fixed<fixed_type_2,M>) > sizeof(ale_fixed<fixed_type,N>)) {
328 typedef typename fixed_type_2::bits_t bits_t_calc;
330 bits_t_calc type_result;
332 if (M >= N)
333 type_result = bits << (bits_t_calc) ((int) M - (int) N);
334 else
335 type_result = bits / ((bits_t_calc) 1 << (bits_t_calc) ((int) N - (int) M));
337 result.bits = type_result;
339 } else {
340 typedef bits_t bits_t_calc;
342 bits_t_calc type_result;
344 if (M >= N)
345 type_result = bits << (bits_t_calc) ((int) M - (int) N);
346 else
347 type_result = bits / ((bits_t_calc) 1 << (bits_t_calc) ((int) N - (int) M));
349 if (type_result > fixed_type_2::posinf())
350 result.bits = fixed_type_2::posinf();
351 else if (type_result < fixed_type_2::neginf())
352 result.bits = fixed_type_2::neginf();
353 else
354 result.bits = type_result;
357 return result;
359 #endif
362 * Cast from ordinary numbers
365 template<class fixed_type_2, unsigned int M>
366 ale_fixed(const ale_fixed<fixed_type_2,M> &d) {
369 * XXX: this shouldn't be necessary.
372 bits = 0;
374 if (d.bits == fixed_type_2::nan()) {
375 bits = ALE_FIXED_NAN;
376 return;
379 if (bits == fixed_type_2::posinf()) {
380 bits = ALE_FIXED_POSINF;
381 return;
384 if (bits == fixed_type_2::neginf()) {
385 bits = ALE_FIXED_NEGINF;
386 return;
389 if (sizeof(ale_fixed<fixed_type,N>) > sizeof(ale_fixed<fixed_type_2,M>)) {
390 if (N >= M)
391 bits = d.bits << (bits_t) ((int) N - (int) M);
392 else
393 bits = d.bits / ((bits_t) 1 << (bits_t) ((int) M - (int) N));
394 } else {
395 typedef typename ale_fixed<fixed_type_2,M>::bits_t bits_t_calc;
397 bits_t_calc type_result;
399 if (N >= M)
400 type_result = d.bits << (bits_t_calc) ((int) N - (int) M);
401 else
402 type_result = d.bits / ((bits_t_calc) 1 << (bits_t_calc) ((int) M - (int) N));
404 if (type_result > ALE_FIXED_POSINF)
405 bits = ALE_FIXED_POSINF;
406 else if (type_result < ALE_FIXED_NEGINF)
407 bits = ALE_FIXED_NEGINF;
408 else
409 bits = type_result;
413 ale_fixed(double d) {
414 #if DEBUG_FIXED_POINT
416 * Removed due to a tendency to trigger unpredictably.
418 assert(!casting_disabled);
419 #endif
421 if (isnan(d)) {
422 bits = ALE_FIXED_NAN;
423 } else if (isinf(d) && d > 0) {
424 bits = ALE_FIXED_POSINF;
425 } else if (isinf(d) && d < 0) {
426 bits = ALE_FIXED_NEGINF;
427 } else {
428 bits = (bits_t) fixed_type::rint(d * (1 << N));
430 #if DEBUG_FIXED_POINT
432 * Removed for performance reasons.
435 assert((double) *this > (d - (double) 1 / (1 << N)));
436 assert((double) *this < (d + (double) 1 / (1 << N)));
438 assert(bits < ALE_FIXED_POSINF);
439 assert(bits > ALE_FIXED_NEGINF);
440 #endif
444 ale_fixed(int d) {
445 bits = (bits_t) d << N;
446 #if DEBUG_FIXED_POINT
448 * Removed for performance reasons.
451 assert((d >= 0 && bits >> N == d)
452 || (d < 0 && (-bits) >> N == -d));
454 assert (bits < ALE_FIXED_POSINF);
455 assert (bits > ALE_FIXED_NEGINF);
456 #endif
459 ale_fixed(unsigned int d) {
460 bits = (bits_t) d << N;
462 assert((unsigned int) (bits >> N) == d);
464 assert (bits < ALE_FIXED_POSINF);
465 assert (bits > ALE_FIXED_NEGINF);
469 * Operators.
472 ale_fixed operator-() const {
474 ale_fixed result;
476 if (bits == ALE_FIXED_NAN || bits == 0)
477 return *this;
478 else if (bits == ALE_FIXED_POSINF)
479 result.bits = ALE_FIXED_NEGINF;
480 else if (bits == ALE_FIXED_NEGINF)
481 result.bits = ALE_FIXED_POSINF;
482 else
483 result.bits = -bits;
485 return result;
488 ale_fixed unexceptional_negation() const {
489 ale_fixed result;
491 result.bits = -bits;
493 return result;
496 ale_fixed operator+(ale_fixed f) const {
497 ale_fixed result;
499 #if DEBUG_FIXED_POINT
501 * Removed for performance reasons.
504 if (bits == ALE_FIXED_NAN || f.bits == ALE_FIXED_NAN
505 || (bits == ALE_FIXED_POSINF && f.bits == ALE_FIXED_NEGINF)
506 || (bits == ALE_FIXED_NEGINF && f.bits == ALE_FIXED_POSINF)) {
507 result.bits = ALE_FIXED_NAN;
508 return result;
510 #endif
512 bits_t bits_result = bits + f.bits;
514 #if DEBUG_FIXED_POINT
516 * Removed for performance reasons.
519 if (bits_result >= ALE_FIXED_POSINF
520 || bits == ALE_FIXED_POSINF || f.bits == ALE_FIXED_POSINF
521 || bits > 0 && f.bits > 0 && bits_result < 0) {
522 result.bits = ALE_FIXED_POSINF;
523 return result;
524 } else if (bits_result <= ALE_FIXED_NEGINF
525 || bits == ALE_FIXED_NEGINF || f.bits == ALE_FIXED_NEGINF
526 || bits < 0 && f.bits < 0 && bits_result > 0) {
527 result.bits = ALE_FIXED_NEGINF;
528 return result;
530 #endif
532 result.bits = bits_result;
534 return result;
537 ale_fixed operator+(int i) const {
538 return operator+(ale_fixed(i));
541 ale_fixed operator+(unsigned int i) const {
542 return operator+(ale_fixed(i));
545 ale_fixed operator-(ale_fixed f) const {
546 ale_fixed result;
548 #if DEBUG_FIXED_POINT
550 * Removed for performance reasons.
553 if (bits == ALE_FIXED_NAN || f.bits == ALE_FIXED_NAN
554 || (bits == ALE_FIXED_POSINF && f.bits == ALE_FIXED_POSINF)
555 || (bits == ALE_FIXED_NEGINF && f.bits == ALE_FIXED_NEGINF)) {
556 result.bits = ALE_FIXED_NAN;
557 return result;
559 #endif
561 bits_t bits_result = bits - f.bits;
563 #if DEBUG_FIXED_POINT
565 * Removed for performance reasons.
568 if (bits_result >= ALE_FIXED_POSINF
569 || bits == ALE_FIXED_POSINF || f.bits == ALE_FIXED_NEGINF
570 || bits > 0 && f.bits < 0 && bits_result < 0) {
571 result.bits = ALE_FIXED_POSINF;
572 return result;
573 } else if (bits_result <= ALE_FIXED_NEGINF
574 || bits == ALE_FIXED_NEGINF || f.bits == ALE_FIXED_POSINF
575 || bits < 0 && f.bits > 0 && bits_result > 0) {
576 result.bits = ALE_FIXED_NEGINF;
577 return result;
579 #endif
581 result.bits = bits_result;
583 return result;
586 ale_fixed operator-(int i) const {
587 return operator-(ale_fixed(i));
590 ale_fixed operator-(unsigned int i) const {
591 return operator-(ale_fixed(i));
594 ale_fixed operator*(ale_fixed f) const {
595 ale_fixed result;
597 #if DEBUG_FIXED_POINT
599 * Removed for performance reasons.
602 if (bits == ALE_FIXED_NAN || f.bits == ALE_FIXED_NAN) {
603 result.bits = ALE_FIXED_NAN;
604 return result;
606 #endif
609 mulbits_t mul_result = ((mulbits_t) bits * (mulbits_t) f.bits) / (1 << N);
611 #if DEBUG_FIXED_POINT
613 * Removed for performance reasons.
616 if (mul_result > (mulbits_t) ALE_FIXED_POSINF
617 || mul_result < (mulbits_t) ALE_FIXED_NEGINF
618 || bits == ALE_FIXED_POSINF || f.bits == ALE_FIXED_POSINF
619 || bits == ALE_FIXED_NEGINF || f.bits == ALE_FIXED_NEGINF) {
620 if (mul_result > 0)
621 result.bits = ALE_FIXED_POSINF;
622 else if (mul_result < 0)
623 result.bits = ALE_FIXED_NEGINF;
624 else if (mul_result == 0)
625 result.bits = ALE_FIXED_NAN;
626 else
627 assert(0);
628 return result;
630 #endif
632 result.bits = mul_result;
633 return result;
636 ale_fixed operator*(int i) const {
637 return operator*(ale_fixed(i));
640 ale_fixed operator*(unsigned int i) const {
641 return operator*(ale_fixed(i));
644 ale_fixed operator/(ale_fixed f) const {
645 ale_fixed result;
648 * While this approach may not be suitable for all
649 * applications, it can be a convenient way to detect and
650 * manufacture non-finite values.
652 if ((bits == 0 && f.bits == 0)
653 #if DEBUG_FIXED_POINT
655 * Removed for performance reasons.
658 || bits == ALE_FIXED_NAN || f.bits == ALE_FIXED_NAN
659 || ((bits == ALE_FIXED_NEGINF || bits == ALE_FIXED_POSINF)
660 && (f.bits == ALE_FIXED_NEGINF || f.bits == ALE_FIXED_POSINF))
661 #endif
663 result.bits = ALE_FIXED_NAN;
664 return result;
665 } else if (f.bits == 0 && bits > 0) {
666 result.bits = ALE_FIXED_POSINF;
667 return result;
668 } else if (f.bits == 0 && bits < 0) {
669 result.bits = ALE_FIXED_NEGINF;
670 return result;
673 #if DEBUG_FIXED_POINT
675 * Removed for performance reasons.
678 else if (f.bits == ALE_FIXED_POSINF || f.bits == ALE_FIXED_NEGINF) {
679 result.bits = 0;
680 return result;
682 #endif
684 mulbits_t div_result = ((mulbits_t) bits << N) / f.bits;
686 #if DEBUG_FIXED_POINT
688 * Removed for performance reasons.
691 if (div_result > (mulbits_t) ALE_FIXED_POSINF) {
692 result.bits = ALE_FIXED_POSINF;
693 return result;
694 } else if (div_result < (mulbits_t) ALE_FIXED_NEGINF) {
695 result.bits = ALE_FIXED_NEGINF;
696 return result;
698 #endif
700 result.bits = (bits_t) div_result;
701 return result;
704 ale_fixed operator/(int i) const {
705 return operator/(ale_fixed(i));
708 ale_fixed operator/(unsigned int i) const {
709 return operator/(ale_fixed(i));
712 ale_fixed &operator+=(ale_fixed f) {
713 *this = *this + f;
714 return *this;
717 ale_fixed &operator-=(ale_fixed f) {
718 *this = *this - f;
719 return *this;
722 ale_fixed &operator*=(ale_fixed f) {
723 *this = *this * f;
724 return *this;
727 ale_fixed &operator/=(ale_fixed f) {
728 *this = *this / f;
729 return *this;
732 int operator!=(ale_fixed f) const {
733 if (bits == ALE_FIXED_NAN || f.bits == ALE_FIXED_NAN)
734 return 1;
736 if (bits == f.bits)
737 return 0;
739 return 1;
742 int operator==(ale_fixed f) const {
743 return !(operator!=(f));
746 int operator<=(ale_fixed f) const {
747 if (bits == ALE_FIXED_NAN || f.bits == ALE_FIXED_NAN)
748 return 0;
750 if (bits <= f.bits)
751 return 1;
753 return 0;
756 int operator>=(ale_fixed f) const {
757 if (bits == ALE_FIXED_NAN || f.bits == ALE_FIXED_NAN)
758 return 0;
760 if (bits >= f.bits)
761 return 1;
763 return 0;
766 int operator>(ale_fixed f) const {
767 if (bits == ALE_FIXED_NAN || f.bits == ALE_FIXED_NAN)
768 return 0;
770 if (bits > f.bits)
771 return 1;
773 return 0;
776 int operator<(ale_fixed f) const {
777 if (bits == ALE_FIXED_NAN || f.bits == ALE_FIXED_NAN)
778 return 0;
780 if (bits < f.bits)
781 return 1;
783 return 0;
786 int operator>=(int d) const {
787 return operator>=((ale_fixed) d);
790 int operator<=(int d) const {
791 return operator<=((ale_fixed) d);
794 int operator==(int d) const {
795 return operator==((ale_fixed) d);
798 int operator!=(int d) const {
799 return operator!=((ale_fixed) d);
802 int operator>(int d) const {
803 return operator>((ale_fixed) d);
806 int operator<(int d) const {
807 return operator<((ale_fixed) d);
810 int operator>=(double d) const {
811 return operator>=((ale_fixed) d);
814 int operator>=(float d) const {
815 return operator>=((ale_fixed) d);
818 int operator<=(double d) const {
819 return operator<=((ale_fixed) d);
822 int operator==(double d) const {
823 return operator==((ale_fixed) d);
826 int operator!=(double d) const {
827 return operator!=((ale_fixed) d);
830 int operator>(double d) const {
831 return operator>((ale_fixed) d);
834 int operator<(double d) const {
835 return operator<((ale_fixed) d);
838 int operator>=(unsigned int d) const {
839 return operator>=((ale_fixed) d);
842 int operator<=(unsigned int d) const {
843 return operator<=((ale_fixed) d);
846 int operator==(unsigned int d) const {
847 return operator==((ale_fixed) d);
850 int operator!=(unsigned int d) const {
851 return operator!=((ale_fixed) d);
854 int operator>(unsigned int d) const {
855 return operator>((ale_fixed) d);
858 int operator<(unsigned int d) const {
859 return operator<((ale_fixed) d);
864 #define ALE_FIXED_INCORPORATE_OPERATOR(return_value, op) \
865 template<class fixed_type, unsigned int N> \
866 return_value operator op(double a, const ale_fixed<fixed_type, N> &f) { \
867 ale_fixed<fixed_type, N> g(a); \
868 return g.operator op(f); \
871 template<class fixed_type, unsigned int N> \
872 return_value operator op(int a, const ale_fixed<fixed_type, N> &f) { \
873 return (ale_fixed<fixed_type, N>) a op f; \
876 template<class fixed_type, unsigned int N> \
877 return_value operator op(unsigned int a, const ale_fixed<fixed_type, N> &f) { \
878 return (ale_fixed<fixed_type, N>) a op f; \
881 #define STDARGS ale_fixed<fixed_type,N>
883 ALE_FIXED_INCORPORATE_OPERATOR(STDARGS, +);
884 ALE_FIXED_INCORPORATE_OPERATOR(STDARGS, -);
885 ALE_FIXED_INCORPORATE_OPERATOR(STDARGS, *);
886 ALE_FIXED_INCORPORATE_OPERATOR(STDARGS, /);
887 ALE_FIXED_INCORPORATE_OPERATOR(int, <=);
888 ALE_FIXED_INCORPORATE_OPERATOR(int, >=);
889 ALE_FIXED_INCORPORATE_OPERATOR(int, <);
890 ALE_FIXED_INCORPORATE_OPERATOR(int, >);
891 ALE_FIXED_INCORPORATE_OPERATOR(int, !=);
892 ALE_FIXED_INCORPORATE_OPERATOR(int, ==);
894 template<class fixed_type, unsigned int N>
895 ale_fixed<fixed_type, N> fabs(ale_fixed<fixed_type, N> f) {
896 if (f < ale_fixed<fixed_type, N>())
897 return -f;
898 return f;
901 template<class fixed_type, unsigned int N>
902 ale_fixed<fixed_type, N> pow(ale_fixed<fixed_type, N> f, double d) {
903 return pow((double) f, (double) d);
907 * sqrt() via the Babylonian method.
909 * http://en.wikipedia.org/wiki/Methods_of_computing_square_roots
912 template<class fixed_type, unsigned int N>
913 ale_fixed<fixed_type, N> sqrt(ale_fixed<fixed_type, N> f) {
914 ale_fixed<fixed_type, N> guess = f;
916 typedef typename ale_fixed<fixed_type, N>::mulbits_t mulbits_t;
918 for (int i = 0; i < 5; i++) {
919 guess.bits >>= 1;
921 if (guess.bits <= 0)
922 return 0;
924 mulbits_t sf = (mulbits_t) f.bits << (N - 2);
925 guess.bits = guess.bits + sf / guess.bits;
928 return guess;
931 template<class fixed_type, unsigned int N>
932 ale_fixed<fixed_type, N> pow(ale_fixed<fixed_type, N> f, ale_fixed<fixed_type, N> d) {
933 if (d == 2)
934 return f * f;
936 if (d == 1)
937 return f;
939 if (d == 0)
940 return ale_fixed<fixed_type,N>(1);
942 return pow((double) f, (double) d);
945 template<class fixed_type, unsigned int N>
946 ale_fixed<fixed_type, N> pow(ale_fixed<fixed_type, N> f, int d) {
947 if (d == 2)
948 return f * f;
950 if (d == 1)
951 return f;
953 if (d == 0)
954 return ale_fixed<fixed_type, N>(1);
956 if (d > 1)
957 return pow(f, d / 2) * pow(f, d - d / 2);
959 if (d < 0)
960 return 1 / pow(f, -d);
962 assert(0);
965 template<class fixed_type, unsigned int N>
966 ale_fixed<fixed_type, N> pow(ale_fixed<fixed_type, N> f, unsigned int d) {
967 if (d == 2)
968 return f * f;
970 if (d == 1)
971 return f;
973 if (d == 0)
974 return ale_fixed<fixed_type, N>(1);
976 return pow(f, d / 2) * pow(f, d - d / 2);
979 template<class fixed_type, unsigned int N>
980 ale_fixed<fixed_type, N> floor(ale_fixed<fixed_type, N> f) {
982 #if DEBUG_FIXED_POINT
984 * Removed for performance reasons.
987 if (N == 0
988 || f.bits == ALE_FIXED_POSINF
989 || f.bits == ALE_FIXED_NEGINF
990 || f.bits == ALE_FIXED_NAN)
991 return f;
992 #endif
994 ale_fixed<fixed_type, N> result;
996 result.bits = (f.bits & ~((1 << N) - 1));
999 * XXX: This isn't exactly right.
1001 if (f.bits < 0)
1002 result.bits -= 1;
1004 return result;
1007 template<class fixed_type, unsigned int N>
1008 ale_fixed<fixed_type, N> lrintf(ale_fixed<fixed_type, N> f) {
1010 #if DEBUG_FIXED_POINT
1012 * Removed for performance reasons.
1015 if (N == 0
1016 || f.bits == ALE_FIXED_POSINF
1017 || f.bits == ALE_FIXED_NEGINF
1018 || f.bits == ALE_FIXED_NAN)
1019 return f;
1020 #endif
1022 ale_fixed<fixed_type, N> result = floor(f);
1024 if (f.bits - result.bits >= (1 << N - 1))
1025 result.bits += (1 << N);
1027 return result;
1030 template<class fixed_type, unsigned int N>
1031 ale_fixed<fixed_type, N> ceil(ale_fixed<fixed_type, N> f) {
1032 return -floor(-f);
1035 template<class fixed_type, unsigned int N>
1036 int ale_isinf(ale_fixed<fixed_type, N> f) {
1037 return (f.bits == ALE_FIXED_NEGINF || f.bits == ALE_FIXED_POSINF);
1040 template<class fixed_type, unsigned int N>
1041 int ale_isnan(ale_fixed<fixed_type, N> f) {
1042 return (f.bits == ALE_FIXED_NAN);
1045 template<class fixed_type, unsigned int N>
1046 int finite(ale_fixed<fixed_type, N> f) {
1047 return (f.bits < ALE_FIXED_POSINF && f.bits > ALE_FIXED_NEGINF);
1050 template<class fixed_type, unsigned int N, unsigned int M>
1051 ale_fixed<fixed_type, N> convert_precision(ale_fixed<fixed_type, M> m) {
1054 * XXX: Checks should be added that precision is not
1055 * lost from most-significant bits.
1058 if (N != M)
1059 assert (0);
1061 ale_fixed<fixed_type, N> n;
1063 n.bits = m.bits << (N - M);
1065 return n;
1068 template<class fixed_type, unsigned int N>
1069 int ale_fixed<fixed_type, N>::casting_disabled = 0;
1071 #undef FIXED16
1072 #undef FIXED32
1074 #endif