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 class ale_fixed_16_accum
{
78 typedef long long mulbits_t
;
79 static bits_t
posinf() {
82 static bits_t
neginf() {
88 static bits_t
rint(double d
) {
89 return (bits_t
) lrint(d
);
93 #if ALE_COLORS == FIXED32 || ALE_COORDINATES == FIXED32
97 typedef long long mulbits_t
;
98 static bits_t
posinf() {
101 static bits_t
neginf() {
104 static bits_t
nan() {
107 static bits_t
rint(double d
) {
108 return (bits_t
) lrint(d
);
113 #if ALE_COLORS == FIXED32
114 class ale_fixed_32_accum
{
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
);
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
>
139 static int casting_disabled
;
143 typedef typename
fixed_type::bits_t bits_t
;
144 typedef typename
fixed_type::mulbits_t mulbits_t
;
155 ale_fixed(const ale_fixed
&f
) {
159 ale_fixed
& operator=(const ale_fixed
&f
) {
169 static void disable_casting() {
170 casting_disabled
= 1;
177 static void enable_casting() {
178 casting_disabled
= 0;
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
) {
202 double nan
= zero
/ zero
;
205 } else if (bits
== ALE_FIXED_NEGINF
) {
208 double neginf
= negone
/ zero
;
209 assert (isinf(neginf
));
212 } else if (bits
== ALE_FIXED_POSINF
) {
215 double posinf
= posone
/ zero
;
216 assert (isinf(posinf
));
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
) {
234 float nan
= zero
/ zero
;
237 } else if (bits
== ALE_FIXED_NEGINF
) {
240 float neginf
= negone
/ zero
;
241 assert (isinf(neginf
));
244 } else if (bits
== ALE_FIXED_POSINF
) {
247 float posinf
= posone
/ zero
;
248 assert (isinf(posinf
));
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
);
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
);
283 return (unsigned int) operator int();
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();
296 if (bits
== ALE_FIXED_POSINF
) {
297 result
.bits
= fixed_type_2::posinf();
301 if (bits
== ALE_FIXED_NEGINF
) {
302 result
.bits
= fixed_type_2::neginf();
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
;
312 type_result
= bits
<< (bits_t_calc
) ((int) M
- (int) N
);
314 type_result
= bits
/ ((bits_t_calc
) 1 << (bits_t_calc
) ((int) N
- (int) M
));
316 result
.bits
= type_result
;
319 typedef bits_t bits_t_calc
;
321 bits_t_calc type_result
;
324 type_result
= bits
<< (bits_t_calc
) ((int) M
- (int) N
);
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();
333 result
.bits
= type_result
;
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.
353 if (d
.bits
== fixed_type_2::nan()) {
354 bits
= ALE_FIXED_NAN
;
358 if (bits
== fixed_type_2::posinf()) {
359 bits
= ALE_FIXED_POSINF
;
363 if (bits
== fixed_type_2::neginf()) {
364 bits
= ALE_FIXED_NEGINF
;
368 if (sizeof(ale_fixed
<fixed_type
,N
>) > sizeof(ale_fixed
<fixed_type_2
,M
>)) {
370 bits
= d
.bits
<< (bits_t
) ((int) N
- (int) M
);
372 bits
= d
.bits
/ ((bits_t
) 1 << (bits_t
) ((int) M
- (int) N
));
374 typedef typename ale_fixed
<fixed_type_2
,M
>::bits_t bits_t_calc
;
376 bits_t_calc type_result
;
379 type_result
= d
.bits
<< (bits_t_calc
) ((int) N
- (int) M
);
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
;
392 ale_fixed(double d
) {
393 assert(!casting_disabled
);
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
;
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
);
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
);
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
);
446 ale_fixed
operator-() const {
450 if (bits
== ALE_FIXED_NAN
|| bits
== 0)
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
;
462 ale_fixed
operator+(ale_fixed f
) const {
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
;
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
;
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
;
498 result
.bits
= bits_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 {
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
;
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
;
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
;
547 result
.bits
= bits_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 {
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
;
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
) {
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
;
598 result
.bits
= mul_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 {
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
))
629 result
.bits
= ALE_FIXED_NAN
;
631 } else if (f
.bits
== 0 && bits
> 0) {
632 result
.bits
= ALE_FIXED_POSINF
;
634 } else if (f
.bits
== 0 && bits
< 0) {
635 result
.bits
= ALE_FIXED_NEGINF
;
639 #if DEBUG_FIXED_POINT
641 * Removed for performance reasons.
644 else if (f
.bits
== ALE_FIXED_POSINF
|| f
.bits
== ALE_FIXED_NEGINF
) {
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
;
660 } else if (div_result
< (mulbits_t
) ALE_FIXED_NEGINF
) {
661 result
.bits
= ALE_FIXED_NEGINF
;
666 result
.bits
= (bits_t
) div_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
) {
683 ale_fixed
&operator-=(ale_fixed f
) {
688 ale_fixed
&operator*=(ale_fixed f
) {
693 ale_fixed
&operator/=(ale_fixed f
) {
698 int operator!=(ale_fixed f
) const {
699 if (bits
== ALE_FIXED_NAN
|| f
.bits
== ALE_FIXED_NAN
)
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
)
722 int operator>=(ale_fixed f
) const {
723 if (bits
== ALE_FIXED_NAN
|| f
.bits
== ALE_FIXED_NAN
)
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 if (bits
== ALE_FIXED_NAN
|| f
.bits
== ALE_FIXED_NAN
)
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
>())
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
++) {
888 long long sf
= (long long) f
.bits
<< (N
- 2);
889 guess
.bits
= guess
.bits
+ sf
/ guess
.bits
;
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
) {
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
) {
918 return ale_fixed
<fixed_type
, N
>(1);
921 return pow(f
, d
/ 2) * pow(f
, d
- d
/ 2);
924 return 1 / pow(f
, -d
);
929 template<class fixed_type
, unsigned int N
>
930 ale_fixed
<fixed_type
, N
> pow(ale_fixed
<fixed_type
, N
> f
, unsigned int d
) {
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.
952 || f
.bits
== ALE_FIXED_POSINF
953 || f
.bits
== ALE_FIXED_NEGINF
954 || f
.bits
== ALE_FIXED_NAN
)
958 ale_fixed
<fixed_type
, N
> result
;
960 result
.bits
= (f
.bits
& ~((1 << N
) - 1));
963 * XXX: This isn't exactly right.
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.
980 || f
.bits
== ALE_FIXED_POSINF
981 || f
.bits
== ALE_FIXED_NEGINF
982 || f
.bits
== ALE_FIXED_NAN
)
986 ale_fixed
<fixed_type
, N
> result
= floor(f
);
988 if (f
.bits
- result
.bits
>= (1 << N
- 1))
989 result
.bits
+= (1 << N
);
994 template<class fixed_type
, unsigned int N
>
995 ale_fixed
<fixed_type
, N
> ceil(ale_fixed
<fixed_type
, N
> 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.
1025 ale_fixed
<fixed_type
, N
> n
;
1027 n
.bits
= m
.bits
<< (N
- M
);
1032 template<class fixed_type
, unsigned int N
>
1033 int ale_fixed
<fixed_type
, N
>::casting_disabled
= 0;