@@ -120,7 +120,6 @@ The division is not implemented. This is a deliberate choice made for two reason
120120
121121
122122
123-
124123/* * constexpr functions used internally.
125124*/
126125
@@ -134,6 +133,16 @@ namespace FixMathPrivate {
134133 constexpr uint64_t uFullRange (int8_t N) { return ((uint64_t (1 )<<(N-1 ))-1 ) + (uint64_t (1 )<<(N-1 ));}
135134 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))));} // returns the RANGE following an addition
136135 constexpr uint64_t rangeShift (int8_t N, int8_t SH, uint64_t RANGE) { return ((SH < N) ? (RANGE) : (shiftR (RANGE,(N-SH))));} // make sure that NI or NF does not turn negative when safe shifts are used.
136+
137+ // Helper struct for NIcount(), below. Needed, because C++ does not allow partial specialization of functions
138+ template <uint64_t value, int8_t bits> struct BitCounter {
139+ static constexpr int8_t bitsNeeded () { return (value >= (uint64_t (1 ) << bits) ? bits+1 : (BitCounter<value, bits-1 >::bitsNeeded ())); }
140+ };
141+ template <uint64_t value> struct BitCounter <value, 0 > {
142+ static constexpr int8_t bitsNeeded () { return (value < 1 ? 0 : 1 ); }
143+ };
144+ // Count number of bits needed to represent the constant value (up to 64 bits). Value is specified as template parameter to constrict usage to compile-time evaluation.
145+ template <uint64_t value> constexpr int8_t NIcount () { return BitCounter<value, 63 >::bitsNeeded (); };
137146}
138147
139148// Forward declaration
@@ -144,7 +153,12 @@ class SFix;
144153template <int8_t NI, int8_t NF, uint64_t RANGE=FixMathPrivate::uFullRange(NI+NF)>
145154class UFix ;
146155
147-
156+ namespace FixMathPrivate {
157+ // Alias declaration for a UFix type with the suitable NI count given RANGE and NF
158+ template <int8_t NF, uint64_t RANGE> using UFixByRange_t=UFix<NIcount<RANGE>()-NF, NF, RANGE>;
159+ // Alias declaration for an SFix type with the suitable NI count given RANGE and NF
160+ template <int8_t NF, uint64_t RANGE> using SFixByRange_t=SFix<NIcount<RANGE>()-NF, NF, RANGE>;
161+ }
148162
149163/* * Instanciate an unsigned fixed point math number.
150164 @param NI The number of bits encoding the integer part. The integral part can range into [0, 2^NI -1]
@@ -222,11 +236,10 @@ class UFix
222236 @return The result of the addition as a UFix.
223237 */
224238 template <int8_t _NI, int8_t _NF, uint64_t _RANGE>
225- constexpr typename UFix< FixMathPrivate::FM_max(NI,_NI), FixMathPrivate::FM_max(NF,_NF), FixMathPrivate::rangeAdd(NF,_NF,RANGE,_RANGE)>::UFixNIadj_t operator + (const UFix<_NI,_NF,_RANGE>& op) const // NOTE: C++-11 does not (yet) allow auto return value
239+ constexpr FixMathPrivate::UFixByRange_t< FixMathPrivate::FM_max(NF,_NF), FixMathPrivate::rangeAdd(NF,_NF,RANGE,_RANGE)> operator + (const UFix<_NI,_NF,_RANGE>& op) const // NOTE: C++-11 does not (yet) allow auto return value
226240 {
227- using namespace FixMathPrivate ;
228- typedef UFix<FM_max (NI,_NI), FM_max (NF,_NF), rangeAdd (NF,_NF,RANGE,_RANGE)> temptype; // intermediate type with the correct RANGE, but not necessarily the required NI
229- typedef typename temptype::UFixNIadj_t worktype; // the proper return type, with NI adjusted according the range calculated, above
241+ // Number of NI in return type amy be FM_max(NI, _NI), or FM_max(NI, _NI)+1. Most easily determined from the resulting RANGE
242+ typedef FixMathPrivate::UFixByRange_t<FixMathPrivate::FM_max (NF,_NF), FixMathPrivate::rangeAdd (NF,_NF,RANGE,_RANGE)> worktype;
230243
231244 return worktype (worktype (*this ).asRaw () + worktype (op).asRaw (), true );
232245 }
@@ -236,11 +249,9 @@ class UFix
236249 @return The result of the addition as a SFix.
237250 */
238251 template <int8_t _NI, int8_t _NF, uint64_t _RANGE>
239- constexpr typename SFix< FixMathPrivate::FM_max(NI,_NI), FixMathPrivate::FM_max(NF,_NF), FixMathPrivate::rangeAdd(NF,_NF,RANGE,_RANGE)>::SFixNIadj_t operator + (const SFix<_NI,_NF,_RANGE>& op) const
252+ constexpr FixMathPrivate::SFixByRange_t< FixMathPrivate::FM_max(NF,_NF), FixMathPrivate::rangeAdd(NF,_NF,RANGE,_RANGE)> operator + (const SFix<_NI,_NF,_RANGE>& op) const
240253 {
241- using namespace FixMathPrivate ;
242- typedef SFix<FM_max (NI,_NI), FM_max (NF,_NF), rangeAdd (NF,_NF,RANGE,_RANGE)> temptype;
243- typedef typename temptype::SFixNIadj_t worktype;
254+ typedef FixMathPrivate::SFixByRange_t<FixMathPrivate::FM_max (NF,_NF), FixMathPrivate::rangeAdd (NF,_NF,RANGE,_RANGE)> worktype;
244255
245256 return worktype (worktype (*this ).asRaw () + worktype (op).asRaw (), true );
246257 }
@@ -265,10 +276,10 @@ class UFix
265276 @return The result of the subtraction as a SFix.
266277 */
267278 template <int8_t _NI, int8_t _NF, uint64_t _RANGE> // We do not have the +1 after FixMathPrivate::FM_max(NI, _NI) because the substraction between two UFix should fit in the biggest of the two.
268- constexpr 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
279+ constexpr FixMathPrivate::SFixByRange_t< 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
269280 {
270281 using namespace FixMathPrivate ;
271- typedef SFix< FM_max (NI,_NI), FM_max (NF,_NF), FM_max (shiftR (RANGE,FM_max (NF,_NF)-NF), shiftR (_RANGE,FM_max (NF,_NF)-_NF))> worktype;
282+ typedef SFixByRange_t< FM_max (NF,_NF), FM_max (shiftR (RANGE,FM_max (NF,_NF)-NF), shiftR (_RANGE,FM_max (NF,_NF)-_NF))> worktype;
272283
273284 return worktype (worktype (*this ).asRaw () - worktype (op).asRaw (), true );
274285 }
@@ -279,7 +290,7 @@ class UFix
279290 @return The result of the subtraction of op1 by op2. As a SFix
280291 */
281292 template <int8_t _NI, int8_t _NF, uint64_t _RANGE>
282- constexpr typename SFix< FixMathPrivate::FM_max(NI,_NI), FixMathPrivate::FM_max(NF,_NF),FixMathPrivate::rangeAdd(NF,_NF,RANGE,_RANGE)>::SFixNIadj_t operator - (const SFix<_NI,_NF, _RANGE>& op2) const
293+ constexpr FixMathPrivate::SFixByRange_t< FixMathPrivate::FM_max(NF,_NF), FixMathPrivate::rangeAdd(NF,_NF,RANGE,_RANGE)> operator - (const SFix<_NI,_NF, _RANGE>& op2) const
283294 {
284295 return -op2+(*this );
285296 }
@@ -312,9 +323,9 @@ class UFix
312323 @return The result of the multiplication as a UFix.
313324 */
314325 template <int8_t _NI, int8_t _NF, uint64_t _RANGE>
315- constexpr typename UFix<NI+_NI, NF+_NF, RANGE*_RANGE>::UFixNIadj_t operator * (const UFix<_NI,_NF,_RANGE>& op) const
326+ constexpr FixMathPrivate::UFixByRange_t< NF+_NF, RANGE*_RANGE> operator * (const UFix<_NI,_NF,_RANGE>& op) const
316327 {
317- typedef typename UFix<NI+_NI, NF+_NF, RANGE*_RANGE>::UFixNIadj_t worktype;
328+ typedef FixMathPrivate::UFixByRange_t< NF+_NF, RANGE*_RANGE> worktype;
318329 return worktype ((typename worktype::internal_type) (internal_value)*op.asRaw (), true );
319330 }
320331
@@ -323,9 +334,9 @@ class UFix
323334 @return The result of the multiplication as a SFix.
324335 */
325336 template <int8_t _NI, int8_t _NF, uint64_t _RANGE>
326- constexpr typename SFix<NI+_NI, NF+_NF, RANGE*_RANGE>::SFixNIadj_t operator * (const SFix<_NI,_NF,_RANGE>& op) const
337+ constexpr FixMathPrivate::SFixByRange_t< NF+_NF, RANGE*_RANGE> operator * (const SFix<_NI,_NF,_RANGE>& op) const
327338 {
328- typedef typename SFix<NI+_NI, NF+_NF, RANGE*_RANGE>::SFixNIadj_t worktype;
339+ typedef FixMathPrivate::SFixByRange_t< NF+_NF, RANGE*_RANGE> worktype;
329340 return worktype ((typename worktype::internal_type) (internal_value)*op.asRaw (), true );
330341 }
331342
@@ -561,10 +572,8 @@ class UFix
561572 */
562573 template <int8_t BITS> static constexpr void assertSize () { static_assert (NI+NF <= BITS, " Data type is larger than expected!" ); }
563574private:
564- template <int8_t , int8_t , uint64_t > friend class UFix ; // All sibling specializations shall be friends, too
575+ template <int8_t , int8_t , uint64_t > friend class UFix ; // for access to internal_type
565576 template <int8_t , int8_t , uint64_t > friend class SFix ;
566- static constexpr uint64_t maxRANGE (int8_t delta_bits=0 ) { return ((uint64_t (1 )<<(NI+NF+delta_bits-1 )) - 1 + (uint64_t (1 )<<(NI+NF+delta_bits-1 ))); } // == 1 << NI+NF+delta_bits, but not overflowing at NIF+NF+delta_bits==64
567- typedef UFix<(RANGE > maxRANGE ()) ? NI+1 : (RANGE > maxRANGE (-1 )) ? NI : NI-1, NF, RANGE> UFixNIadj_t;
568577
569578 internal_type internal_value;
570579 // static constexpr internal_type onesbitmask() { return (internal_type) ((1ULL<< (NI+NF)) - 1); }
@@ -678,6 +687,10 @@ constexpr SFix<NI, NF> operator-(double op, const UFix<NI, NF>& uf) {return -uf+
678687 whereas the latter will lead to NF=8. Mozzi's objects (Oscil and the like)
679688 returns correct types, hence you can use this function to convert the return
680689 value of a Mozzi's function/class member into a pure fractional number.
690+
691+ @note If the value is known at compile time, it is much more efficient to
692+ construct using UFixAuto(), and then shifting to the right.
693+
681694 @param val The value to be converted into a pure fractional number.
682695 @return A UFix<0,NF> with NF chosen according to the input type
683696*/
@@ -693,6 +706,10 @@ constexpr inline UFix<0, sizeof(T)*8> toUFraction(T val) {
693706 whereas the latter will lead to NI=8. Mozzi's objects (Oscil and the like)
694707 returns correct types, hence you can use this function to convert the return
695708 value of a Mozzi's function/class member into a pure fractional number.
709+
710+ @note If the value is known at compile time, it is much more efficient to
711+ construct using UFixAuto().
712+
696713 @param val The value to be converted into a pure unsigned integer fixed math number.
697714 @return A UFix<NI,0> with NI chosen according to the input type
698715*/
@@ -701,6 +718,24 @@ constexpr inline UFix<sizeof(T)*8,0> toUInt(T val) {
701718 return UFix<sizeof (T)*8 ,0 >::fromRaw (val);
702719}
703720
721+ /* * Create a pure integer unsigned fix number (UFix) from a compile time constant.
722+ The number of integer bits needed is determined, automatically, based on the actual
723+ value. This allows to easily create constants requiring minimal storage, without
724+ counting bits, manually.
725+
726+ Examples:
727+ @code
728+ auto three = UFixAuto<3>(); // UFix<2, 0>
729+ auto ten_point_five = UFixAuto<21>().sR<1>(); // UFix<5, 1>
730+ auto nearly_Pi = UFixAuto<201>().sR<6>(); // UFix<2, 6> = 3.140625
731+ @endcode
732+ */
733+ // TODO: auto sixteen = UFixAuto<16>(); could be made to return UFix<1, -4>!
734+ template <uint64_t value>
735+ constexpr FixMathPrivate::UFixByRange_t<0 , value> UFixAuto () {
736+ return FixMathPrivate::UFixByRange_t<0 , value>::fromRaw (value);
737+ }
738+
704739
705740
706741/* * Instanciate an signed fixed point math number.
@@ -772,10 +807,9 @@ class SFix
772807 @return The result of the addition as a SFix.
773808 */
774809 template <int8_t _NI, int8_t _NF, uint64_t _RANGE>
775- constexpr typename SFix< FixMathPrivate::FM_max(NI,_NI), FixMathPrivate::FM_max(NF,_NF),FixMathPrivate::rangeAdd(NF,_NF,RANGE,_RANGE)>::SFixNIadj_t operator + (const SFix<_NI,_NF,_RANGE>& op) const
810+ constexpr FixMathPrivate::SFixByRange_t< FixMathPrivate::FM_max(NF,_NF),FixMathPrivate::rangeAdd(NF,_NF,RANGE,_RANGE)> operator + (const SFix<_NI,_NF,_RANGE>& op) const
776811 {
777- using namespace FixMathPrivate ;
778- typedef typename SFix<FM_max (NI,_NI),FM_max (NF,_NF),rangeAdd (NF,_NF,RANGE,_RANGE)>::SFixNIadj_t worktype;
812+ typedef FixMathPrivate::SFixByRange_t<FixMathPrivate::FM_max (NF,_NF),FixMathPrivate::rangeAdd (NF,_NF,RANGE,_RANGE)> worktype;
779813 return worktype (worktype (*this ).asRaw () + worktype (op).asRaw (), true );
780814 }
781815
@@ -785,7 +819,7 @@ class SFix
785819 @return The result of the addition of op1 and op2. As a SFix
786820 */
787821 template <int8_t _NI, int8_t _NF, uint64_t _RANGE>
788- constexpr typename SFix< FixMathPrivate::FM_max(NI,_NI), FixMathPrivate::FM_max(NF,_NF),FixMathPrivate::rangeAdd(NF,_NF,RANGE,_RANGE)>::SFixNIadj_t operator + (const UFix<_NI,_NF,_RANGE>& op2) const
822+ constexpr FixMathPrivate::SFixByRange_t< FixMathPrivate::FM_max(NF,_NF),FixMathPrivate::rangeAdd(NF,_NF,RANGE,_RANGE)> operator + (const UFix<_NI,_NF,_RANGE>& op2) const
789823 {
790824 return op2+(*this );
791825 }
@@ -810,9 +844,9 @@ class SFix
810844 @return The result of the subtraction as a SFix.
811845 */
812846 template <int8_t _NI, int8_t _NF, uint64_t _RANGE>
813- constexpr typename SFix< FixMathPrivate::FM_max(NI,_NI), FixMathPrivate::FM_max(NF,_NF),FixMathPrivate::rangeAdd(NF,_NF,RANGE,_RANGE)>::SFixNIadj_t operator - (const SFix<_NI,_NF, _RANGE>& op) const
847+ constexpr FixMathPrivate::SFixByRange_t< FixMathPrivate::FM_max(NF,_NF),FixMathPrivate::rangeAdd(NF,_NF,RANGE,_RANGE)> operator - (const SFix<_NI,_NF, _RANGE>& op) const
814848 {
815- typedef typename SFix< FixMathPrivate::FM_max (NI,_NI), FixMathPrivate::FM_max (NF,_NF),FixMathPrivate::rangeAdd (NF,_NF,RANGE,_RANGE)>::SFixNIadj_t worktype;
849+ typedef FixMathPrivate::SFixByRange_t< FixMathPrivate::FM_max (NF,_NF),FixMathPrivate::rangeAdd (NF,_NF,RANGE,_RANGE)> worktype;
816850 return worktype (worktype (*this ).asRaw () - worktype (op).asRaw (), true );
817851 }
818852
@@ -821,9 +855,9 @@ class SFix
821855 @return The result of the subtraction as a SFix.
822856 */
823857 template <int8_t _NI, int8_t _NF, uint64_t _RANGE>
824- constexpr typename SFix< FixMathPrivate::FM_max(NI,_NI), FixMathPrivate::FM_max(NF,_NF),FixMathPrivate::rangeAdd(NF,_NF,RANGE,_RANGE)>::SFixNIadj_t operator - (const UFix<_NI,_NF, _RANGE>& op) const
858+ constexpr FixMathPrivate::SFixByRange_t< FixMathPrivate::FM_max(NF,_NF),FixMathPrivate::rangeAdd(NF,_NF,RANGE,_RANGE)> operator - (const UFix<_NI,_NF, _RANGE>& op) const
825859 {
826- typedef typename SFix< FixMathPrivate::FM_max (NI,_NI), FixMathPrivate::FM_max (NF,_NF),FixMathPrivate::rangeAdd (NF,_NF,RANGE,_RANGE)>::SFixNIadj_t worktype;
860+ typedef FixMathPrivate::SFixByRange_t< FixMathPrivate::FM_max (NF,_NF),FixMathPrivate::rangeAdd (NF,_NF,RANGE,_RANGE)> worktype;
827861 return worktype (worktype (*this ).asRaw () - worktype (op).asRaw (), true );
828862 }
829863
@@ -855,9 +889,9 @@ class SFix
855889 @return The result of the multiplication as a SFix.
856890 */
857891 template <int8_t _NI, int8_t _NF, uint64_t _RANGE>
858- constexpr typename SFix<NI+_NI, NF+_NF, RANGE*_RANGE>::SFixNIadj_t operator * (const SFix<_NI,_NF,_RANGE>& op) const
892+ constexpr FixMathPrivate::SFixByRange_t< NF+_NF, RANGE*_RANGE> operator * (const SFix<_NI,_NF,_RANGE>& op) const
859893 {
860- typedef typename SFix<NI+_NI, NF+_NF, RANGE*_RANGE>::SFixNIadj_t worktype;
894+ typedef FixMathPrivate::SFixByRange_t< NF+_NF, RANGE*_RANGE> worktype;
861895 return worktype ((typename worktype::internal_type)(internal_value)*op.asRaw (), true );
862896 }
863897
@@ -867,7 +901,7 @@ class SFix
867901 @return The result of the multiplication of op1 and op2. As a SFix
868902 */
869903 template <int8_t _NI, int8_t _NF, uint64_t _RANGE>
870- constexpr typename SFix<NI+_NI, NF+_NF, RANGE*_RANGE>::SFixNIadj_t operator * (const UFix<_NI,_NF,_RANGE>& op2) const
904+ constexpr FixMathPrivate::SFixByRange_t< NF+_NF, RANGE*_RANGE> operator * (const UFix<_NI,_NF,_RANGE>& op2) const
871905 {
872906 return op2*(*this );
873907 }
@@ -1080,15 +1114,13 @@ class SFix
10801114 */
10811115 template <int8_t BITS> static constexpr void assertSize () { static_assert (NI+NF+1 <= BITS, " Data type is larger than expected!" ); }
10821116private:
1083- template <int8_t , int8_t , uint64_t > friend class UFix ; // for access to UFixNIadj_t
1117+ template <int8_t , int8_t , uint64_t > friend class UFix ; // for access to internal_type
10841118 template <int8_t , int8_t , uint64_t > friend class SFix ;
1085- static constexpr uint64_t maxRANGE (int8_t delta_bits=0 ) { return (uint64_t (1 )<<(NI+NF+delta_bits)); } // no -1 for signed, because negative number actually extend to -2^n, not just 2^n-1
1086- typedef SFix<(RANGE > maxRANGE ()) ? NI+1 : (RANGE > maxRANGE (-1 )) ? NI : NI-1, NF, RANGE> SFixNIadj_t;
10871119
10881120 internal_type internal_value;
10891121 // static constexpr internal_type onesbitmask() { return (internal_type) ((1ULL<< (NI+NF)) - 1); }
10901122 static constexpr internal_type onesbitmask () { return (internal_type) ((1ULL << (NI+NF-1 )) + ((1ULL << (NI+NF-1 )) - 1 )); }
1091- static constexpr internal_type msbone () { return (internal_type) (1ULL << (NI+NF-1 )); }
1123+ static constexpr internal_type msbone () { return (internal_type) (1ULL << (NI+NF-1 )); }
10921124};
10931125
10941126
@@ -1295,14 +1327,18 @@ constexpr bool operator!= (const UFix<NI,NF>& op1, const SFix<_NI,_NF>& op2 )
12951327// //// Helper functions to build SFix from a normal type automatically
12961328
12971329
1298- /* * Create a *pure* fractional signed fixed number (SFix) from a integer.
1330+ /* * Create a *pure* fractional signed fixed number (SFix) from an integer.
12991331 The number of fractional bits (NF) is chosen automatically depending on the input
13001332 type. Hence toSFraction(127) and toSFraction(int8_t(127)) *do not* lead to the
13011333 same thing: on an AVR, the former will lead to NF=15 - which is overkill and
13021334 incorrect if you expect toSFraction(127) = 1 -
13031335 whereas the latter will lead to NF=7. Mozzi's objects (Oscil and the like)
13041336 returns correct types, hence you can use this function to convert the return
13051337 value of a Mozzi's function/class member into a pure fractional number.
1338+
1339+ @note If the value is known at compile time, it is much more efficient to
1340+ construct using SFixAuto(), and then shifting to the right.
1341+
13061342 @param val The value to be converted into a pure fractional number.
13071343 @return A SFix<0,NF> with NF chosen according to the input type
13081344*/
@@ -1311,13 +1347,17 @@ constexpr SFix<0, sizeof(T)*8-1> toSFraction(T val) {
13111347 return SFix<0 , sizeof (T)*8 -1 >::fromRaw (val);
13121348}
13131349
1314- /* * Create a *pure* integer signed fixed number (SFix) from a integer.
1350+ /* * Create a *pure* integer signed fixed number (SFix) from an integer.
13151351 The number of fractional bits (NI) is chosen automatically depending on the input
13161352 type. Hence toSInt(127) and toSInt(int8_t(127)) *do not* lead to the
13171353 same thing: on an AVR, the former will lead to NI=15 - which is overkill -
13181354 whereas the latter will lead to NI=7. Mozzi's objects (Oscil and the like)
13191355 returns correct types, hence you can use this function to convert the return
13201356 value of a Mozzi's function/class member into a pure fractional number.
1357+
1358+ @note If the value is known at compile time, it is much more efficient to
1359+ construct using SFixAuto().
1360+
13211361 @param val The value to be converted into a pure integer fixed math number.
13221362 @return A SFix<NI,0> with NI chosen according to the input type
13231363*/
@@ -1326,7 +1366,22 @@ constexpr SFix<sizeof(T)*8-1,0> toSInt(T val) {
13261366 return SFix<sizeof (T)*8 -1 ,0 >::fromRaw (val);
13271367}
13281368
1329-
1369+ /* * Create a pure integer signed fix number (SFix) from a compile time constant.
1370+ The number of integer bits needed is determined, automatically, based on the actual
1371+ value. This allows to easily create constants requiring minimal storage, without
1372+ counting bits, manually.
1373+
1374+ Examples:
1375+ @code
1376+ auto neg_three = SFixAuto<-3>(); // SFix<2, 0>
1377+ auto ten_point_five = SFixAuto<21>().sR<1>(); // SFix<5, 1>, but consider using
1378+ // UFixAuto() for positive values!
1379+ @endcode
1380+ */
1381+ template <int64_t value>
1382+ constexpr const FixMathPrivate::SFixByRange_t<0 , value < 0 ? -value : value> SFixAuto () {
1383+ return FixMathPrivate::SFixByRange_t<0 , value < 0 ? -value : value>::fromRaw (value);
1384+ }
13301385
13311386#include " FixMath_Autotests.h"
13321387
0 commit comments