108 #define FIXMATH_UNSAFE
113 #include "IntegerType.h"
122 template<
typename T> constexpr T shiftR(T x, int8_t bits) {
return (bits > 0 ? (x >> (bits)) : (x << (-bits)));}
123 constexpr int8_t sBitsToBytes(int8_t N) {
return (((N)>>3)+1);}
124 constexpr int8_t uBitsToBytes(int8_t N) {
return (((N-1)>>3)+1);}
125 template<
typename T> constexpr T FM_max(T N1, T N2) {
return (N1) > (N2) ? (N1) : (N2);}
126 template<
typename T> constexpr T FM_min(T N1, T N2) {
return (N1) > (N2) ? (N2) : (N1);}
127 constexpr uint64_t sFullRange(int8_t N) {
return uint64_t(1)<<N;}
128 constexpr uint64_t uFullRange(int8_t N) {
return ((uint64_t(1)<<(N-1))-1) + (uint64_t(1)<<(N-1));}
129 constexpr uint64_t rangeAdd(
byte NF,
byte _NF, uint64_t RANGE, uint64_t _RANGE) {
return ((NF > _NF) ? (RANGE + (_RANGE<<(NF-_NF))) : (_RANGE + (RANGE<<(_NF-NF))));}
130 constexpr int8_t neededNIExtra(int8_t NI, int8_t NF, uint64_t RANGE) {
return (RANGE > (uFullRange(NI+NF)) ? (NI+1) : (RANGE > (uFullRange(NI+NF-1)) ? (NI) : (NI-1)));}
131 constexpr int8_t neededSNIExtra(int8_t NI, int8_t NF, uint64_t RANGE) {
return (RANGE > (sFullRange(NI+NF)) ? (NI+1) : (RANGE > (sFullRange(NI+NF-1)) ? (NI) : (NI-1)));}
132 constexpr uint64_t rangeShift(int8_t N, int8_t SH, uint64_t RANGE) {
return ((SH < N) ? (RANGE) : (shiftR(RANGE,(N-SH))));}
136 template<
int8_t NI,
int8_t NF, u
int64_t RANGE=FixMathPrivate::sFullRange(NI+NF)>
146 template<
int8_t NI,
int8_t NF, u
int64_t RANGE=FixMathPrivate::uFullRange(NI+NF)>
149 static_assert(NI+NF<=64,
"The total width of a UFix cannot exceed 64bits");
150 typedef typename IntegerType<FixMathPrivate::uBitsToBytes(NI+NF)>::unsigned_type internal_type ;
151 typedef typename IntegerType<FixMathPrivate::uBitsToBytes(NI+NF+1)>::unsigned_type next_greater_type ;
162 UFix(
float fl) {internal_value = (fl * (next_greater_type(1) << NF));}
168 UFix(
double fl) {internal_value =
static_cast<internal_type
> (fl * (next_greater_type(1) << NF)); }
179 UFix(T value,
bool as_raw=
false) {
181 if (as_raw) internal_value = value;
182 else internal_value = (internal_type(value) << NF);
201 template<
int8_t _NI,
int8_t _NF, u
int64_t _RANGE>
203 internal_value = FixMathPrivate::shiftR((
typename IntegerType<FixMathPrivate::uBitsToBytes(FixMathPrivate::FM_max(NI+NF,_NI+_NF))>::unsigned_type) uf.
asRaw(),(_NF-NF));
212 template<
int8_t _NI,
int8_t _NF, u
int64_t _RANGE>
214 internal_value = FixMathPrivate::shiftR((
typename IntegerType<FixMathPrivate::uBitsToBytes(FixMathPrivate::FM_max(NI+NF,_NI+_NF))>::unsigned_type) uf.
asRaw(),(_NF-NF));
224 template<
int8_t _NI,
int8_t _NF, u
int64_t _RANGE>
225 UFix<FixMathPrivate::neededNIExtra(FixMathPrivate::FM_max(NI,_NI),FixMathPrivate::FM_max(NF,_NF),FixMathPrivate::rangeAdd(NF,_NF,RANGE,_RANGE)),FixMathPrivate::FM_max(NF, _NF), FixMathPrivate::rangeAdd(NF,_NF,RANGE,_RANGE)>
operator+ (
const UFix<_NI,_NF,_RANGE>& op)
const
227 constexpr uint64_t new_RANGE = FixMathPrivate::rangeAdd(NF,_NF,RANGE,_RANGE);
228 constexpr int8_t new_NI = FixMathPrivate::neededNIExtra(FixMathPrivate::FM_max(NI,_NI),FixMathPrivate::FM_max(NF,_NF),new_RANGE);
229 constexpr int8_t new_NF = FixMathPrivate::FM_max(NF, _NF);
230 typedef typename IntegerType<FixMathPrivate::uBitsToBytes(new_NI+new_NF)>::unsigned_type return_type;
234 return_type tt = return_type(left.
asRaw()) + right.
asRaw();
242 template<
int8_t _NI,
int8_t _NF, u
int64_t _RANGE>
243 SFix<FixMathPrivate::neededSNIExtra(FixMathPrivate::FM_max(NI,_NI),FixMathPrivate::FM_max(NF,_NF),FixMathPrivate::rangeAdd(NF,_NF,RANGE,_RANGE)),FixMathPrivate::FM_max(NF, _NF), FixMathPrivate::rangeAdd(NF,_NF,RANGE,_RANGE)>
operator+ (
const SFix<_NI,_NF,_RANGE>& op)
const
245 constexpr uint64_t new_RANGE = FixMathPrivate::rangeAdd(NF,_NF,RANGE,_RANGE);
246 constexpr int8_t new_NI = FixMathPrivate::neededSNIExtra(FixMathPrivate::FM_max(NI,_NI),FixMathPrivate::FM_max(NF,_NF),new_RANGE);
247 constexpr int8_t new_NF = FixMathPrivate::FM_max(NF, _NF);
248 typedef typename IntegerType<FixMathPrivate::uBitsToBytes(new_NI+new_NF)>::signed_type return_type;
252 return_type tt = return_type(left.
asRaw()) + right.
asRaw();
256 #ifdef FIXMATH_UNSAFE
265 return UFix<NI,NF>(internal_value+((internal_type)op<<NF),
true);
275 template<
int8_t _NI,
int8_t _NF, u
int64_t _RANGE>
276 SFix<FixMathPrivate::FM_max(NI,_NI),FixMathPrivate::FM_max(NF,_NF), FixMathPrivate::FM_max(FixMathPrivate::shiftR(RANGE,FixMathPrivate::FM_max(NF,_NF)-NF), FixMathPrivate::shiftR(_RANGE,FixMathPrivate::FM_max(NF,_NF)-_NF))>
operator- (
const UFix<_NI,_NF, _RANGE>& op)
const
278 constexpr int8_t new_NI = FixMathPrivate::FM_max(NI, _NI);
279 constexpr int8_t new_NF = FixMathPrivate::FM_max(NF, _NF);
280 typedef typename IntegerType<FixMathPrivate::sBitsToBytes(new_NI+new_NF)>::signed_type return_type;
284 return_type tt = return_type(left.
asRaw()) - right.
asRaw();
285 return SFix<new_NI,new_NF,FixMathPrivate::FM_max(FixMathPrivate::shiftR(RANGE,FixMathPrivate::FM_max(NF,_NF)-NF), FixMathPrivate::shiftR(_RANGE,FixMathPrivate::FM_max(NF,_NF)-_NF))>(tt,
true);
288 #ifdef FIXMATH_UNSAFE
297 return UFix<NI,NF>(internal_value-((internal_type)op<<NF),
true);
315 template<
int8_t _NI,
int8_t _NF, u
int64_t _RANGE>
318 constexpr int8_t NEW_NI = FixMathPrivate::neededNIExtra(NI+_NI, NF+_NF, RANGE*_RANGE);
319 typedef typename IntegerType<FixMathPrivate::uBitsToBytes(NEW_NI+NF+_NF)>::unsigned_type return_type ;
320 return_type tt = return_type(internal_value)*op.
asRaw();
328 template<
int8_t _NI,
int8_t _NF, u
int64_t _RANGE>
331 constexpr int8_t NEW_NI = FixMathPrivate::neededSNIExtra(NI+_NI, NF+_NF, RANGE*_RANGE);
332 typedef typename IntegerType<FixMathPrivate::sBitsToBytes(NEW_NI+NF+_NF)>::signed_type return_type ;
333 return_type tt = return_type(internal_value)*op.
asRaw();
337 #ifdef FIXMATH_UNSAFE
360 static_assert(NI+NF<=63, "The fast inverse cannot be computed for when NI+NF>63. Reduce the number of bits.
");
361 return UFix<NF,NI>((onesbitmask()/internal_value),true);
370 UFix<NF,_NF> inv() const
372 return UFix<_NF,NF>(internal_value,true).invFast();
382 UFix<NF,FixMathPrivate::FM_min(NI*2+NF,63-NF)> invAccurate() const // The FixMathPrivate::FM_min is just to remove compiler error when a big FixMath is instanciated but no accurate inverse is actually computed (this would be catch by the static_assert)
384 static_assert(2*NI+2*NF<=63, "The accurate inverse cannot be computed
for when 2*NI+2*NF>63. Reduce the number of bits.
");
385 return inv<NI*2+NF>();
400 UFix<NI,NF> operator>> (const int8_t op) const
402 return UFix<NI,NF>(internal_value>>op,true);
406 #ifdef FIXMATH_UNSAFE
413 UFix<NI,NF> operator<< (const int8_t op) const
415 return UFix<NI,NF>(internal_value<<op,true);
424 UFix<FixMathPrivate::FM_max(NI-op,0),NF+op, FixMathPrivate::rangeShift(NI,op,RANGE)> sR()
426 return UFix<FixMathPrivate::FM_max(NI-op,0),NF+op,FixMathPrivate::rangeShift(NI,op,RANGE)>(internal_value,true);
434 UFix<NI+op,FixMathPrivate::FM_max(NF-op,0),FixMathPrivate::rangeShift(NF,op,RANGE)> sL()
436 return UFix<NI+op,FixMathPrivate::FM_max(NF-op,0)>(internal_value,true);
441 /** Comparison with another UFix.
443 @return true if this is bigger than op, false otherwise
445 template<int8_t _NI, int8_t _NF>
446 bool operator> (const UFix<_NI,_NF>& op) const
448 constexpr int8_t new_NI = FixMathPrivate::FM_max(NI, _NI);
449 constexpr int8_t new_NF = FixMathPrivate::FM_max(NF, _NF);
450 UFix<new_NI,new_NF> left(*this);
451 UFix<new_NI,new_NF> right(op);
452 return left.asRaw()>right.asRaw();
459 template<int8_t _NI, int8_t _NF>
460 bool operator< (const UFix<_NI,_NF>& op) const
470 template<int8_t _NI, int8_t _NF>
471 bool operator== (const UFix<_NI,_NF>& op) const
473 constexpr int8_t new_NI = FixMathPrivate::FM_max(NI, _NI);
474 constexpr int8_t new_NF = FixMathPrivate::FM_max(NF, _NF);
475 UFix<new_NI,new_NF> left(*this);
476 UFix<new_NI,new_NF> right(op);
477 return left.asRaw()==right.asRaw();
484 template<int8_t _NI, int8_t _NF>
485 bool operator!= (const UFix<_NI,_NF>& op) const
487 constexpr int8_t new_NI = FixMathPrivate::FM_max(NI, _NI);
488 constexpr int8_t new_NF = FixMathPrivate::FM_max(NF, _NF);
489 UFix<new_NI,new_NF> left(*this);
490 UFix<new_NI,new_NF> right(op);
491 return left.asRaw()!=right.asRaw();
497 SFix<NI,NF,RANGE> asSFix() const
499 return SFix<NI,NF,RANGE>(internal_value,true);
505 float asFloat() const { return (static_cast<float>(internal_value)) / (next_greater_type(1)<<NF); }
510 internal_type asRaw() const { return internal_value; }
515 int8_t getNI() const {return NI;}
520 int8_t getNF() const {return NF;}
523 internal_type internal_value;
524 static constexpr internal_type onesbitmask() { return (internal_type) ((1ULL<< (NI+NF)) - 1); }
528 #ifdef FIXMATH_UNSAFE
530 template <int8_t NI, int8_t NF>
531 inline UFix<NI, NF> operator*(uint8_t op, const UFix<NI, NF>& uf) {return uf*op;}
533 template <int8_t NI, int8_t NF>
534 inline UFix<NI, NF> operator*(uint16_t op, const UFix<NI, NF>& uf) {return uf*op;}
536 template <int8_t NI, int8_t NF>
537 inline UFix<NI, NF> operator*(uint32_t op, const UFix<NI, NF>& uf) {return uf*op;}
539 template <int8_t NI, int8_t NF>
540 inline UFix<NI, NF> operator*(uint64_t op, const UFix<NI, NF>& uf) {return uf*op;}
542 template <int8_t NI, int8_t NF>
543 inline UFix<NI, NF> operator*(int8_t op, const UFix<NI, NF>& uf) {return uf*op;}
545 template <int8_t NI, int8_t NF>
546 inline UFix<NI, NF> operator*(int16_t op, const UFix<NI, NF>& uf) {return uf*op;}
548 template <int8_t NI, int8_t NF>
549 inline UFix<NI, NF> operator*(int32_t op, const UFix<NI, NF>& uf) {return uf*op;}
551 template <int8_t NI, int8_t NF>
552 inline UFix<NI, NF> operator*(int64_t op, const UFix<NI, NF>& uf) {return uf*op;}
554 template <int8_t NI, int8_t NF>
555 inline UFix<NI, NF> operator*(float op, const UFix<NI, NF>& uf) {return uf*op;}
557 template <int8_t NI, int8_t NF>
558 inline UFix<NI, NF> operator*(double op, const UFix<NI, NF>& uf) {return uf*op;}
561 template <int8_t NI, int8_t NF>
562 inline UFix<NI, NF> operator+(uint8_t op, const UFix<NI, NF>& uf) {return uf+op;}
564 template <int8_t NI, int8_t NF>
565 inline UFix<NI, NF> operator+(uint16_t op, const UFix<NI, NF>& uf) {return uf+op;}
567 template <int8_t NI, int8_t NF>
568 inline UFix<NI, NF> operator+(uint32_t op, const UFix<NI, NF>& uf) {return uf+op;}
570 template <int8_t NI, int8_t NF>
571 inline UFix<NI, NF> operator+(uint64_t op, const UFix<NI, NF>& uf) {return uf+op;}
573 template <int8_t NI, int8_t NF>
574 inline UFix<NI, NF> operator+(int8_t op, const UFix<NI, NF>& uf) {return uf+op;}
576 template <int8_t NI, int8_t NF>
577 inline UFix<NI, NF> operator+(int16_t op, const UFix<NI, NF>& uf) {return uf+op;}
579 template <int8_t NI, int8_t NF>
580 inline UFix<NI, NF> operator+(int32_t op, const UFix<NI, NF>& uf) {return uf+op;}
582 template <int8_t NI, int8_t NF>
583 inline UFix<NI, NF> operator+(int64_t op, const UFix<NI, NF>& uf) {return uf+op;}
585 template <int8_t NI, int8_t NF>
586 inline UFix<NI, NF> operator+(float op, const UFix<NI, NF>& uf) {return uf+op;}
588 template <int8_t NI, int8_t NF>
589 inline UFix<NI, NF> operator+(double op, const UFix<NI, NF>& uf) {return uf+op;}
592 template <int8_t NI, int8_t NF>
593 inline SFix<NI, NF> operator-(uint8_t op, const UFix<NI, NF>& uf) {return -uf+op;}
595 template <int8_t NI, int8_t NF>
596 inline SFix<NI, NF> operator-(uint16_t op, const UFix<NI, NF>& uf) {return -uf+op;}
598 template <int8_t NI, int8_t NF>
599 inline SFix<NI, NF> operator-(uint32_t op, const UFix<NI, NF>& uf) {return -uf+op;}
601 template <int8_t NI, int8_t NF>
602 inline SFix<NI, NF> operator-(uint64_t op, const UFix<NI, NF>& uf) {return -uf+op;}
604 template <int8_t NI, int8_t NF>
605 inline SFix<NI, NF> operator-(int8_t op, const UFix<NI, NF>& uf) {return -uf+op;}
607 template <int8_t NI, int8_t NF>
608 inline SFix<NI, NF> operator-(int16_t op, const UFix<NI, NF>& uf) {return -uf+op;}
610 template <int8_t NI, int8_t NF>
611 inline SFix<NI, NF> operator-(int32_t op, const UFix<NI, NF>& uf) {return -uf+op;}
613 template <int8_t NI, int8_t NF>
614 inline SFix<NI, NF> operator-(int64_t op, const UFix<NI, NF>& uf) {return -uf+op;}
616 template <int8_t NI, int8_t NF>
617 inline SFix<NI, NF> operator-(float op, const UFix<NI, NF>& uf) {return -uf+op;}
619 template <int8_t NI, int8_t NF>
620 inline SFix<NI, NF> operator-(double op, const UFix<NI, NF>& uf) {return -uf+op;}
637 inline UFix<0, sizeof(T)*8> toUFraction(T val) {
638 return UFix<0, sizeof(T)*8>::fromRaw(val);
652 inline UFix<sizeof(T)*8,0> toUInt(T val) {
653 return UFix<sizeof(T)*8,0>::fromRaw(val);
664 template<int8_t NI, int8_t NF, uint64_t RANGE> // NI and NF being the number of bits for the integral and the fractionnal parts respectively.
667 static_assert(NI+NF<64, "The total width of a
SFix cannot exceed 63bits
");
668 typedef typename IntegerType<FixMathPrivate::sBitsToBytes(NI+NF)>::signed_type internal_type ; // smallest size that fits our internal integer
669 typedef typename IntegerType<FixMathPrivate::sBitsToBytes(NI+NF+1)>::signed_type next_greater_type ; // smallest size that fits 1<<NF for sure (NI could be equal to 0). It can be the same than internal_type in some cases.
680 SFix(float fl) {internal_value = /*static_cast<internal_type>*/(fl * (next_greater_type(1) << NF));}
686 SFix(double fl) {internal_value = static_cast<internal_type> (fl * (next_greater_type(1) << NF)); }
696 SFix(T value,bool as_raw=false)
698 if (as_raw) internal_value = value;
699 else internal_value = (internal_type(value) << NF);
707 static SFix<NI,NF> fromRaw(T raw){return SFix<NI,NF>(raw,true);}
714 template<int8_t _NI, int8_t _NF, uint64_t _RANGE>
715 SFix(const SFix<_NI,_NF, _RANGE>& uf) {
716 internal_value = FixMathPrivate::shiftR((typename IntegerType<FixMathPrivate::sBitsToBytes(FixMathPrivate::FM_max(NI+NF,_NI+_NF))>::signed_type) uf.asRaw(),(_NF-NF));
724 template<int8_t _NI, int8_t _NF, uint64_t _RANGE>
725 SFix(const UFix<_NI,_NF, _RANGE>& uf) {
726 internal_value = FixMathPrivate::shiftR((typename IntegerType<FixMathPrivate::uBitsToBytes(FixMathPrivate::FM_max(NI+NF,_NI+_NF))>::unsigned_type) uf.asRaw(),(_NF-NF));
735 template<int8_t _NI, int8_t _NF, uint64_t _RANGE>
736 SFix<FixMathPrivate::neededSNIExtra(FixMathPrivate::FM_max(NI,_NI),FixMathPrivate::FM_max(NF,_NF),FixMathPrivate::rangeAdd(NF,_NF,RANGE,_RANGE)),FixMathPrivate::FM_max(NF, _NF), FixMathPrivate::rangeAdd(NF,_NF,RANGE,_RANGE)> operator+ (const SFix<_NI,_NF,_RANGE>& op) const
738 constexpr uint64_t new_RANGE = FixMathPrivate::rangeAdd(NF,_NF,RANGE,_RANGE);
739 constexpr int8_t new_NI = FixMathPrivate::neededSNIExtra(FixMathPrivate::FM_max(NI,_NI),FixMathPrivate::FM_max(NF,_NF),new_RANGE);
740 constexpr int8_t new_NF = FixMathPrivate::FM_max(NF, _NF);
741 typedef typename IntegerType<FixMathPrivate::sBitsToBytes(new_NI+new_NF)>::signed_type return_type;
742 SFix<new_NI,new_NF> left(*this);
743 SFix<new_NI,new_NF> right(op);
745 return_type tt = return_type(left.asRaw()) + right.asRaw();
746 return SFix<new_NI, new_NF, new_RANGE>(tt,true);
749 #ifdef FIXMATH_UNSAFE
756 SFix<NI,NF> operator+ (const T op) const
758 return SFix<NI,NF>(internal_value+(op<<NF),true);
768 template<int8_t _NI, int8_t _NF, uint64_t _RANGE>
769 SFix<FixMathPrivate::neededSNIExtra(FixMathPrivate::FM_max(NI,_NI),FixMathPrivate::FM_max(NF,_NF),FixMathPrivate::rangeAdd(NF,_NF,RANGE,_RANGE)),FixMathPrivate::FM_max(NF, _NF), FixMathPrivate::rangeAdd(NF,_NF,RANGE,_RANGE)> operator- (const SFix<_NI,_NF, _RANGE>& op) const
771 constexpr uint64_t new_RANGE = FixMathPrivate::rangeAdd(NF,_NF,RANGE,_RANGE);
772 constexpr int8_t new_NI = FixMathPrivate::neededSNIExtra(FixMathPrivate::FM_max(NI,_NI),FixMathPrivate::FM_max(NF,_NF),new_RANGE);
773 constexpr int8_t new_NF = FixMathPrivate::FM_max(NF, _NF);
774 typedef typename IntegerType<FixMathPrivate::sBitsToBytes(new_NI+new_NF)>::signed_type return_type;
775 SFix<new_NI,new_NF> left(*this);
776 SFix<new_NI,new_NF> right(op);
777 return_type tt = return_type(left.asRaw()) - return_type(right.asRaw());
778 return SFix<new_NI, new_NF, new_RANGE>(tt,true);
785 template<int8_t _NI, int8_t _NF, uint64_t _RANGE>
786 SFix<FixMathPrivate::neededSNIExtra(FixMathPrivate::FM_max(NI,_NI),FixMathPrivate::FM_max(NF,_NF),FixMathPrivate::rangeAdd(NF,_NF,RANGE,_RANGE)),FixMathPrivate::FM_max(NF, _NF), FixMathPrivate::rangeAdd(NF,_NF,RANGE,_RANGE)> operator- (const UFix<_NI,_NF, _RANGE>& op) const
788 constexpr uint64_t new_RANGE = FixMathPrivate::rangeAdd(NF,_NF,RANGE,_RANGE);
789 constexpr int8_t new_NI = FixMathPrivate::neededSNIExtra(FixMathPrivate::FM_max(NI,_NI),FixMathPrivate::FM_max(NF,_NF),new_RANGE);
790 constexpr int8_t new_NF = FixMathPrivate::FM_max(NF, _NF);
791 typedef typename IntegerType<FixMathPrivate::sBitsToBytes(new_NI+new_NF)>::signed_type return_type;
792 SFix<new_NI,new_NF> left(*this);
793 SFix<new_NI,new_NF> right(op);
794 return_type tt = return_type(left.asRaw()) - return_type(right.asRaw());
795 return SFix<new_NI, new_NF, new_RANGE>(tt,true);
798 #ifdef FIXMATH_UNSAFE
805 SFix<NI,NF> operator- (const T op) const
807 return SFix<NI,NF>(internal_value-(op<<NF),true);
814 SFix<NI,NF,RANGE> operator-() const
816 return SFix<NI,NF,RANGE>(-internal_value,true);
825 template<int8_t _NI, int8_t _NF, uint64_t _RANGE>
826 SFix<FixMathPrivate::neededSNIExtra(NI+_NI, NF+_NF, RANGE*_RANGE),NF+_NF, RANGE*_RANGE> operator* (const SFix<_NI,_NF,_RANGE>& op) const
828 constexpr int8_t NEW_NI = FixMathPrivate::neededSNIExtra(NI+_NI, NF+_NF, RANGE*_RANGE);
829 typedef typename IntegerType<FixMathPrivate::sBitsToBytes(NI+_NI+NF+_NF)>::signed_type return_type ;
830 return_type tt = return_type(internal_value)*op.asRaw();
831 return SFix<NI+_NI,NF+_NF>(tt,true);
834 #ifdef FIXMATH_UNSAFE
841 SFix<NI,NF> operator* (const T op) const
843 return SFix<NI,NF>(internal_value*op,true);
857 SFix<NF,NI> invFast() const
859 static_assert(NI+NF<=62, "The fast inverse cannot be computed
for when NI+NF>63. Reduce the number of bits.
");
860 return SFix<NF,NI>((onesbitmask()/internal_value),true);
868 SFix<NF,_NF> inv() const
870 return SFix<_NF,NF>(internal_value,true).invFast();
878 SFix<NF,FixMathPrivate::FM_min(NI*2+NF,62-NF)> invAccurate() const
880 return inv<NI*2+NF>();
891 SFix<NI,NF> operator>> (const int8_t op) const
893 return SFix<NI,NF>(internal_value>>op,true);
896 #ifdef FIXMATH_UNSAFE
903 SFix<NI,NF> operator<< (const int8_t op) const
905 return SFix<NI,NF>(internal_value<<op,true);
914 SFix<FixMathPrivate::FM_max(NI-op,0), NF+op, FixMathPrivate::rangeShift(NI,op,RANGE)> sR()
916 return SFix<FixMathPrivate::FM_max(NI-op,0),NF+op,FixMathPrivate::rangeShift(NI,op,RANGE)>(internal_value,true);
924 SFix<NI+op,FixMathPrivate::FM_max(NF-op,0),FixMathPrivate::rangeShift(NF,op,RANGE)> sL()
926 return SFix<NI+op,FixMathPrivate::FM_max(NF-op,0)>(internal_value,true);
936 template<int8_t _NI, int8_t _NF>
937 bool operator> (const SFix<_NI,_NF>& op) const
939 constexpr int8_t new_NI = FixMathPrivate::FM_max(NI, _NI);
940 constexpr int8_t new_NF = FixMathPrivate::FM_max(NF, _NF);
941 SFix<new_NI,new_NF> left(*this);
942 SFix<new_NI,new_NF> right(op);
943 return left.asRaw()>right.asRaw();
950 template<int8_t _NI, int8_t _NF>
951 bool operator< (const SFix<_NI,_NF>& op) const
961 template<int8_t _NI, int8_t _NF>
962 bool operator== (const SFix<_NI,_NF>& op) const
964 constexpr int8_t new_NI = FixMathPrivate::FM_max(NI, _NI);
965 constexpr int8_t new_NF = FixMathPrivate::FM_max(NF, _NF);
966 SFix<new_NI,new_NF> left(*this);
967 SFix<new_NI,new_NF> right(op);
968 return left.asRaw()==right.asRaw();
975 template<int8_t _NI, int8_t _NF>
976 bool operator!= (const SFix<_NI,_NF>& op) const
978 constexpr int8_t new_NI = FixMathPrivate::FM_max(NI, _NI);
979 constexpr int8_t new_NF = FixMathPrivate::FM_max(NF, _NF);
980 SFix<new_NI,new_NF> left(*this);
981 SFix<new_NI,new_NF> right(op);
982 return left.asRaw()!=right.asRaw();
989 UFix<NI,NF,RANGE> asUFix() const
991 return UFix<NI,NF,RANGE>(internal_value,true);
998 float asFloat() const {return (static_cast<float>(internal_value)) / (next_greater_type(1)<<NF); }
1003 internal_type asRaw() const {return internal_value; }
1008 int8_t getNI() const {return NI;}
1013 int8_t getNF() const {return NF;}
1017 internal_type internal_value;
1018 static constexpr internal_type onesbitmask() { return (internal_type) ((1ULL<< (NI+NF)) - 1); }
1022 #ifdef FIXMATH_UNSAFE
1026 template <int8_t NI, int8_t NF>
1027 inline SFix<NI, NF> operator*(uint8_t op, const SFix<NI, NF>& uf) {return uf*op;}
1029 template <int8_t NI, int8_t NF>
1030 inline SFix<NI, NF> operator*(uint16_t op, const SFix<NI, NF>& uf) {return uf*op;}
1032 template <int8_t NI, int8_t NF>
1033 inline SFix<NI, NF> operator*(uint32_t op, const SFix<NI, NF>& uf) {return uf*op;}
1035 template <int8_t NI, int8_t NF>
1036 inline SFix<NI, NF> operator*(uint64_t op, const SFix<NI, NF>& uf) {return uf*op;}
1038 template <int8_t NI, int8_t NF>
1039 inline SFix<NI, NF> operator*(int8_t op, const SFix<NI, NF>& uf) {return uf*op;}
1041 template <int8_t NI, int8_t NF>
1042 inline SFix<NI, NF> operator*(int16_t op, const SFix<NI, NF>& uf) {return uf*op;}
1044 template <int8_t NI, int8_t NF>
1045 inline SFix<NI, NF> operator*(int32_t op, const SFix<NI, NF>& uf) {return uf*op;}
1047 template <int8_t NI, int8_t NF>
1048 inline SFix<NI, NF> operator*(int64_t op, const SFix<NI, NF>& uf) {return uf*op;}
1050 template <int8_t NI, int8_t NF>
1051 inline SFix<NI, NF> operator*(float op, const SFix<NI, NF>& uf) {return uf*op;}
1053 template <int8_t NI, int8_t NF>
1054 inline SFix<NI, NF> operator*(double op, const SFix<NI, NF>& uf) {return uf*op;}
1057 template <int8_t NI, int8_t NF>
1058 inline SFix<NI, NF> operator+(uint8_t op, const SFix<NI, NF>& uf) {return uf+op;}
1060 template <int8_t NI, int8_t NF>
1061 inline SFix<NI, NF> operator+(uint16_t op, const SFix<NI, NF>& uf) {return uf+op;}
1063 template <int8_t NI, int8_t NF>
1064 inline SFix<NI, NF> operator+(uint32_t op, const SFix<NI, NF>& uf) {return uf+op;}
1066 template <int8_t NI, int8_t NF>
1067 inline SFix<NI, NF> operator+(uint64_t op, const SFix<NI, NF>& uf) {return uf+op;}
1069 template <int8_t NI, int8_t NF>
1070 inline SFix<NI, NF> operator+(int8_t op, const SFix<NI, NF>& uf) {return uf+op;}
1072 template <int8_t NI, int8_t NF>
1073 inline SFix<NI, NF> operator+(int16_t op, const SFix<NI, NF>& uf) {return uf+op;}
1075 template <int8_t NI, int8_t NF>
1076 inline SFix<NI, NF> operator+(int32_t op, const SFix<NI, NF>& uf) {return uf+op;}
1078 template <int8_t NI, int8_t NF>
1079 inline SFix<NI, NF> operator+(int64_t op, const SFix<NI, NF>& uf) {return uf+op;}
1081 template <int8_t NI, int8_t NF>
1082 inline SFix<NI, NF> operator+(float op, const SFix<NI, NF>& uf) {return uf+op;}
1084 template <int8_t NI, int8_t NF>
1085 inline SFix<NI, NF> operator+(double op, const SFix<NI, NF>& uf) {return uf+op;}
1088 template <int8_t NI, int8_t NF>
1089 inline SFix<NI, NF> operator-(uint8_t op, const SFix<NI, NF>& uf) {return (-uf)+op;}
1091 template <int8_t NI, int8_t NF>
1092 inline SFix<NI, NF> operator-(uint16_t op, const SFix<NI, NF>& uf) {return (-uf)+op;}
1094 template <int8_t NI, int8_t NF>
1095 inline SFix<NI, NF> operator-(uint32_t op, const SFix<NI, NF>& uf) {return (-uf)+op;}
1097 template <int8_t NI, int8_t NF>
1098 inline SFix<NI, NF> operator-(uint64_t op, const SFix<NI, NF>& uf) {return (-uf)+op;}
1100 template <int8_t NI, int8_t NF>
1101 inline SFix<NI, NF> operator-(int8_t op, const SFix<NI, NF>& uf) {return (-uf)+op;}
1103 template <int8_t NI, int8_t NF>
1104 inline SFix<NI, NF> operator-(int16_t op, const SFix<NI, NF>& uf) {return (-uf)+op;}
1106 template <int8_t NI, int8_t NF>
1107 inline SFix<NI, NF> operator-(int32_t op, const SFix<NI, NF>& uf) {return (-uf)+op;}
1109 template <int8_t NI, int8_t NF>
1110 inline SFix<NI, NF> operator-(int64_t op, const SFix<NI, NF>& uf) {return (-uf)+op;}
1112 template <int8_t NI, int8_t NF>
1113 inline SFix<NI, NF> operator-(float op, const SFix<NI, NF>& uf) {return (-uf)+op;}
1115 template <int8_t NI, int8_t NF>
1116 inline SFix<NI, NF> operator-(double op, const SFix<NI, NF>& uf) {return (-uf)+op;}
1130 template<int8_t NI, int8_t NF, uint64_t RANGE, int8_t _NI, int8_t _NF, uint64_t _RANGE>
1131 inline SFix<FixMathPrivate::neededSNIExtra(FixMathPrivate::FM_max(NI,_NI),FixMathPrivate::FM_max(NF,_NF),FixMathPrivate::rangeAdd(NF,_NF,RANGE,_RANGE)),FixMathPrivate::FM_max(NF, _NF), FixMathPrivate::rangeAdd(NF,_NF,RANGE,_RANGE)> operator+ (const SFix<NI,NF,RANGE>& op1, const UFix<_NI,_NF,_RANGE>& op2 )
1142 template<int8_t NI, int8_t NF, uint64_t RANGE, int8_t _NI, int8_t _NF, uint64_t _RANGE>
1143 inline SFix<FixMathPrivate::neededSNIExtra(FixMathPrivate::FM_max(NI,_NI),FixMathPrivate::FM_max(NF,_NF),FixMathPrivate::rangeAdd(NF,_NF,RANGE,_RANGE)),FixMathPrivate::FM_max(NF, _NF), FixMathPrivate::rangeAdd(NF,_NF,RANGE,_RANGE)> operator- (const UFix<NI,NF, RANGE>& op1, const SFix<_NI,_NF, _RANGE>& op2)
1154 template<int8_t NI, int8_t NF, uint64_t RANGE, int8_t _NI, int8_t _NF, uint64_t _RANGE>
1155 inline SFix<FixMathPrivate::neededSNIExtra(NI+_NI, NF+_NF, RANGE*_RANGE),NF+_NF, RANGE*_RANGE> operator* (const SFix<_NI,_NF,_RANGE>& op1, const UFix<NI,NF,RANGE>& op2)
1160 // Comparison between SFix and UFixmath
1167 template<int8_t NI, int8_t NF, int8_t _NI, int8_t _NF>
1168 inline bool operator> (const SFix<NI,NF>& op1, const UFix<_NI,_NF>& op2 )
1170 constexpr int8_t new_NI = FixMathPrivate::FM_max(NI, _NI);
1171 constexpr int8_t new_NF = FixMathPrivate::FM_max(NF, _NF);
1172 SFix<new_NI,new_NF> left(op1);
1173 SFix<new_NI,new_NF> right(op2);
1174 return left.asRaw() > right.asRaw();
1182 template<int8_t NI, int8_t NF, int8_t _NI, int8_t _NF>
1183 inline bool operator> (const UFix<NI,NF>& op1, const SFix<_NI,_NF>& op2 )
1185 constexpr int8_t new_NI = FixMathPrivate::FM_max(NI, _NI);
1186 constexpr int8_t new_NF = FixMathPrivate::FM_max(NF, _NF);
1187 SFix<new_NI,new_NF> left(op1);
1188 SFix<new_NI,new_NF> right(op2);
1189 return left.asRaw() > right.asRaw();
1197 template<int8_t NI, int8_t NF, int8_t _NI, int8_t _NF>
1198 inline bool operator< (const UFix<NI,NF>& op1, const SFix<_NI,_NF>& op2 )
1209 template<int8_t NI, int8_t NF, int8_t _NI, int8_t _NF>
1210 inline bool operator< (const SFix<NI,NF>& op1, const UFix<_NI,_NF>& op2 )
1221 template<int8_t NI, int8_t NF, int8_t _NI, int8_t _NF>
1222 inline bool operator== (const SFix<NI,NF>& op1, const UFix<_NI,_NF>& op2 )
1224 constexpr int8_t new_NI = FixMathPrivate::FM_max(NI, _NI);
1225 constexpr int8_t new_NF = FixMathPrivate::FM_max(NF, _NF);
1226 SFix<new_NI,new_NF> left(op1);
1227 SFix<new_NI,new_NF> right(op2);
1228 return left.asRaw() == right.asRaw();
1237 template<int8_t NI, int8_t NF, int8_t _NI, int8_t _NF>
1238 inline bool operator== (const UFix<NI,NF>& op1, const SFix<_NI,_NF>& op2 )
1248 template<int8_t NI, int8_t NF, int8_t _NI, int8_t _NF>
1249 inline bool operator!= (const SFix<NI,NF>& op1, const UFix<_NI,_NF>& op2 )
1251 constexpr int8_t new_NI = FixMathPrivate::FM_max(NI, _NI);
1252 constexpr int8_t new_NF = FixMathPrivate::FM_max(NF, _NF);
1253 SFix<new_NI,new_NF> left(op1);
1254 SFix<new_NI,new_NF> right(op2);
1255 return left.asRaw() != right.asRaw();
1264 template<int8_t NI, int8_t NF, int8_t _NI, int8_t _NF>
1265 inline bool operator!= (const UFix<NI,NF>& op1, const SFix<_NI,_NF>& op2 )
1284 template<typename T>
1285 inline SFix<0, sizeof(T)*8-1> toSFraction(T val) {
1286 return SFix<0, sizeof(T)*8-1>::fromRaw(val);
1299 template<typename T>
1300 inline SFix<sizeof(T)*8-1,0> toSInt(T val) {
1301 return SFix<sizeof(T)*8-1,0>::fromRaw(val);
Definition: FixMath.h:666
internal_type asRaw() const
Definition: FixMath.h:1003
Definition: FixMath.h:148
SFix< NI, NF, RANGE > operator-() const
Definition: FixMath.h:304
UFix(double fl)
Definition: FixMath.h:168
UFix()
Definition: FixMath.h:156
UFix(const UFix< _NI, _NF, _RANGE > &uf)
Definition: FixMath.h:202
static UFix< NI, NF > fromRaw(T raw)
Definition: FixMath.h:191
UFix(const SFix< _NI, _NF, _RANGE > &uf)
Definition: FixMath.h:213
UFix(T value, bool as_raw=false)
Definition: FixMath.h:179
UFix(float fl)
Definition: FixMath.h:162
UFix< FixMathPrivate::neededNIExtra(NI+_NI, NF+_NF, RANGE *_RANGE), NF+_NF, RANGE *_RANGE > operator*(const UFix< _NI, _NF, _RANGE > &op) const
Definition: FixMath.h:316
UFix< NF, NI > invFast() const
Definition: FixMath.h:358
internal_type asRaw() const
Definition: FixMath.h:510
UFix< FixMathPrivate::neededNIExtra(FixMathPrivate::FM_max(NI, _NI), FixMathPrivate::FM_max(NF, _NF), FixMathPrivate::rangeAdd(NF, _NF, RANGE, _RANGE)), FixMathPrivate::FM_max(NF, _NF), FixMathPrivate::rangeAdd(NF, _NF, RANGE, _RANGE)> operator+(const UFix< _NI, _NF, _RANGE > &op) const
Definition: FixMath.h:225
Definition: FixMath.h:121
Definition: IntegerType.h:9