d2::render::ipc: Revise bounds calculations for improved performance.
[Ale.git] / ale_fixed.h
blobb78528c9fd9771ca8432cf1f5d2b786f54166c04
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 class ale_fixed_16_accum {
76 public:
77 typedef int bits_t;
78 typedef long long mulbits_t;
79 static bits_t posinf() {
80 return 2147483647;
82 static bits_t neginf() {
83 return -2147483646;
85 static bits_t nan() {
86 return -2147483647;
88 static bits_t rint(double d) {
89 return (bits_t) lrint(d);
93 #if ALE_COLORS == FIXED32 || ALE_COORDINATES == FIXED32
94 class ale_fixed_32 {
95 public:
96 typedef int bits_t;
97 typedef long long mulbits_t;
98 static bits_t posinf() {
99 return 2147483647;
101 static bits_t neginf() {
102 return -2147483646;
104 static bits_t nan() {
105 return -2147483647;
107 static bits_t rint(double d) {
108 return (bits_t) lrint(d);
111 #endif
113 #if ALE_COLORS == FIXED32
114 class ale_fixed_32_accum {
115 public:
116 typedef long long bits_t;
117 typedef long long mulbits_t;
118 static bits_t posinf() {
119 return 9223372036854775807LL;
121 static bits_t neginf() {
122 return -9223372036854775806LL;
124 static bits_t nan() {
125 return -9223372036854775807LL;
127 static bits_t rint(double d) {
128 return (bits_t) llrint(d);
131 #endif
133 #define ALE_FIXED_NAN (fixed_type::nan())
134 #define ALE_FIXED_POSINF (fixed_type::posinf())
135 #define ALE_FIXED_NEGINF (fixed_type::neginf())
137 template<class fixed_type, unsigned int N>
138 class ale_fixed {
139 static int casting_disabled;
141 public:
143 typedef typename fixed_type::bits_t bits_t;
144 typedef typename fixed_type::mulbits_t mulbits_t;
146 bits_t bits;
149 * Constructors.
151 ale_fixed() {
152 bits = 0;
155 ale_fixed(const ale_fixed &f) {
156 bits = f.bits;
159 ale_fixed& operator=(const ale_fixed &f) {
160 bits = f.bits;
162 return (*this);
166 * Disable casting
169 static void disable_casting() {
170 casting_disabled = 1;
174 * Enable casting
177 static void enable_casting() {
178 casting_disabled = 0;
182 * Casting status.
185 static int casting_status() {
186 return !casting_disabled;
190 * Cast to ordinary numbers
193 operator double() const {
194 #if DEBUG_FIXED_POINT
196 * Removed for performance reasons.
199 assert(!casting_disabled);
200 if (bits == ALE_FIXED_NAN) {
201 double zero = 0;
202 double nan = zero / zero;
203 assert (isnan(nan));
204 return nan;
205 } else if (bits == ALE_FIXED_NEGINF) {
206 double zero = 0;
207 double negone = -1;
208 double neginf = negone / zero;
209 assert (isinf(neginf));
210 assert (neginf < 0);
211 return neginf;
212 } else if (bits == ALE_FIXED_POSINF) {
213 double zero = 0;
214 double posone = +1;
215 double posinf = posone / zero;
216 assert (isinf(posinf));
217 assert (posinf > 0);
218 return posinf;
220 #endif
222 return (((double) bits) / (1 << N));
225 operator float() const {
226 #if DEBUG_FIXED_POINT
228 * Removed for performance reasons.
231 assert(!casting_disabled);
232 if (bits == ALE_FIXED_NAN) {
233 float zero = 0;
234 float nan = zero / zero;
235 assert (isnan(nan));
236 return nan;
237 } else if (bits == ALE_FIXED_NEGINF) {
238 float zero = 0;
239 float negone = -1;
240 float neginf = negone / zero;
241 assert (isinf(neginf));
242 assert (neginf < 0);
243 return neginf;
244 } else if (bits == ALE_FIXED_POSINF) {
245 float zero = 0;
246 float posone = +1;
247 float posinf = posone / zero;
248 assert (isinf(posinf));
249 assert (posinf > 0);
250 return posinf;
252 #endif
254 return (((float) bits) / (1 << N));
257 operator int() const {
258 #if DEBUG_FIXED_POINT
260 * Removed for performance reasons.
263 assert (bits != ALE_FIXED_NAN);
264 assert (bits != ALE_FIXED_POSINF);
265 assert (bits != ALE_FIXED_NEGINF);
266 #endif
268 return bits / (1 << N);
271 operator unsigned int() const {
272 #if DEBUG_FIXED_POINT
274 * Removed for performance reasons.
277 assert (bits != ALE_FIXED_NAN);
278 assert (bits != ALE_FIXED_POSINF);
279 assert (bits != ALE_FIXED_NEGINF);
280 assert (bits >= 0);
281 #endif
283 return (unsigned int) operator int();
286 #if 0
287 template<class fixed_type_2, unsigned int M>
288 operator ale_fixed<fixed_type_2, M>() const {
289 ale_fixed<fixed_type_2, M> result;
291 if (bits == ALE_FIXED_NAN) {
292 result.bits = fixed_type_2::nan();
293 return result;
296 if (bits == ALE_FIXED_POSINF) {
297 result.bits = fixed_type_2::posinf();
298 return result;
301 if (bits == ALE_FIXED_NEGINF) {
302 result.bits = fixed_type_2::neginf();
303 return result;
306 if (sizeof(ale_fixed<fixed_type_2,M>) > sizeof(ale_fixed<fixed_type,N>)) {
307 typedef typename fixed_type_2::bits_t bits_t_calc;
309 bits_t_calc type_result;
311 if (M >= N)
312 type_result = bits << (bits_t_calc) ((int) M - (int) N);
313 else
314 type_result = bits / ((bits_t_calc) 1 << (bits_t_calc) ((int) N - (int) M));
316 result.bits = type_result;
318 } else {
319 typedef bits_t bits_t_calc;
321 bits_t_calc type_result;
323 if (M >= N)
324 type_result = bits << (bits_t_calc) ((int) M - (int) N);
325 else
326 type_result = bits / ((bits_t_calc) 1 << (bits_t_calc) ((int) N - (int) M));
328 if (type_result > fixed_type_2::posinf())
329 result.bits = fixed_type_2::posinf();
330 else if (type_result < fixed_type_2::neginf())
331 result.bits = fixed_type_2::neginf();
332 else
333 result.bits = type_result;
336 return result;
338 #endif
341 * Cast from ordinary numbers
344 template<class fixed_type_2, unsigned int M>
345 ale_fixed(const ale_fixed<fixed_type_2,M> &d) {
348 * XXX: this shouldn't be necessary.
351 bits = 0;
353 if (d.bits == fixed_type_2::nan()) {
354 bits = ALE_FIXED_NAN;
355 return;
358 if (bits == fixed_type_2::posinf()) {
359 bits = ALE_FIXED_POSINF;
360 return;
363 if (bits == fixed_type_2::neginf()) {
364 bits = ALE_FIXED_NEGINF;
365 return;
368 if (sizeof(ale_fixed<fixed_type,N>) > sizeof(ale_fixed<fixed_type_2,M>)) {
369 if (N >= M)
370 bits = d.bits << (bits_t) ((int) N - (int) M);
371 else
372 bits = d.bits / ((bits_t) 1 << (bits_t) ((int) M - (int) N));
373 } else {
374 typedef typename ale_fixed<fixed_type_2,M>::bits_t bits_t_calc;
376 bits_t_calc type_result;
378 if (N >= M)
379 type_result = d.bits << (bits_t_calc) ((int) N - (int) M);
380 else
381 type_result = d.bits / ((bits_t_calc) 1 << (bits_t_calc) ((int) M - (int) N));
383 if (type_result > ALE_FIXED_POSINF)
384 bits = ALE_FIXED_POSINF;
385 else if (type_result < ALE_FIXED_NEGINF)
386 bits = ALE_FIXED_NEGINF;
387 else
388 bits = type_result;
392 ale_fixed(double d) {
393 assert(!casting_disabled);
395 if (isnan(d)) {
396 bits = ALE_FIXED_NAN;
397 } else if (isinf(d) && d > 0) {
398 bits = ALE_FIXED_POSINF;
399 } else if (isinf(d) && d < 0) {
400 bits = ALE_FIXED_NEGINF;
401 } else {
402 bits = (bits_t) fixed_type::rint(d * (1 << N));
404 #if DEBUG_FIXED_POINT
406 * Removed for performance reasons.
409 assert((double) *this > (d - (double) 1 / (1 << N)));
410 assert((double) *this < (d + (double) 1 / (1 << N)));
412 assert(bits < ALE_FIXED_POSINF);
413 assert(bits > ALE_FIXED_NEGINF);
414 #endif
418 ale_fixed(int d) {
419 bits = (bits_t) d << N;
420 #if DEBUG_FIXED_POINT
422 * Removed for performance reasons.
425 assert((d >= 0 && bits >> N == d)
426 || (d < 0 && (-bits) >> N == -d));
428 assert (bits < ALE_FIXED_POSINF);
429 assert (bits > ALE_FIXED_NEGINF);
430 #endif
433 ale_fixed(unsigned int d) {
434 bits = (bits_t) d << N;
436 assert((unsigned int) (bits >> N) == d);
438 assert (bits < ALE_FIXED_POSINF);
439 assert (bits > ALE_FIXED_NEGINF);
443 * Operators.
446 ale_fixed operator-() const {
448 ale_fixed result;
450 if (bits == ALE_FIXED_NAN || bits == 0)
451 return *this;
452 else if (bits == ALE_FIXED_POSINF)
453 result.bits = ALE_FIXED_NEGINF;
454 else if (bits == ALE_FIXED_NEGINF)
455 result.bits = ALE_FIXED_POSINF;
456 else
457 result.bits = -bits;
459 return result;
462 ale_fixed operator+(ale_fixed f) const {
463 ale_fixed result;
465 #if DEBUG_FIXED_POINT
467 * Removed for performance reasons.
470 if (bits == ALE_FIXED_NAN || f.bits == ALE_FIXED_NAN
471 || (bits == ALE_FIXED_POSINF && f.bits == ALE_FIXED_NEGINF)
472 || (bits == ALE_FIXED_NEGINF && f.bits == ALE_FIXED_POSINF)) {
473 result.bits = ALE_FIXED_NAN;
474 return result;
476 #endif
478 bits_t bits_result = bits + f.bits;
480 #if DEBUG_FIXED_POINT
482 * Removed for performance reasons.
485 if (bits_result >= ALE_FIXED_POSINF
486 || bits == ALE_FIXED_POSINF || f.bits == ALE_FIXED_POSINF
487 || bits > 0 && f.bits > 0 && bits_result < 0) {
488 result.bits = ALE_FIXED_POSINF;
489 return result;
490 } else if (bits_result <= ALE_FIXED_NEGINF
491 || bits == ALE_FIXED_NEGINF || f.bits == ALE_FIXED_NEGINF
492 || bits < 0 && f.bits < 0 && bits_result > 0) {
493 result.bits = ALE_FIXED_NEGINF;
494 return result;
496 #endif
498 result.bits = bits_result;
500 return result;
503 ale_fixed operator+(int i) const {
504 return operator+(ale_fixed(i));
507 ale_fixed operator+(unsigned int i) const {
508 return operator+(ale_fixed(i));
511 ale_fixed operator-(ale_fixed f) const {
512 ale_fixed result;
514 #if DEBUG_FIXED_POINT
516 * Removed for performance reasons.
519 if (bits == ALE_FIXED_NAN || f.bits == ALE_FIXED_NAN
520 || (bits == ALE_FIXED_POSINF && f.bits == ALE_FIXED_POSINF)
521 || (bits == ALE_FIXED_NEGINF && f.bits == ALE_FIXED_NEGINF)) {
522 result.bits = ALE_FIXED_NAN;
523 return result;
525 #endif
527 bits_t bits_result = bits - f.bits;
529 #if DEBUG_FIXED_POINT
531 * Removed for performance reasons.
534 if (bits_result >= ALE_FIXED_POSINF
535 || bits == ALE_FIXED_POSINF || f.bits == ALE_FIXED_NEGINF
536 || bits > 0 && f.bits < 0 && bits_result < 0) {
537 result.bits = ALE_FIXED_POSINF;
538 return result;
539 } else if (bits_result <= ALE_FIXED_NEGINF
540 || bits == ALE_FIXED_NEGINF || f.bits == ALE_FIXED_POSINF
541 || bits < 0 && f.bits > 0 && bits_result > 0) {
542 result.bits = ALE_FIXED_NEGINF;
543 return result;
545 #endif
547 result.bits = bits_result;
549 return result;
552 ale_fixed operator-(int i) const {
553 return operator-(ale_fixed(i));
556 ale_fixed operator-(unsigned int i) const {
557 return operator-(ale_fixed(i));
560 ale_fixed operator*(ale_fixed f) const {
561 ale_fixed result;
563 #if DEBUG_FIXED_POINT
565 * Removed for performance reasons.
568 if (bits == ALE_FIXED_NAN || f.bits == ALE_FIXED_NAN) {
569 result.bits = ALE_FIXED_NAN;
570 return result;
572 #endif
575 mulbits_t mul_result = ((mulbits_t) bits * (mulbits_t) f.bits) / (1 << N);
577 #if DEBUG_FIXED_POINT
579 * Removed for performance reasons.
582 if (mul_result > (mulbits_t) ALE_FIXED_POSINF
583 || mul_result < (mulbits_t) ALE_FIXED_NEGINF
584 || bits == ALE_FIXED_POSINF || f.bits == ALE_FIXED_POSINF
585 || bits == ALE_FIXED_NEGINF || f.bits == ALE_FIXED_NEGINF) {
586 if (mul_result > 0)
587 result.bits = ALE_FIXED_POSINF;
588 else if (mul_result < 0)
589 result.bits = ALE_FIXED_NEGINF;
590 else if (mul_result == 0)
591 result.bits = ALE_FIXED_NAN;
592 else
593 assert(0);
594 return result;
596 #endif
598 result.bits = mul_result;
599 return result;
602 ale_fixed operator*(int i) const {
603 return operator*(ale_fixed(i));
606 ale_fixed operator*(unsigned int i) const {
607 return operator*(ale_fixed(i));
610 ale_fixed operator/(ale_fixed f) const {
611 ale_fixed result;
614 * While this approach may not be suitable for all
615 * applications, it can be a convenient way to detect and
616 * manufacture non-finite values.
618 if ((bits == 0 && f.bits == 0)
619 #if DEBUG_FIXED_POINT
621 * Removed for performance reasons.
624 || bits == ALE_FIXED_NAN || f.bits == ALE_FIXED_NAN
625 || ((bits == ALE_FIXED_NEGINF || bits == ALE_FIXED_POSINF)
626 && (f.bits == ALE_FIXED_NEGINF || f.bits == ALE_FIXED_POSINF))
627 #endif
629 result.bits = ALE_FIXED_NAN;
630 return result;
631 } else if (f.bits == 0 && bits > 0) {
632 result.bits = ALE_FIXED_POSINF;
633 return result;
634 } else if (f.bits == 0 && bits < 0) {
635 result.bits = ALE_FIXED_NEGINF;
636 return result;
639 #if DEBUG_FIXED_POINT
641 * Removed for performance reasons.
644 else if (f.bits == ALE_FIXED_POSINF || f.bits == ALE_FIXED_NEGINF) {
645 result.bits = 0;
646 return result;
648 #endif
650 mulbits_t div_result = ((mulbits_t) bits << N) / f.bits;
652 #if DEBUG_FIXED_POINT
654 * Removed for performance reasons.
657 if (div_result > (mulbits_t) ALE_FIXED_POSINF) {
658 result.bits = ALE_FIXED_POSINF;
659 return result;
660 } else if (div_result < (mulbits_t) ALE_FIXED_NEGINF) {
661 result.bits = ALE_FIXED_NEGINF;
662 return result;
664 #endif
666 result.bits = (bits_t) div_result;
667 return result;
670 ale_fixed operator/(int i) const {
671 return operator/(ale_fixed(i));
674 ale_fixed operator/(unsigned int i) const {
675 return operator/(ale_fixed(i));
678 ale_fixed &operator+=(ale_fixed f) {
679 *this = *this + f;
680 return *this;
683 ale_fixed &operator-=(ale_fixed f) {
684 *this = *this - f;
685 return *this;
688 ale_fixed &operator*=(ale_fixed f) {
689 *this = *this * f;
690 return *this;
693 ale_fixed &operator/=(ale_fixed f) {
694 *this = *this / f;
695 return *this;
698 int operator!=(ale_fixed f) const {
699 if (bits == ALE_FIXED_NAN || f.bits == ALE_FIXED_NAN)
700 return 1;
702 if (bits == f.bits)
703 return 0;
705 return 1;
708 int operator==(ale_fixed f) const {
709 return !(operator!=(f));
712 int operator<=(ale_fixed f) const {
713 if (bits == ALE_FIXED_NAN || f.bits == ALE_FIXED_NAN)
714 return 0;
716 if (bits <= f.bits)
717 return 1;
719 return 0;
722 int operator>=(ale_fixed f) const {
723 if (bits == ALE_FIXED_NAN || f.bits == ALE_FIXED_NAN)
724 return 0;
726 if (bits >= f.bits)
727 return 1;
729 return 0;
732 int operator>(ale_fixed f) const {
733 if (bits == ALE_FIXED_NAN || f.bits == ALE_FIXED_NAN)
734 return 0;
736 if (bits > f.bits)
737 return 1;
739 return 0;
742 int operator<(ale_fixed f) const {
743 if (bits == ALE_FIXED_NAN || f.bits == ALE_FIXED_NAN)
744 return 0;
746 if (bits < f.bits)
747 return 1;
749 return 0;
752 int operator>=(int d) const {
753 return operator>=((ale_fixed) d);
756 int operator<=(int d) const {
757 return operator<=((ale_fixed) d);
760 int operator==(int d) const {
761 return operator==((ale_fixed) d);
764 int operator!=(int d) const {
765 return operator!=((ale_fixed) d);
768 int operator>(int d) const {
769 return operator>((ale_fixed) d);
772 int operator<(int d) const {
773 return operator<((ale_fixed) d);
776 int operator>=(double d) const {
777 return operator>=((ale_fixed) d);
780 int operator>=(float d) const {
781 return operator>=((ale_fixed) d);
784 int operator<=(double d) const {
785 return operator<=((ale_fixed) d);
788 int operator==(double d) const {
789 return operator==((ale_fixed) d);
792 int operator!=(double d) const {
793 return operator!=((ale_fixed) d);
796 int operator>(double d) const {
797 return operator>((ale_fixed) d);
800 int operator<(double d) const {
801 return operator<((ale_fixed) d);
804 int operator>=(unsigned int d) const {
805 return operator>=((ale_fixed) d);
808 int operator<=(unsigned int d) const {
809 return operator<=((ale_fixed) d);
812 int operator==(unsigned int d) const {
813 return operator==((ale_fixed) d);
816 int operator!=(unsigned int d) const {
817 return operator!=((ale_fixed) d);
820 int operator>(unsigned int d) const {
821 return operator>((ale_fixed) d);
824 int operator<(unsigned int d) const {
825 return operator<((ale_fixed) d);
830 #define ALE_FIXED_INCORPORATE_OPERATOR(return_value, op) \
831 template<class fixed_type, unsigned int N> \
832 return_value operator op(double a, const ale_fixed<fixed_type, N> &f) { \
833 ale_fixed<fixed_type, N> g(a); \
834 return g.operator op(f); \
837 template<class fixed_type, unsigned int N> \
838 return_value operator op(int a, const ale_fixed<fixed_type, N> &f) { \
839 return (ale_fixed<fixed_type, N>) a op f; \
842 template<class fixed_type, unsigned int N> \
843 return_value operator op(unsigned int a, const ale_fixed<fixed_type, N> &f) { \
844 return (ale_fixed<fixed_type, N>) a op f; \
847 #define STDARGS ale_fixed<fixed_type,N>
849 ALE_FIXED_INCORPORATE_OPERATOR(STDARGS, +);
850 ALE_FIXED_INCORPORATE_OPERATOR(STDARGS, -);
851 ALE_FIXED_INCORPORATE_OPERATOR(STDARGS, *);
852 ALE_FIXED_INCORPORATE_OPERATOR(STDARGS, /);
853 ALE_FIXED_INCORPORATE_OPERATOR(int, <=);
854 ALE_FIXED_INCORPORATE_OPERATOR(int, >=);
855 ALE_FIXED_INCORPORATE_OPERATOR(int, <);
856 ALE_FIXED_INCORPORATE_OPERATOR(int, >);
857 ALE_FIXED_INCORPORATE_OPERATOR(int, !=);
858 ALE_FIXED_INCORPORATE_OPERATOR(int, ==);
860 template<class fixed_type, unsigned int N>
861 ale_fixed<fixed_type, N> fabs(ale_fixed<fixed_type, N> f) {
862 if (f < ale_fixed<fixed_type, N>())
863 return -f;
864 return f;
867 template<class fixed_type, unsigned int N>
868 ale_fixed<fixed_type, N> pow(ale_fixed<fixed_type, N> f, double d) {
869 return pow((double) f, (double) d);
873 * sqrt() via the Babylonian method.
875 * http://en.wikipedia.org/wiki/Methods_of_computing_square_roots
878 template<class fixed_type, unsigned int N>
879 ale_fixed<fixed_type, N> sqrt(ale_fixed<fixed_type, N> f) {
880 ale_fixed<fixed_type, N> guess = f;
882 for (int i = 0; i < 5; i++) {
883 guess.bits >>= 1;
885 if (guess.bits <= 0)
886 return 0;
888 long long sf = (long long) f.bits << (N - 2);
889 guess.bits = guess.bits + sf / guess.bits;
892 return guess;
895 template<class fixed_type, unsigned int N>
896 ale_fixed<fixed_type, N> pow(ale_fixed<fixed_type, N> f, ale_fixed<fixed_type, N> d) {
897 if (d == 2)
898 return f * f;
900 if (d == 1)
901 return f;
903 if (d == 0)
904 return ale_fixed<fixed_type,N>(1);
906 return pow((double) f, (double) d);
909 template<class fixed_type, unsigned int N>
910 ale_fixed<fixed_type, N> pow(ale_fixed<fixed_type, N> f, int d) {
911 if (d == 2)
912 return f * f;
914 if (d == 1)
915 return f;
917 if (d == 0)
918 return ale_fixed<fixed_type, N>(1);
920 if (d > 1)
921 return pow(f, d / 2) * pow(f, d - d / 2);
923 if (d < 0)
924 return 1 / pow(f, -d);
926 assert(0);
929 template<class fixed_type, unsigned int N>
930 ale_fixed<fixed_type, N> pow(ale_fixed<fixed_type, N> f, unsigned int d) {
931 if (d == 2)
932 return f * f;
934 if (d == 1)
935 return f;
937 if (d == 0)
938 return ale_fixed<fixed_type, N>(1);
940 return pow(f, d / 2) * pow(f, d - d / 2);
943 template<class fixed_type, unsigned int N>
944 ale_fixed<fixed_type, N> floor(ale_fixed<fixed_type, N> f) {
946 #if DEBUG_FIXED_POINT
948 * Removed for performance reasons.
951 if (N == 0
952 || f.bits == ALE_FIXED_POSINF
953 || f.bits == ALE_FIXED_NEGINF
954 || f.bits == ALE_FIXED_NAN)
955 return f;
956 #endif
958 ale_fixed<fixed_type, N> result;
960 result.bits = (f.bits & ~((1 << N) - 1));
963 * XXX: This isn't exactly right.
965 if (f.bits < 0)
966 result.bits -= 1;
968 return result;
971 template<class fixed_type, unsigned int N>
972 ale_fixed<fixed_type, N> lrintf(ale_fixed<fixed_type, N> f) {
974 #if DEBUG_FIXED_POINT
976 * Removed for performance reasons.
979 if (N == 0
980 || f.bits == ALE_FIXED_POSINF
981 || f.bits == ALE_FIXED_NEGINF
982 || f.bits == ALE_FIXED_NAN)
983 return f;
984 #endif
986 ale_fixed<fixed_type, N> result = floor(f);
988 if (f.bits - result.bits >= (1 << N - 1))
989 result.bits += (1 << N);
991 return result;
994 template<class fixed_type, unsigned int N>
995 ale_fixed<fixed_type, N> ceil(ale_fixed<fixed_type, N> f) {
996 return -floor(-f);
999 template<class fixed_type, unsigned int N>
1000 int ale_isinf(ale_fixed<fixed_type, N> f) {
1001 return (f.bits == ALE_FIXED_NEGINF || f.bits == ALE_FIXED_POSINF);
1004 template<class fixed_type, unsigned int N>
1005 int ale_isnan(ale_fixed<fixed_type, N> f) {
1006 return (f.bits == ALE_FIXED_NAN);
1009 template<class fixed_type, unsigned int N>
1010 int finite(ale_fixed<fixed_type, N> f) {
1011 return (f.bits < ALE_FIXED_POSINF && f.bits > ALE_FIXED_NEGINF);
1014 template<class fixed_type, unsigned int N, unsigned int M>
1015 ale_fixed<fixed_type, N> convert_precision(ale_fixed<fixed_type, M> m) {
1018 * XXX: Checks should be added that precision is not
1019 * lost from most-significant bits.
1022 if (N != M)
1023 assert (0);
1025 ale_fixed<fixed_type, N> n;
1027 n.bits = m.bits << (N - M);
1029 return n;
1032 template<class fixed_type, unsigned int N>
1033 int ale_fixed<fixed_type, N>::casting_disabled = 0;
1035 #undef FIXED16
1036 #undef FIXED32
1038 #endif