36 #ifndef VIGRA_FIXEDPOINT_HXX 
   37 #define VIGRA_FIXEDPOINT_HXX 
   39 #include "mathutil.hxx" 
   40 #include "static_assert.hxx" 
   42 #include "numerictraits.hxx" 
   46 template <
unsigned IntBits, 
unsigned FractionalBits>
 
   49 struct Error_FixedPointTraits_not_specialized_for_this_case;
 
   51 template <
class T1, 
class T2>
 
   52 class FixedPointTraits
 
   55     typedef Error_FixedPointTraits_not_specialized_for_this_case PlusType;
 
   56     typedef Error_FixedPointTraits_not_specialized_for_this_case MinusType;
 
   57     typedef Error_FixedPointTraits_not_specialized_for_this_case MultipliesType;
 
   65 template <
unsigned IntBits1, 
unsigned FracBits1, 
unsigned IntBits2, 
unsigned FracBits2>
 
   68     enum { MaxIntBits  = (IntBits1 < IntBits2) ? IntBits2 : IntBits1,
 
   69            MaxFracBits = (FracBits1 < FracBits2) ? FracBits2 : FracBits1,
 
   70            PlusMinusIntBits = (MaxIntBits + 1 + MaxFracBits < 32) ?
 
   71                                MaxIntBits + 1 : MaxIntBits,
 
   72            MultipliesFracBits = (IntBits1 + IntBits2 < 31) 
 
   73                                     ? (FracBits1 + FracBits2) > (31 - IntBits1 - IntBits2) 
 
   74                                             ? 31 - IntBits1 - IntBits2
 
   75                                             : FracBits1 + FracBits2
 
   79     typedef FixedPoint<PlusMinusIntBits, MaxFracBits>               PlusType;
 
   80     typedef FixedPoint<PlusMinusIntBits, MaxFracBits>               MinusType;
 
   81     typedef FixedPoint<IntBits1 + IntBits2, MultipliesFracBits>  MultipliesType;
 
   85 template <
unsigned IntBits, 
unsigned FracBits>
 
   86 struct SquareRootTraits<FixedPoint<IntBits, FracBits> >
 
   88     enum { SRTotalBits = (IntBits + FracBits + 1) / 2,
 
   89            SRIntBits   = (IntBits + 1) / 2,
 
   90            SRFracBits  = SRTotalBits - SRIntBits
 
   93     typedef FixedPoint<IntBits, FracBits>      Type;
 
   94     typedef FixedPoint<SRIntBits, SRFracBits>  SquareRootResult;
 
   95     typedef Type                               SquareRootArgument;
 
  102 struct FixedPoint_overflow_error__More_than_31_bits_requested
 
  103 : staticAssert::AssertBool<(N < 32)>
 
  110 template <bool Predicate>
 
  111 struct FixedPoint_assignment_error__Target_object_has_too_few_integer_bits
 
  112 : staticAssert::AssertBool<Predicate>
 
  115 enum FixedPointNoShift { FPNoShift };
 
  119 template <bool MustRound>
 
  120 struct FPAssignWithRound;
 
  123 struct FPAssignWithRound<false>
 
  126     static inline int exec(int v) { return v << (-N); }
 
  130 struct FPAssignWithRound<true>
 
  133     static inline int exec(int const v)
 
  135         return (v + (1 << (N - 1))) >> (N);
 
  139 template <bool MustRound>
 
  140 struct FPMulImplementation;
 
  143 struct FPMulImplementation<false>
 
  146     static inline int exec(int l, int r) { return (l * r) << (-N); }
 
  150 struct FPMulImplementation<true>
 
  153     static inline int exec(int l, int r)
 
  157         enum { diffl = N / 2, diffr = N  - diffl, maskl = (1 << diffl) - 1, maskr = (1 << diffr) - 1 };
 
  158         int shiftl = l >> diffl;
 
  159         int shiftr = r >> diffr;
 
  161         return shiftl * shiftr + (((l & maskl) * shiftr) >> diffl) +
 
  162                                  (((r & maskr) * shiftl) >> diffr);
 
  216 template <unsigned IntBits, unsigned FractionalBits>
 
  222         FRACTIONAL_BITS = FractionalBits,
 
  223         TOTAL_BITS      = IntBits + FractionalBits,
 
  224         MAX             = (int)(((unsigned)1 << TOTAL_BITS) - 1),
 
  225         ONE             = 1 << FractionalBits,
 
  227         FRACTIONAL_MASK = ONE - 1,
 
  228         INT_MASK        = MAX ^ FRACTIONAL_MASK
 
  235         VIGRA_STATIC_ASSERT((FixedPoint_overflow_error__More_than_31_bits_requested<(IntBits + FractionalBits)>));
 
  240     explicit FixedPoint(int v)
 
  241     : value(v << FractionalBits)
 
  243         VIGRA_STATIC_ASSERT((FixedPoint_overflow_error__More_than_31_bits_requested<(IntBits + FractionalBits)>));
 
  248     FixedPoint(int v, FixedPointNoShift)
 
  251         VIGRA_STATIC_ASSERT((FixedPoint_overflow_error__More_than_31_bits_requested<(IntBits + FractionalBits)>));
 
  258     explicit FixedPoint(double rhs)
 
  259     : value((int)round(rhs * ONE))
 
  261         VIGRA_STATIC_ASSERT((FixedPoint_overflow_error__More_than_31_bits_requested<(IntBits + FractionalBits)>));
 
  262         vigra_precondition(abs(rhs * ONE) <= (double)MAX,
 
  263             "FixedPoint(double rhs): Too few integer bits to convert rhs.");
 
  268     FixedPoint(const FixedPoint &other)
 
  275     template <unsigned Int2, unsigned Frac2>
 
  276     FixedPoint(const FixedPoint<Int2, Frac2> &other)
 
  277     : value(detail::FPAssignWithRound<(Frac2 > FractionalBits)>::template exec<int(Frac2) - int(FractionalBits)>(other.value))
 
  279         VIGRA_STATIC_ASSERT((FixedPoint_overflow_error__More_than_31_bits_requested<(IntBits + FractionalBits)>));
 
  280         VIGRA_STATIC_ASSERT((FixedPoint_assignment_error__Target_object_has_too_few_integer_bits<(IntBits >= Int2)>));
 
  287     FixedPoint &operator=(int rhs)
 
  289         vigra_precondition(abs(rhs) < (1 << IntBits),
 
  290             "FixedPoint::operator=(int rhs): Too few integer bits to represent rhs.");
 
  291         value = rhs << FractionalBits;
 
  299     FixedPoint &operator=(double rhs)
 
  301         vigra_precondition(abs(rhs) <= ((1 << IntBits) - 1),
 
  302             "FixedPoint::operator=(double rhs): Too few integer bits to convert rhs.");
 
  303         value = (int)round(rhs * ONE);
 
  309     FixedPoint & operator=(const FixedPoint &other)
 
  318     template <unsigned Int2, unsigned Frac2>
 
  319     FixedPoint & operator=(const FixedPoint<Int2, Frac2> &other)
 
  321         VIGRA_STATIC_ASSERT((FixedPoint_assignment_error__Target_object_has_too_few_integer_bits<(IntBits >= Int2)>));
 
  322         value = detail::FPAssignWithRound<(Frac2 > FractionalBits)>::template exec<int(Frac2) - int(FractionalBits)>(other.value);
 
  328     FixedPoint operator-() const
 
  330         return FixedPoint(-value, FPNoShift);
 
  335     FixedPoint & operator++()
 
  343     FixedPoint operator++(int)
 
  345         FixedPoint old(*this);
 
  352     FixedPoint & operator--()
 
  360     FixedPoint operator--(int)
 
  362         FixedPoint old(*this);
 
  370     template <unsigned Int2, unsigned Frac2>
 
  371     FixedPoint & operator+=(const FixedPoint<Int2, Frac2> &other)
 
  373         VIGRA_STATIC_ASSERT((FixedPoint_assignment_error__Target_object_has_too_few_integer_bits<(IntBits >= Int2)>));
 
  374         value += detail::FPAssignWithRound<(Frac2 > FractionalBits)>::template exec<Frac2 - FractionalBits>(other.value);
 
  381     template <unsigned Int2, unsigned Frac2>
 
  382     FixedPoint & operator-=(const FixedPoint<Int2, Frac2> &other)
 
  384         VIGRA_STATIC_ASSERT((FixedPoint_assignment_error__Target_object_has_too_few_integer_bits<(IntBits >= Int2)>));
 
  385         value -= detail::FPAssignWithRound<(Frac2 > FractionalBits)>::template exec<Frac2 - FractionalBits>(other.value);
 
  392     template <unsigned Int2, unsigned Frac2>
 
  393     FixedPoint & operator*=(const FixedPoint<Int2, Frac2> &other)
 
  395         VIGRA_STATIC_ASSERT((FixedPoint_assignment_error__Target_object_has_too_few_integer_bits<(IntBits >= Int2)>));
 
  396         value = detail::FPMulImplementation<(Frac2 > 0)>::template exec<Frac2>(value, other.value);
 
  401 #define VIGRA_FIXED_POINT_FACTORY(T, INTBITS) \
 
  402     inline FixedPoint<INTBITS, 0> fixedPoint(T t) \
 
  404         return FixedPoint<INTBITS, 0>(t, FPNoShift); \
 
  407 VIGRA_FIXED_POINT_FACTORY(unsigned char, 8)
 
  408 VIGRA_FIXED_POINT_FACTORY(signed char, 7)
 
  409 VIGRA_FIXED_POINT_FACTORY(unsigned short, 16)
 
  410 VIGRA_FIXED_POINT_FACTORY(signed short, 15)
 
  411 VIGRA_FIXED_POINT_FACTORY(int, 31)
 
  413 #undef VIGRA_FIXED_POINT_FACTORY
 
  416 struct FixedPointCast;
 
  418 #define VIGRA_FIXED_POINT_CAST(type) \
 
  420 struct FixedPointCast<type> \
 
  422     template <unsigned IntBits, unsigned FracBits> \
 
  423     static type cast(FixedPoint<IntBits, FracBits> v) \
 
  429 VIGRA_FIXED_POINT_CAST(Int8)
 
  430 VIGRA_FIXED_POINT_CAST(UInt8)
 
  431 VIGRA_FIXED_POINT_CAST(Int16)
 
  432 VIGRA_FIXED_POINT_CAST(UInt16)
 
  433 VIGRA_FIXED_POINT_CAST(Int32)
 
  434 VIGRA_FIXED_POINT_CAST(UInt32)
 
  436 #undef VIGRA_FIXED_POINT_CAST
 
  439 struct FixedPointCast<float>
 
  441     template <unsigned IntBits, unsigned FracBits>
 
  442     static float cast(FixedPoint<IntBits, FracBits> v)
 
  444         return (float)v.value / FixedPoint<IntBits, FracBits>::ONE;
 
  449 struct FixedPointCast<double>
 
  451     template <unsigned IntBits, unsigned FracBits>
 
  452     static double cast(FixedPoint<IntBits, FracBits> v)
 
  454         return (double)v.value / FixedPoint<IntBits, FracBits>::ONE;
 
  485 template <class TARGET, unsigned IntBits, unsigned FracBits>
 
  486 TARGET fixed_point_cast(FixedPoint<IntBits, FracBits> v)
 
  488     return FixedPointCast<TARGET>::cast(v);
 
  492 template <unsigned IntBits1, unsigned FracBits1, unsigned IntBits2, unsigned FracBits2>
 
  494 bool operator==(FixedPoint<IntBits1, FracBits1> l, FixedPoint<IntBits2, FracBits2> r)
 
  496     enum { MaxFracBits = (FracBits1 < FracBits2) ? FracBits2 : FracBits1 };
 
  497     return (l.value << (MaxFracBits - FracBits1)) == (r.value << (MaxFracBits - FracBits2));
 
  501 template <unsigned IntBits1, unsigned FracBits1, unsigned IntBits2, unsigned FracBits2>
 
  503 bool operator!=(FixedPoint<IntBits1, FracBits1> l, FixedPoint<IntBits2, FracBits2> r)
 
  505     enum { MaxFracBits = (FracBits1 < FracBits2) ? FracBits2 : FracBits1 };
 
  506     return (l.value << (MaxFracBits - FracBits1)) != (r.value << (MaxFracBits - FracBits2));
 
  510 template <unsigned IntBits1, unsigned FracBits1, unsigned IntBits2, unsigned FracBits2>
 
  512 bool operator<(FixedPoint<IntBits1, FracBits1> l, FixedPoint<IntBits2, FracBits2> r)
 
  514     enum { MaxFracBits = (FracBits1 < FracBits2) ? FracBits2 : FracBits1 };
 
  515     return (l.value << (MaxFracBits - FracBits1)) < (r.value << (MaxFracBits - FracBits2));
 
  519 template <unsigned IntBits1, unsigned FracBits1, unsigned IntBits2, unsigned FracBits2>
 
  521 bool operator<=(FixedPoint<IntBits1, FracBits1> l, FixedPoint<IntBits2, FracBits2> r)
 
  523     enum { MaxFracBits = (FracBits1 < FracBits2) ? FracBits2 : FracBits1 };
 
  524     return (l.value << (MaxFracBits - FracBits1)) <= (r.value << (MaxFracBits - FracBits2));
 
  528 template <unsigned IntBits1, unsigned FracBits1, unsigned IntBits2, unsigned FracBits2>
 
  530 bool operator>(FixedPoint<IntBits1, FracBits1> l, FixedPoint<IntBits2, FracBits2> r)
 
  532     enum { MaxFracBits = (FracBits1 < FracBits2) ? FracBits2 : FracBits1 };
 
  533     return (l.value << (MaxFracBits - FracBits1)) > (r.value << (MaxFracBits - FracBits2));
 
  537 template <unsigned IntBits1, unsigned FracBits1, unsigned IntBits2, unsigned FracBits2>
 
  539 bool operator>=(FixedPoint<IntBits1, FracBits1> l, FixedPoint<IntBits2, FracBits2> r)
 
  541     enum { MaxFracBits = (FracBits1 < FracBits2) ? FracBits2 : FracBits1 };
 
  542     return (l.value << (MaxFracBits - FracBits1)) >= (r.value << (MaxFracBits - FracBits2));
 
  546 template <unsigned IntBits1, unsigned FracBits1, unsigned IntBits2, unsigned FracBits2>
 
  548 typename FixedPointTraits<FixedPoint<IntBits1, FracBits1>, FixedPoint<IntBits2, FracBits2> >::PlusType
 
  549 operator+(FixedPoint<IntBits1, FracBits1> l, FixedPoint<IntBits2, FracBits2> r)
 
  551     enum { MaxFracBits = (FracBits1 < FracBits2) ? FracBits2 : FracBits1 };
 
  553         FixedPointTraits<FixedPoint<IntBits1, FracBits1>, FixedPoint<IntBits2, FracBits2> >::
 
  554         PlusType((l.value << (MaxFracBits - FracBits1)) + (r.value << (MaxFracBits - FracBits2)), FPNoShift);
 
  558 template <unsigned IntBits1, unsigned FracBits1, unsigned IntBits2, unsigned FracBits2,
 
  559           unsigned IntBits3, unsigned FracBits3>
 
  561 add(FixedPoint<IntBits1, FracBits1> l, FixedPoint<IntBits2, FracBits2> r,
 
  562     FixedPoint<IntBits3, FracBits3> & result)
 
  568 template <unsigned IntBits1, unsigned FracBits1, unsigned IntBits2, unsigned FracBits2>
 
  570 typename FixedPointTraits<FixedPoint<IntBits1, FracBits1>, FixedPoint<IntBits2, FracBits2> >::MinusType
 
  571 operator-(FixedPoint<IntBits1, FracBits1> l, FixedPoint<IntBits2, FracBits2> r)
 
  573     enum { MaxFracBits = (FracBits1 < FracBits2) ? FracBits2 : FracBits1 };
 
  575         FixedPointTraits<FixedPoint<IntBits1, FracBits1>, FixedPoint<IntBits2, FracBits2> >::
 
  576         MinusType((l.value << (MaxFracBits - FracBits1)) - (r.value << (MaxFracBits - FracBits2)), FPNoShift);
 
  580 template <unsigned IntBits1, unsigned FracBits1, unsigned IntBits2, unsigned FracBits2,
 
  581           unsigned IntBits3, unsigned FracBits3>
 
  583 sub(FixedPoint<IntBits1, FracBits1> l, FixedPoint<IntBits2, FracBits2> r,
 
  584     FixedPoint<IntBits3, FracBits3> & result)
 
  590 template <unsigned IntBits1, unsigned FracBits1, unsigned IntBits2, unsigned FracBits2>
 
  592 typename FixedPointTraits<FixedPoint<IntBits1, FracBits1>, FixedPoint<IntBits2, FracBits2> >::MultipliesType
 
  593 operator*(FixedPoint<IntBits1, FracBits1> l, FixedPoint<IntBits2, FracBits2> r)
 
  595     typename FixedPointTraits<FixedPoint<IntBits1, FracBits1>, FixedPoint<IntBits2, FracBits2> >::
 
  602 template <unsigned IntBits1, unsigned FracBits1, unsigned IntBits2, unsigned FracBits2,
 
  603           unsigned IntBits3, unsigned FracBits3>
 
  605 mul(FixedPoint<IntBits1, FracBits1> l, FixedPoint<IntBits2, FracBits2> r,
 
  606     FixedPoint<IntBits3, FracBits3> & result)
 
  608     VIGRA_STATIC_ASSERT((FixedPoint_assignment_error__Target_object_has_too_few_integer_bits<(IntBits1 + IntBits2 <= IntBits3)>));
 
  609     enum { diff = FracBits1 + FracBits2 - FracBits3 };
 
  610     result.value = detail::FPMulImplementation<(diff > 0)>::template exec<diff>(l.value, r.value);
 
  614 template <unsigned IntBits, unsigned FracBits>
 
  615 inline typename SquareRootTraits<FixedPoint<IntBits, FracBits> >::SquareRootResult
 
  616 sqrt(FixedPoint<IntBits, FracBits> v)
 
  618     return typename SquareRootTraits<FixedPoint<IntBits, FracBits> >::SquareRootResult(sqrti(v.value), FPNoShift);
 
  622 template <unsigned IntBits, unsigned FracBits>
 
  623 inline FixedPoint<IntBits, FracBits>
 
  624 abs(FixedPoint<IntBits, FracBits> v)
 
  626     return FixedPoint<IntBits, FracBits>(abs(v.value), FPNoShift);
 
  630 template <unsigned IntBits, unsigned FracBits>
 
  632 typename FixedPointTraits<FixedPoint<IntBits, FracBits>, FixedPoint<IntBits, FracBits> >::MultipliesType
 
  633 squaredNorm(FixedPoint<IntBits, FracBits> v)
 
  639 template <unsigned IntBits, unsigned FracBits>
 
  641 FixedPoint<IntBits, FracBits>
 
  642 norm(FixedPoint<IntBits, FracBits> const & v)
 
  648 template <unsigned IntBits, unsigned FracBits>
 
  649 inline FixedPoint<0, FracBits>
 
  650 frac(FixedPoint<IntBits, FracBits> v)
 
  652     return FixedPoint<0, FracBits>(v.value & FixedPoint<IntBits, FracBits>::FRACTIONAL_MASK, FPNoShift);
 
  656 template <unsigned IntBits, unsigned FracBits>
 
  657 inline FixedPoint<0, FracBits>
 
  658 dual_frac(FixedPoint<IntBits, FracBits> v)
 
  660     return FixedPoint<0, FracBits>(FixedPoint<0, FracBits>::ONE - 
 
  661                                    (v.value & FixedPoint<IntBits, FracBits>::FRACTIONAL_MASK), FPNoShift);
 
  665 template <unsigned IntBits, unsigned FracBits>
 
  667 floor(FixedPoint<IntBits, FracBits> v)
 
  669     return(v.value >> FracBits);
 
  673 template <unsigned IntBits, unsigned FracBits>
 
  675 ceil(FixedPoint<IntBits, FracBits> v)
 
  677     return((v.value + FixedPoint<IntBits, FracBits>::FRACTIONAL_MASK) >> FracBits);
 
  681 template <unsigned IntBits, unsigned FracBits>
 
  683 round(FixedPoint<IntBits, FracBits> v)
 
  685     return((v.value + FixedPoint<IntBits, FracBits>::ONE_HALF) >> FracBits);
 
  763 template <unsigned IntBits, unsigned FracBits>
 
  764 struct NumericTraits<FixedPoint<IntBits, FracBits> >
 
  766     typedef FixedPoint<IntBits, FracBits> Type;
 
  770     typedef Type ValueType;
 
  772     typedef VigraFalseType isIntegral;
 
  773     typedef VigraTrueType  isScalar;
 
  774     typedef VigraTrueType  isSigned;
 
  775     typedef VigraTrueType  isOrdered;
 
  776     typedef VigraFalseType isComplex;
 
  778     static Type zero() { return Type(0, FPNoShift); }
 
  779     static Type one() { return Type(Type::ONE, FPNoShift); }
 
  780     static Type nonZero() { return one(); }
 
  781     static Type epsilon() { return Type(1, FPNoShift); }
 
  782     static Type smallestPositive() { return Type(1, FPNoShift); }
 
  783     static Type max() { return Type( Type::MAX, FPNoShift); }
 
  784     static Type min() { return -max(); }
 
  787 template <unsigned IntBits, unsigned FracBits>
 
  788 struct NormTraits<FixedPoint<IntBits, FracBits> >
 
  790     typedef FixedPoint<IntBits, FracBits>         Type;
 
  792         FixedPointTraits<FixedPoint<IntBits, FracBits>, FixedPoint<IntBits, FracBits> >::MultipliesType
 
  794     typedef Type                                  NormType;
 
  797 template <unsigned IntBits1, unsigned FracBits1, unsigned IntBits2, unsigned FracBits2>
 
  798 struct PromoteTraits<FixedPoint<IntBits1, FracBits1>,
 
  799                      FixedPoint<IntBits2, FracBits2> >
 
  802         FixedPointTraits<FixedPoint<IntBits1, FracBits1>, FixedPoint<IntBits2, FracBits2> >::PlusType 
 
  808 enum FPOverflowHandling { FPOverflowIgnore, FPOverflowSaturate, FPOverflowError };
 
  810 template <int IntBits, FPOverflowHandling OverflowHandling = FPOverflowIgnore>
 
  874 template <int IntBits, FPOverflowHandling OverflowHandling>
 
  875 struct NumericTraits<FixedPoint16<IntBits, OverflowHandling> >
 
  877     typedef FixedPoint16<IntBits, OverflowHandling> Type;
 
  878     typedef Type                                    Promote;
 
  881     typedef Type ValueType;
 
  883     typedef VigraFalseType isIntegral;
 
  884     typedef VigraTrueType  isScalar;
 
  885     typedef VigraTrueType  isSigned;
 
  886     typedef VigraTrueType  isOrdered;
 
  887     typedef VigraFalseType isComplex;
 
  889     static Type zero() { return Type(0, FPNoShift); }
 
  890     static Type one() { return Type(Type::ONE, FPNoShift); }
 
  891     static Type nonZero() { return one(); }
 
  892     static Type epsilon() { return Type(1, FPNoShift); }
 
  893     static Type smallestPositive() { return Type(1, FPNoShift); }
 
  894     static Type max() { return Type( Type::MAX, FPNoShift); }
 
  895     static Type min() { return Type( Type::MIN, FPNoShift); }
 
  897     static Promote toPromote(Type v) { return v; }
 
  898     static Type fromPromote(Promote v) { return v; }; 
 
  901 template <int IntBits1, FPOverflowHandling OverflowHandling, int IntBits2>
 
  902 struct PromoteTraits<FixedPoint16<IntBits1, OverflowHandling>,
 
  903                      FixedPoint16<IntBits2, OverflowHandling> >
 
  905     typedef FixedPoint16<MetaMax<IntBits1, IntBits2>::value, OverflowHandling> Promote;
 
  906     static Promote toPromote(FixedPoint16<IntBits1, OverflowHandling> v) { return Promote(v); }
 
  907     static Promote toPromote(FixedPoint16<IntBits2, OverflowHandling> v) { return Promote(v); }
 
  910 template <int IntBits, FPOverflowHandling OverflowHandling>
 
  911 struct PromoteTraits<FixedPoint16<IntBits, OverflowHandling>,
 
  912                      FixedPoint16<IntBits, OverflowHandling> >
 
  914     typedef FixedPoint16<IntBits, OverflowHandling> Promote;
 
  915     static Promote toPromote(FixedPoint16<IntBits, OverflowHandling> v) { return v; }
 
  918 template <int IntBits, FPOverflowHandling OverflowHandling>
 
  919 struct NormTraits<FixedPoint16<IntBits, OverflowHandling> >
 
  921     typedef FixedPoint16<IntBits, OverflowHandling>     Type;
 
  922     typedef typename PromoteTraits<Type, Type>::Promote SquaredNormType;
 
  923     typedef Type                                        NormType;
 
  926 template <int IntBits, FPOverflowHandling OverflowHandling>
 
  927 struct SquareRootTraits<FixedPoint16<IntBits, OverflowHandling> >
 
  929     typedef FixedPoint16<IntBits, OverflowHandling>            Type;
 
  930     typedef FixedPoint16<(IntBits + 1) / 2, OverflowHandling>  SquareRootResult;
 
  931     typedef Type                                               SquareRootArgument;
 
  936 template <bool Compatible>
 
  937 struct FixedPoint_error__Right_shift_operator_has_unsupported_semantics
 
  938 : staticAssert::AssertBool<Compatible>
 
  943 template <bool Predicate>
 
  944 struct FixedPoint16_assignment_error__Target_object_has_too_few_integer_bits
 
  945 : staticAssert::AssertBool<Predicate>
 
  950 template<int BeforeIntBits, int AfterIntBits, 
 
  952          bool RightShift = (AfterIntBits >= BeforeIntBits)>
 
  955 template<int BeforeIntBits>
 
  956 struct FP16Align<BeforeIntBits, BeforeIntBits, true, true>
 
  958     static inline Int32 exec(Int32 v)
 
  964 template<int BeforeIntBits>
 
  965 struct FP16Align<BeforeIntBits, BeforeIntBits, false, true>
 
  967     static inline Int32 exec(Int32 v)
 
  973 template<int BeforeIntBits, int AfterIntBits>
 
  974 struct FP16Align<BeforeIntBits, AfterIntBits, false, true>
 
  976     static inline Int32 exec(Int32 v)
 
  978         VIGRA_STATIC_ASSERT((FixedPoint_error__Right_shift_operator_has_unsupported_semantics<((-1 >> 8) == -1)>));
 
  979         return v >> (AfterIntBits - BeforeIntBits);
 
  983 template<int BeforeIntBits, int AfterIntBits>
 
  984 struct FP16Align<BeforeIntBits, AfterIntBits, true, true>
 
  986     enum { ONE_HALF = 1 << (AfterIntBits - BeforeIntBits - 1) };
 
  987     static inline Int32 exec(Int32 v)
 
  989         VIGRA_STATIC_ASSERT((FixedPoint_error__Right_shift_operator_has_unsupported_semantics<((-1 >> 8) == -1)>));
 
  990         return (v + ONE_HALF) >> (AfterIntBits - BeforeIntBits);
 
  994 template<int BeforeIntBits, int AfterIntBits, bool Round>
 
  995 struct FP16Align<BeforeIntBits, AfterIntBits, Round, false>
 
  997     static inline Int32 exec(Int32 v)
 
  999         return v << (BeforeIntBits - AfterIntBits);
 
 1003 template <FPOverflowHandling OverflowHandling = FPOverflowIgnore>
 
 1004 struct FP16OverflowHandling
 
 1006     static inline Int32 exec(Int32 v)
 
 1011     static inline Int32 exec(UInt32 v)
 
 1018 struct FP16OverflowHandling<FPOverflowSaturate>
 
 1020     static inline Int32 exec(Int32 v)
 
 1023             return (1 << 15) - 1;
 
 1028     static inline Int32 exec(UInt32 v)
 
 1031             return (1 << 15) - 1;
 
 1037 struct FP16OverflowHandling<FPOverflowError>
 
 1039     static inline Int32 exec(Int32 v)
 
 1041         vigra_precondition(v < (1 << 15) && v >= -(1 << 15),
 
 1042              "FixedPoint16: Operation overflows.");
 
 1045     static inline Int32 exec(UInt32 v)
 
 1047         vigra_precondition(v < (1 << 15),
 
 1048              "FixedPoint16: Operation overflows.");
 
 1054 template <int IntBits1, int IntBits2, int IntBitsOut, 
 
 1055           FPOverflowHandling OverflowHandling >
 
 1058     enum { MinIntBits = MetaMin<IntBits1, IntBits2>::value };
 
 1059     static inline Int32 exec(Int32 t1, Int32 t2)
 
 1061        return FP16OverflowHandling<OverflowHandling>::exec(
 
 1062                   FP16Align<MinIntBits, IntBitsOut,  true>::exec(
 
 1063                       FP16Align<IntBits1, MinIntBits,  false>::exec(t1) + 
 
 1064                       FP16Align<IntBits2, MinIntBits,  false>::exec(t2)));
 
 1068 template <int IntBits1, int IntBits2, int IntBitsOut, 
 
 1069           FPOverflowHandling OverflowHandling >
 
 1072     enum { MinIntBits = MetaMin<IntBits1, IntBits2>::value };
 
 1073     static inline Int32 exec(Int32 t1, Int32 t2)
 
 1075        return FP16OverflowHandling<OverflowHandling>::exec(
 
 1076                   FP16Align<MinIntBits, IntBitsOut,  true>::exec(
 
 1077                       FP16Align<IntBits1, MinIntBits,  false>::exec(t1) - 
 
 1078                       FP16Align<IntBits2, MinIntBits,  false>::exec(t2)));
 
 1082 template <int IntBits1, int IntBits2, int IntBitsOut, 
 
 1083           FPOverflowHandling OverflowHandling >
 
 1086     static inline Int32 exec(Int32 t1, Int32 t2)
 
 1088         return FP16OverflowHandling<OverflowHandling>::exec(
 
 1089                    FP16Align<IntBits1+IntBits2, IntBitsOut+15,  true>::exec(t1*t2));
 
 1093 template <int IntBits1, int IntBits2, int IntBitsOut, 
 
 1094           FPOverflowHandling OverflowHandling >
 
 1097     static inline Int32 exec(Int32 t1, Int32 t2)
 
 1103         return FP16OverflowHandling<OverflowHandling>::exec(
 
 1104                    FP16Align<IntBits1-IntBits2, IntBitsOut+1,  true>::exec((t1<<16)/t2));
 
 1116 template <class TARGET, int IntBits, FPOverflowHandling OverflowHandling>
 
 1117 TARGET fixed_point_cast(FixedPoint16<IntBits, OverflowHandling> v);
 
 1173 template <int IntBits, FPOverflowHandling OverflowHandling>
 
 1177     static const Int32 TOTAL_BITS      = 15; 
 
 1178     static const Int32 INT_BITS        = IntBits;
 
 1179     static const Int32 FRACTIONAL_BITS = TOTAL_BITS - INT_BITS;
 
 1180     static const Int32 MAX             = (Int32)((1u << TOTAL_BITS) - 1);
 
 1181     static const Int32 MIN             = -(Int32)(1u << TOTAL_BITS);
 
 1182     static const Int32 ONE             = 1 << FRACTIONAL_BITS;
 
 1183     static const Int32 ONE_HALF        = ONE >> 1;
 
 1184     static const Int32 FRACTIONAL_MASK = (1u << FRACTIONAL_BITS) - 1;
 
 1185     static const Int32 INT_MASK        = 0xffffffffu ^ FRACTIONAL_MASK;
 
 1187     static const FixedPoint16 zero, pi, pi_2, mpi_2; 
 
 1194         VIGRA_STATIC_ASSERT((FixedPoint_error__Right_shift_operator_has_unsupported_semantics<((-1 >> 8) == -1)>));
 
 1200     explicit FixedPoint16(Int32 v)
 
 1201     : value(detail::FP16OverflowHandling<OverflowHandling>::exec(v << FRACTIONAL_BITS))
 
 1203         VIGRA_STATIC_ASSERT((FixedPoint_error__Right_shift_operator_has_unsupported_semantics<((-1 >> 8) == -1)>));
 
 1208     FixedPoint16(Int32 v, FixedPointNoShift)
 
 1209     : value(detail::FP16OverflowHandling<OverflowHandling>::exec(v))
 
 1211         VIGRA_STATIC_ASSERT((FixedPoint_error__Right_shift_operator_has_unsupported_semantics<((-1 >> 8) == -1)>));
 
 1218     explicit FixedPoint16(double rhs)
 
 1219     : value(detail::FP16OverflowHandling<OverflowHandling>::exec((Int32)roundi(rhs * ONE)))
 
 1221         VIGRA_STATIC_ASSERT((FixedPoint_error__Right_shift_operator_has_unsupported_semantics<((-1 >> 8) == -1)>));
 
 1226     FixedPoint16(const FixedPoint16 &other)
 
 1227     : value(other.value)
 
 1229         VIGRA_STATIC_ASSERT((FixedPoint_error__Right_shift_operator_has_unsupported_semantics<((-1 >> 8) == -1)>));
 
 1235     template <int IntBits2, FPOverflowHandling OverflowHandling2>
 
 1236     FixedPoint16(const FixedPoint16<IntBits2, OverflowHandling2> &other)
 
 1237     : value(detail::FP16OverflowHandling<OverflowHandling>::exec(
 
 1238             detail::FP16Align<IntBits2, IntBits, true>::exec(other.value)))
 
 1240         VIGRA_STATIC_ASSERT((FixedPoint_error__Right_shift_operator_has_unsupported_semantics<((-1 >> 8) == -1)>));
 
 1246     FixedPoint16 &operator=(Int32 rhs)
 
 1248         value = detail::FP16OverflowHandling<OverflowHandling>::exec(rhs << FRACTIONAL_BITS);
 
 1255     FixedPoint16 &operator=(double rhs)
 
 1257         value = detail::FP16OverflowHandling<OverflowHandling>::exec(roundi(rhs * ONE));
 
 1263     FixedPoint16 & operator=(const FixedPoint16 &other)
 
 1265         value = other.value;
 
 1272     template <int IntBits2>
 
 1273     FixedPoint16 & operator=(const FixedPoint16<IntBits2, OverflowHandling> &other)
 
 1275         value = detail::FP16OverflowHandling<OverflowHandling>::exec(
 
 1276                 detail::FP16Align<IntBits2, IntBits, true>::exec(other.value));
 
 1282     operator float() const
 
 1284         return fixed_point_cast<float>(*this);
 
 1289     operator double() const
 
 1291         return fixed_point_cast<double>(*this);
 
 1296     FixedPoint16 operator+() const
 
 1303     FixedPoint16 operator-() const
 
 1305         return FixedPoint16(-value, FPNoShift);
 
 1310     FixedPoint16 & operator++()
 
 1312         value = detail::FP16OverflowHandling<OverflowHandling>::exec(value+ONE);
 
 1318     FixedPoint16 operator++(int)
 
 1320         FixedPoint16 old(*this);
 
 1327     FixedPoint16 & operator--()
 
 1329         value = detail::FP16OverflowHandling<OverflowHandling>::exec(value-ONE);
 
 1335     FixedPoint16 operator--(int)
 
 1337         FixedPoint16 old(*this);
 
 1345     template <int IntBits2>
 
 1346     FixedPoint16 & operator+=(const FixedPoint16<IntBits2, OverflowHandling> &other)
 
 1348         value = detail::FP16AddImpl<IntBits, IntBits2, IntBits, OverflowHandling>::exec(value, other.value);
 
 1355     template <int IntBits2>
 
 1356     FixedPoint16 & operator-=(const FixedPoint16<IntBits2, OverflowHandling> &other)
 
 1358         value = detail::FP16SubImpl<IntBits, IntBits2, IntBits, OverflowHandling>::exec(value, other.value);
 
 1365     template <int IntBits2>
 
 1366     FixedPoint16 & operator*=(const FixedPoint16<IntBits2, OverflowHandling> &other)
 
 1368         value = detail::FP16MulImpl<IntBits, IntBits2, IntBits, OverflowHandling>::exec(value, other.value);
 
 1375     template <int IntBits2>
 
 1376     FixedPoint16 & operator/=(const FixedPoint16<IntBits2, OverflowHandling> &other)
 
 1378         value = detail::FP16DivImpl<IntBits, IntBits2, IntBits, OverflowHandling>::exec(value, other.value);
 
 1383 template <int IntBits, FPOverflowHandling OverflowHandling>
 
 1384 const FixedPoint16<IntBits, OverflowHandling> FixedPoint16<IntBits, OverflowHandling>::zero(0);
 
 1386 template <int IntBits, FPOverflowHandling OverflowHandling>
 
 1387 const FixedPoint16<IntBits, OverflowHandling> FixedPoint16<IntBits, OverflowHandling>::pi(M_PI);
 
 1389 template <int IntBits, FPOverflowHandling OverflowHandling>
 
 1390 const FixedPoint16<IntBits, OverflowHandling> FixedPoint16<IntBits, OverflowHandling>::pi_2(0.5 * M_PI);
 
 1392 template <int IntBits, FPOverflowHandling OverflowHandling>
 
 1393 const FixedPoint16<IntBits, OverflowHandling> FixedPoint16<IntBits, OverflowHandling>::mpi_2(-0.5 * M_PI); 
 
 1398 struct FixedPoint16Cast;
 
 1400 #define VIGRA_FIXED_POINT_CAST(type) \
 
 1402 struct FixedPoint16Cast<type> \
 
 1404     template <int IntBits, FPOverflowHandling OverflowHandling> \
 
 1405     static type cast(FixedPoint16<IntBits, OverflowHandling> v) \
 
 1411 VIGRA_FIXED_POINT_CAST(Int8)
 
 1412 VIGRA_FIXED_POINT_CAST(UInt8)
 
 1413 VIGRA_FIXED_POINT_CAST(Int16)
 
 1414 VIGRA_FIXED_POINT_CAST(UInt16)
 
 1415 VIGRA_FIXED_POINT_CAST(Int32)
 
 1416 VIGRA_FIXED_POINT_CAST(UInt32)
 
 1417 VIGRA_FIXED_POINT_CAST(Int64)
 
 1418 VIGRA_FIXED_POINT_CAST(UInt64)
 
 1420 #undef VIGRA_FIXED_POINT_CAST
 
 1423 struct FixedPoint16Cast<float>
 
 1425     template <int IntBits, FPOverflowHandling OverflowHandling>
 
 1426     static float cast(FixedPoint16<IntBits, OverflowHandling> v)
 
 1428         return (float)v.value / FixedPoint16<IntBits, OverflowHandling>::ONE;
 
 1433 struct FixedPoint16Cast<double>
 
 1435     template <int IntBits, FPOverflowHandling OverflowHandling>
 
 1436     static double cast(FixedPoint16<IntBits, OverflowHandling> v)
 
 1438         return (double)v.value / FixedPoint16<IntBits, OverflowHandling>::ONE;
 
 1471 template <class TARGET, int IntBits, FPOverflowHandling OverflowHandling>
 
 1472 TARGET fixed_point_cast(FixedPoint16<IntBits, OverflowHandling> v)
 
 1474     return detail::FixedPoint16Cast<TARGET>::cast(v);
 
 1479 template <int IntBits1, FPOverflowHandling OverflowHandling, int IntBits2>
 
 1481 bool operator==(FixedPoint16<IntBits1, OverflowHandling> l, FixedPoint16<IntBits2, OverflowHandling> r)
 
 1483     enum { MinIntBits = MetaMin<IntBits1, IntBits2>::value };
 
 1484     return (l.value << (IntBits1 - MinIntBits)) == (r.value << (IntBits2 - MinIntBits));
 
 1488 template <int IntBits1, FPOverflowHandling OverflowHandling, int IntBits2>
 
 1490 bool operator!=(FixedPoint16<IntBits1, OverflowHandling> l, FixedPoint16<IntBits2, OverflowHandling> r)
 
 1492     enum { MinIntBits = MetaMin<IntBits1, IntBits2>::value };
 
 1493     return (l.value << (IntBits1 - MinIntBits)) != (r.value << (IntBits2 - MinIntBits));
 
 1497 template <int IntBits1, FPOverflowHandling OverflowHandling, int IntBits2>
 
 1499 bool operator<(FixedPoint16<IntBits1, OverflowHandling> l, FixedPoint16<IntBits2, OverflowHandling> r)
 
 1501     enum { MinIntBits = MetaMin<IntBits1, IntBits2>::value };
 
 1502     return (l.value << (IntBits1 - MinIntBits)) < (r.value << (IntBits2 - MinIntBits));
 
 1506 template <int IntBits1, FPOverflowHandling OverflowHandling, int IntBits2>
 
 1508 bool operator<=(FixedPoint16<IntBits1, OverflowHandling> l, FixedPoint16<IntBits2, OverflowHandling> r)
 
 1510     enum { MinIntBits = MetaMin<IntBits1, IntBits2>::value };
 
 1511     return (l.value << (IntBits1 - MinIntBits)) <= (r.value << (IntBits2 - MinIntBits));
 
 1515 template <int IntBits1, FPOverflowHandling OverflowHandling, int IntBits2>
 
 1517 bool operator>(FixedPoint16<IntBits1, OverflowHandling> l, FixedPoint16<IntBits2, OverflowHandling> r)
 
 1519     enum { MinIntBits = MetaMin<IntBits1, IntBits2>::value };
 
 1520     return (l.value << (IntBits1 - MinIntBits)) > (r.value << (IntBits2 - MinIntBits));
 
 1524 template <int IntBits1, FPOverflowHandling OverflowHandling, int IntBits2>
 
 1526 bool operator>=(FixedPoint16<IntBits1, OverflowHandling> l, FixedPoint16<IntBits2, OverflowHandling> r)
 
 1528     enum { MinIntBits = MetaMin<IntBits1, IntBits2>::value };
 
 1529     return (l.value << (IntBits1 - MinIntBits)) >= (r.value << (IntBits2 - MinIntBits));
 
 1533 template <int IntBits1, FPOverflowHandling OverflowHandling, int IntBits2>
 
 1535 typename PromoteTraits<FixedPoint16<IntBits1, OverflowHandling>, FixedPoint16<IntBits2, OverflowHandling> >::Promote
 
 1536 operator+(FixedPoint16<IntBits1, OverflowHandling> l, FixedPoint16<IntBits2, OverflowHandling> r)
 
 1539         PromoteTraits<FixedPoint16<IntBits1, OverflowHandling>, FixedPoint16<IntBits2, OverflowHandling> >::Promote
 
 1541     return Result(detail::FP16AddImpl<IntBits1, IntBits2, Result::INT_BITS, OverflowHandling>::exec(l.value, r.value), FPNoShift);
 
 1545 template <int IntBits1, FPOverflowHandling OverflowHandling, int IntBits2, int IntBits3>
 
 1547 FixedPoint16<IntBits3, OverflowHandling> &
 
 1548 add(FixedPoint16<IntBits1, OverflowHandling> l, FixedPoint16<IntBits2, OverflowHandling> r,
 
 1549     FixedPoint16<IntBits3, OverflowHandling> & result)
 
 1551     result.value = detail::FP16AddImpl<IntBits1, IntBits2, IntBits3, OverflowHandling>::exec(l.value, r.value);
 
 1556 template <int IntBits1, FPOverflowHandling OverflowHandling, int IntBits2>
 
 1558 typename PromoteTraits<FixedPoint16<IntBits1, OverflowHandling>, FixedPoint16<IntBits2, OverflowHandling> >::Promote
 
 1559 operator-(FixedPoint16<IntBits1, OverflowHandling> l, FixedPoint16<IntBits2, OverflowHandling> r)
 
 1562         PromoteTraits<FixedPoint16<IntBits1, OverflowHandling>, FixedPoint16<IntBits2, OverflowHandling> >::Promote
 
 1564     return Result(detail::FP16SubImpl<IntBits1, IntBits2, Result::INT_BITS, OverflowHandling>::exec(l.value, r.value), FPNoShift);
 
 1568 template <int IntBits1, FPOverflowHandling OverflowHandling, int IntBits2, int IntBits3>
 
 1569 inline FixedPoint16<IntBits3, OverflowHandling> &
 
 1570 sub(FixedPoint16<IntBits1, OverflowHandling> l, FixedPoint16<IntBits2, OverflowHandling> r,
 
 1571     FixedPoint16<IntBits3, OverflowHandling> & result)
 
 1573     result.value = detail::FP16SubImpl<IntBits1, IntBits2, IntBits3, OverflowHandling>::exec(l.value, r.value);
 
 1578 template <int IntBits1, FPOverflowHandling OverflowHandling, int IntBits2>
 
 1580 typename PromoteTraits<FixedPoint16<IntBits1, OverflowHandling>, FixedPoint16<IntBits2, OverflowHandling> >::Promote
 
 1581 operator*(FixedPoint16<IntBits1, OverflowHandling> l, FixedPoint16<IntBits2, OverflowHandling> r)
 
 1584         PromoteTraits<FixedPoint16<IntBits1, OverflowHandling>, FixedPoint16<IntBits2, OverflowHandling> >::Promote
 
 1586     return Result(detail::FP16MulImpl<IntBits1, IntBits2, Result::INT_BITS, OverflowHandling>::exec(l.value, r.value), FPNoShift);
 
 1590 template <int IntBits1, FPOverflowHandling OverflowHandling, int IntBits2, int IntBits3>
 
 1592 FixedPoint16<IntBits3, OverflowHandling> &
 
 1593 mul(FixedPoint16<IntBits1, OverflowHandling> l, FixedPoint16<IntBits2, OverflowHandling> r,
 
 1594     FixedPoint16<IntBits3, OverflowHandling> & result)
 
 1596     result.value = detail::FP16MulImpl<IntBits1, IntBits2, IntBits3, OverflowHandling>::exec(l.value, r.value);
 
 1601 template <int IntBits1, FPOverflowHandling OverflowHandling, int IntBits2>
 
 1603 typename PromoteTraits<FixedPoint16<IntBits1, OverflowHandling>, FixedPoint16<IntBits2, OverflowHandling> >::Promote
 
 1604 operator/(FixedPoint16<IntBits1, OverflowHandling> l, FixedPoint16<IntBits2, OverflowHandling> r)
 
 1607         PromoteTraits<FixedPoint16<IntBits1, OverflowHandling>, FixedPoint16<IntBits2, OverflowHandling> >::Promote
 
 1609     return Result(detail::FP16DivImpl<IntBits1, IntBits2, Result::INT_BITS, OverflowHandling>::exec(l.value, r.value), FPNoShift);
 
 1613 template <int IntBits1, FPOverflowHandling OverflowHandling, int IntBits2, int IntBits3>
 
 1615 FixedPoint16<IntBits3, OverflowHandling> &
 
 1616 div(FixedPoint16<IntBits1, OverflowHandling> l, FixedPoint16<IntBits2, OverflowHandling> r,
 
 1617     FixedPoint16<IntBits3, OverflowHandling> & result)
 
 1619     result.value = detail::FP16DivImpl<IntBits1, IntBits2, IntBits3, OverflowHandling>::exec(l.value, r.value);
 
 1624 template <int IntBits, FPOverflowHandling OverflowHandling>
 
 1625 inline typename SquareRootTraits<FixedPoint16<IntBits, OverflowHandling> >::SquareRootResult
 
 1626 sqrt(FixedPoint16<IntBits, OverflowHandling> v)
 
 1628     typedef typename SquareRootTraits<FixedPoint16<IntBits, OverflowHandling> >::SquareRootResult Result;
 
 1629     enum { Shift = 15 + IntBits - 2*Result::INT_BITS };
 
 1630     return Result(sqrti(v.value << Shift), FPNoShift);
 
 1633 #ifndef VIGRA_NO_HYPOT
 
 1638 template <int IntBits, FPOverflowHandling OverflowHandling>
 
 1639 inline FixedPoint16<IntBits, OverflowHandling>
 
 1640 hypot(FixedPoint16<IntBits, OverflowHandling> v1, FixedPoint16<IntBits, OverflowHandling> v2)
 
 1642     UInt32 l = abs(v1.value), r = abs(v2.value);   
 
 1644     return FixedPoint16<IntBits, OverflowHandling>(
 
 1645                    detail::FP16OverflowHandling<OverflowHandling>::exec(sqrti(sq(l) + sq(r))), 
 
 1652 template <int IntBits, FPOverflowHandling OverflowHandling>
 
 1653 FixedPoint16<2, OverflowHandling>
 
 1654 atan2(FixedPoint16<IntBits, OverflowHandling> y, FixedPoint16<IntBits, OverflowHandling> x)
 
 1656     enum { ResIntBits = 2 };
 
 1657     typedef FixedPoint16<ResIntBits, OverflowHandling> FP;
 
 1658     static const Int32 Pi_4  = 25736,       
 
 1670         return (y.value > 0)
 
 1676     Int32 abs_y = abs(y.value);
 
 1682         r = ((x.value - abs_y) << 15) / (x.value + abs_y); 
 
 1689         r = ((x.value + abs_y) << 15) / (abs_y - x.value); 
 
 1693     angle += r*((c2 + c1 * (sq(r) >> 15)) >> 15) >> 15;
 
 1695     return (y.value > 0)
 
 1696                ? FP(detail::FP16Align<0, ResIntBits, true>::exec( angle), FPNoShift)
 
 1697                : FP(detail::FP16Align<0, ResIntBits, true>::exec(-angle), FPNoShift);
 
 1701 template <int IntBits, FPOverflowHandling OverflowHandling>
 
 1702 inline FixedPoint16<IntBits, OverflowHandling>
 
 1703 abs(FixedPoint16<IntBits, OverflowHandling> v)
 
 1705     return FixedPoint16<IntBits, OverflowHandling>(abs(v.value), FPNoShift);
 
 1709 template <int IntBits, FPOverflowHandling OverflowHandling>
 
 1711 typename NormTraits<FixedPoint16<IntBits, OverflowHandling> >::SquaredNormType
 
 1712 squaredNorm(FixedPoint16<IntBits, OverflowHandling> v)
 
 1718 template <int IntBits, FPOverflowHandling OverflowHandling>
 
 1720 typename NormTraits<FixedPoint16<IntBits, OverflowHandling> >::NormType
 
 1721 norm(FixedPoint16<IntBits, OverflowHandling> const & v)
 
 1727 template <int IntBits, FPOverflowHandling OverflowHandling>
 
 1728 inline FixedPoint16<IntBits, OverflowHandling>
 
 1729 frac(FixedPoint16<IntBits, OverflowHandling> v)
 
 1731     return FixedPoint16<IntBits, OverflowHandling>(
 
 1732            v.value - (v.value & FixedPoint16<IntBits, OverflowHandling>::INT_MASK), 
 
 1737 template <int IntBits, FPOverflowHandling OverflowHandling>
 
 1738 inline FixedPoint16<IntBits, OverflowHandling>
 
 1739 dual_frac(FixedPoint16<IntBits, OverflowHandling> v)
 
 1741     return FixedPoint16<IntBits, OverflowHandling>(
 
 1742            FixedPoint16<IntBits, OverflowHandling>::ONE - v.value + (v.value & FixedPoint16<IntBits, OverflowHandling>::INT_MASK), 
 
 1747 template <int IntBits, FPOverflowHandling OverflowHandling>
 
 1749 floor(FixedPoint16<IntBits, OverflowHandling> v)
 
 1751     return(v.value >> FixedPoint16<IntBits, OverflowHandling>::FRACTIONAL_BITS);
 
 1755 template <int IntBits, FPOverflowHandling OverflowHandling>
 
 1757 ceil(FixedPoint16<IntBits, OverflowHandling> v)
 
 1759     return((v.value + FixedPoint16<IntBits, OverflowHandling>::FRACTIONAL_MASK) >> 
 
 1760                       FixedPoint16<IntBits, OverflowHandling>::FRACTIONAL_BITS);
 
 1764 template <int IntBits, FPOverflowHandling OverflowHandling>
 
 1766 round(FixedPoint16<IntBits, OverflowHandling> v)
 
 1768     return((v.value + FixedPoint16<IntBits, OverflowHandling>::ONE_HALF) >> 
 
 1769                       FixedPoint16<IntBits, OverflowHandling>::FRACTIONAL_BITS);
 
 1773 template <int IntBits, FPOverflowHandling OverflowHandling>
 
 1775 roundi(FixedPoint16<IntBits, OverflowHandling> v)
 
 1786 template <int IntBits, vigra::FPOverflowHandling OverflowHandling>
 
 1787 ostream & operator<<(ostream & s, vigra::FixedPoint16<IntBits, OverflowHandling> v)
 
 1789     s << vigra::fixed_point_cast<float>(v);
 
Definition: fixedpoint.hxx:47