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__
33 #define DEBUG_FIXED_POINT 0
36 * Define a fixed point data type.
42 typedef int mulbits_t
;
43 static bits_t
posinf() {
46 static bits_t
neginf() {
52 static bits_t
rint(double d
) {
53 return (bits_t
) lrint(d
);
57 class ale_fixed_16_calc
{
60 typedef int mulbits_t
;
61 static bits_t
posinf() {
64 static bits_t
neginf() {
70 static bits_t
rint(double d
) {
71 return (bits_t
) lrint(d
);
75 #if ALE_COLORS == FIXED16
76 class ale_fixed_16_accum
{
79 typedef long long mulbits_t
;
80 static bits_t
posinf() {
83 static bits_t
neginf() {
89 static bits_t
rint(double d
) {
90 return (bits_t
) lrint(d
);
95 #if ALE_COLORS == FIXED32 || ALE_COORDINATES == FIXED32
99 typedef long long mulbits_t
;
100 static bits_t
posinf() {
103 static bits_t
neginf() {
106 static bits_t
nan() {
109 static bits_t
rint(double d
) {
110 return (bits_t
) lrint(d
);
115 #if ALE_COLORS == FIXED32
116 class ale_fixed_32_accum
{
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
);
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
>
141 static int casting_disabled
;
145 typedef typename
fixed_type::bits_t bits_t
;
146 typedef typename
fixed_type::mulbits_t mulbits_t
;
151 * Bit-conversion facilities.
154 static ale_fixed
bits_to_fixed(bits_t b
) {
160 static bits_t
fixed_to_bits(ale_fixed f
) {
162 if (f
.bits
>= 1 << N
)
163 return ((1 << N
) - 1);
176 ale_fixed(const ale_fixed
&f
) {
180 ale_fixed
& operator=(const ale_fixed
&f
) {
190 static void disable_casting() {
191 casting_disabled
= 1;
198 static void enable_casting() {
199 casting_disabled
= 0;
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
) {
223 double nan
= zero
/ zero
;
226 } else if (bits
== ALE_FIXED_NEGINF
) {
229 double neginf
= negone
/ zero
;
230 assert (isinf(neginf
));
233 } else if (bits
== ALE_FIXED_POSINF
) {
236 double posinf
= posone
/ zero
;
237 assert (isinf(posinf
));
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
) {
255 float nan
= zero
/ zero
;
258 } else if (bits
== ALE_FIXED_NEGINF
) {
261 float neginf
= negone
/ zero
;
262 assert (isinf(neginf
));
265 } else if (bits
== ALE_FIXED_POSINF
) {
268 float posinf
= posone
/ zero
;
269 assert (isinf(posinf
));
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
);
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
);
304 return (unsigned int) operator int();
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();
317 if (bits
== ALE_FIXED_POSINF
) {
318 result
.bits
= fixed_type_2::posinf();
322 if (bits
== ALE_FIXED_NEGINF
) {
323 result
.bits
= fixed_type_2::neginf();
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
;
333 type_result
= bits
<< (bits_t_calc
) ((int) M
- (int) N
);
335 type_result
= bits
/ ((bits_t_calc
) 1 << (bits_t_calc
) ((int) N
- (int) M
));
337 result
.bits
= type_result
;
340 typedef bits_t bits_t_calc
;
342 bits_t_calc type_result
;
345 type_result
= bits
<< (bits_t_calc
) ((int) M
- (int) N
);
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();
354 result
.bits
= type_result
;
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.
374 if (d
.bits
== fixed_type_2::nan()) {
375 bits
= ALE_FIXED_NAN
;
379 if (bits
== fixed_type_2::posinf()) {
380 bits
= ALE_FIXED_POSINF
;
384 if (bits
== fixed_type_2::neginf()) {
385 bits
= ALE_FIXED_NEGINF
;
389 if (sizeof(ale_fixed
<fixed_type
,N
>) > sizeof(ale_fixed
<fixed_type_2
,M
>)) {
391 bits
= d
.bits
<< (bits_t
) ((int) N
- (int) M
);
393 bits
= d
.bits
/ ((bits_t
) 1 << (bits_t
) ((int) M
- (int) N
));
395 typedef typename ale_fixed
<fixed_type_2
,M
>::bits_t bits_t_calc
;
397 bits_t_calc type_result
;
400 type_result
= d
.bits
<< (bits_t_calc
) ((int) N
- (int) M
);
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
;
413 ale_fixed(double d
) {
414 #if DEBUG_FIXED_POINT
416 * Removed due to a tendency to trigger unpredictably.
418 assert(!casting_disabled
);
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
;
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
);
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
);
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
);
472 ale_fixed
operator-() const {
476 if (bits
== ALE_FIXED_NAN
|| bits
== 0)
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
;
488 ale_fixed
unexceptional_negation() const {
496 ale_fixed
operator+(ale_fixed f
) const {
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
;
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
;
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
;
532 result
.bits
= bits_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 {
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
;
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
;
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
;
581 result
.bits
= bits_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 {
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
;
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
) {
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
;
632 result
.bits
= mul_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 {
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
))
663 result
.bits
= ALE_FIXED_NAN
;
665 } else if (f
.bits
== 0 && bits
> 0) {
666 result
.bits
= ALE_FIXED_POSINF
;
668 } else if (f
.bits
== 0 && bits
< 0) {
669 result
.bits
= ALE_FIXED_NEGINF
;
673 #if DEBUG_FIXED_POINT
675 * Removed for performance reasons.
678 else if (f
.bits
== ALE_FIXED_POSINF
|| f
.bits
== ALE_FIXED_NEGINF
) {
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
;
694 } else if (div_result
< (mulbits_t
) ALE_FIXED_NEGINF
) {
695 result
.bits
= ALE_FIXED_NEGINF
;
700 result
.bits
= (bits_t
) div_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
) {
717 ale_fixed
&operator-=(ale_fixed f
) {
722 ale_fixed
&operator*=(ale_fixed f
) {
727 ale_fixed
&operator/=(ale_fixed f
) {
732 int operator!=(ale_fixed f
) const {
733 if (bits
== ALE_FIXED_NAN
|| f
.bits
== ALE_FIXED_NAN
)
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
)
756 int operator>=(ale_fixed f
) const {
757 if (bits
== ALE_FIXED_NAN
|| f
.bits
== ALE_FIXED_NAN
)
766 int operator>(ale_fixed f
) const {
767 if (bits
== ALE_FIXED_NAN
|| f
.bits
== ALE_FIXED_NAN
)
776 int operator<(ale_fixed f
) const {
777 if (bits
== ALE_FIXED_NAN
|| f
.bits
== ALE_FIXED_NAN
)
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
>())
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
++) {
924 mulbits_t sf
= (mulbits_t
) f
.bits
<< (N
- 2);
925 guess
.bits
= guess
.bits
+ sf
/ guess
.bits
;
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
) {
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
) {
954 return ale_fixed
<fixed_type
, N
>(1);
957 return pow(f
, d
/ 2) * pow(f
, d
- d
/ 2);
960 return 1 / pow(f
, -d
);
965 template<class fixed_type
, unsigned int N
>
966 ale_fixed
<fixed_type
, N
> pow(ale_fixed
<fixed_type
, N
> f
, unsigned int d
) {
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.
988 || f
.bits
== ALE_FIXED_POSINF
989 || f
.bits
== ALE_FIXED_NEGINF
990 || f
.bits
== ALE_FIXED_NAN
)
994 ale_fixed
<fixed_type
, N
> result
;
996 result
.bits
= (f
.bits
& ~((1 << N
) - 1));
999 * XXX: This isn't exactly right.
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.
1016 || f
.bits
== ALE_FIXED_POSINF
1017 || f
.bits
== ALE_FIXED_NEGINF
1018 || f
.bits
== ALE_FIXED_NAN
)
1022 ale_fixed
<fixed_type
, N
> result
= floor(f
);
1024 if (f
.bits
- result
.bits
>= (1 << N
- 1))
1025 result
.bits
+= (1 << N
);
1030 template<class fixed_type
, unsigned int N
>
1031 ale_fixed
<fixed_type
, N
> ceil(ale_fixed
<fixed_type
, N
> 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.
1061 ale_fixed
<fixed_type
, N
> n
;
1063 n
.bits
= m
.bits
<< (N
- M
);
1068 template<class fixed_type
, unsigned int N
>
1069 int ale_fixed
<fixed_type
, N
>::casting_disabled
= 0;