@@ -106,7 +106,12 @@ class rational {
106
106
constexpr rational (signed char initial_value) { *this = initial_value; }
107
107
constexpr rational (short initial_value) { *this = initial_value; }
108
108
constexpr rational (int initial_value) { *this = initial_value; }
109
+ constexpr rational (long initial_value) { *this = initial_value; }
109
110
constexpr rational (long long initial_value) { *this = initial_value; }
111
+ constexpr rational (unsigned char initial_value) { *this = initial_value; }
112
+ constexpr rational (unsigned short initial_value) { *this = initial_value; }
113
+ constexpr rational (unsigned int initial_value) { *this = initial_value; }
114
+ constexpr rational (unsigned long initial_value) { *this = initial_value; }
110
115
constexpr rational (unsigned long long initial_value) { *this = initial_value; }
111
116
constexpr rational (float initial_value) { *this = initial_value; }
112
117
constexpr rational (double initial_value) { *this = initial_value; }
@@ -115,17 +120,23 @@ class rational {
115
120
constexpr rational& operator =(signed char rhs) { return convert_signed (rhs); }
116
121
constexpr rational& operator =(short rhs) { return convert_signed (rhs); }
117
122
constexpr rational& operator =(int rhs) { return convert_signed (rhs); }
123
+ constexpr rational& operator =(long rhs) { return convert_signed (rhs); }
118
124
constexpr rational& operator =(long long rhs) { return convert_signed (rhs); }
125
+ constexpr rational& operator =(unsigned char rhs) { return convert_unsigned (rhs); }
126
+ constexpr rational& operator =(unsigned short rhs) { return convert_unsigned (rhs); }
127
+ constexpr rational& operator =(unsigned int rhs) { return convert_unsigned (rhs); }
128
+ constexpr rational& operator =(unsigned long rhs) { return convert_unsigned (rhs); }
119
129
constexpr rational& operator =(unsigned long long rhs) { return convert_unsigned (rhs); }
120
130
constexpr rational& operator =(float rhs) { return convert_ieee754 (rhs); }
121
131
constexpr rational& operator =(double rhs) { return convert_ieee754 (rhs); }
122
132
123
133
// explicit conversion operators
124
- // explicit conversion operators
134
+ explicit operator char () const noexcept { return to_unsigned< char >(); }
125
135
explicit operator unsigned short () const noexcept { return to_unsigned<unsigned short >(); }
126
136
explicit operator unsigned int () const noexcept { return to_unsigned<unsigned int >(); }
127
137
explicit operator unsigned long () const noexcept { return to_unsigned<unsigned long >(); }
128
138
explicit operator unsigned long long () const noexcept { return to_unsigned<unsigned long long >(); }
139
+ explicit operator signed char () const noexcept { return to_signed<signed char >(); }
129
140
explicit operator short () const noexcept { return to_signed<short >(); }
130
141
explicit operator int () const noexcept { return to_signed<int >(); }
131
142
explicit operator long () const noexcept { return to_signed<long >(); }
@@ -149,6 +160,8 @@ class rational {
149
160
// increment and decrement operators are not defined for rational
150
161
151
162
// in-place arithmetic assignment operators
163
+
164
+ // in-place addition
152
165
rational& operator +=(const rational& rhs) {
153
166
SignedBlockBinary x = n;
154
167
SignedBlockBinary y = d;
@@ -167,27 +180,79 @@ class rational {
167
180
normalize ();
168
181
return *this ;
169
182
}
170
- rational& operator +=(double rhs) { return *this += rational (rhs); }
183
+ rational& operator +=(unsigned short rhs) { return *this += rational (rhs); }
184
+ rational& operator +=(unsigned int rhs) { return *this += rational (rhs); }
185
+ rational& operator +=(unsigned long rhs) { return *this += rational (rhs); }
186
+ rational& operator +=(unsigned long long rhs) { return *this += rational (rhs); }
187
+ rational& operator +=(short rhs) { return *this += rational (rhs); }
188
+ rational& operator +=(int rhs) { return *this += rational (rhs); }
189
+ rational& operator +=(long rhs) { return *this += rational (rhs); }
190
+ rational& operator +=(long long rhs) { return *this += rational (rhs); }
191
+ rational& operator +=(float rhs) { return *this += rational (rhs); }
192
+ rational& operator +=(double rhs) { return *this += rational (rhs); }
193
+ // in-place subtraction
171
194
rational& operator -=(const rational& rhs) {
172
-
173
- normalize ();
195
+ SignedBlockBinary x = n;
196
+ SignedBlockBinary y = d;
197
+ SignedBlockBinary v = rhs.n ;
198
+ SignedBlockBinary w = rhs.d ;
199
+ if (y == w) {
200
+ SignedBlockBinary num = x - v;
201
+ n = num;
202
+ }
203
+ else {
204
+ SignedBlockBinary e = x * w - y * v;
205
+ SignedBlockBinary f = y * w;
206
+ n = e;
207
+ d = f;
208
+ }
209
+ normalize ();
174
210
return *this ;
175
211
}
176
- rational& operator -=(double rhs) { return *this -= rational<nbits,bt>(rhs); }
212
+ rational& operator -=(unsigned short rhs) { return *this -= rational (rhs); }
213
+ rational& operator -=(unsigned int rhs) { return *this -= rational (rhs); }
214
+ rational& operator -=(unsigned long rhs) { return *this -= rational (rhs); }
215
+ rational& operator -=(unsigned long long rhs) { return *this -= rational (rhs); }
216
+ rational& operator -=(short rhs) { return *this -= rational (rhs); }
217
+ rational& operator -=(int rhs) { return *this -= rational (rhs); }
218
+ rational& operator -=(long rhs) { return *this -= rational (rhs); }
219
+ rational& operator -=(long long rhs) { return *this -= rational (rhs); }
220
+ rational& operator -=(float rhs) { return *this -= rational (rhs); }
221
+ rational& operator -=(double rhs) { return *this -= rational (rhs); }
222
+ // in-place multiplication
177
223
rational& operator *=(const rational& rhs) {
178
224
n *= rhs.n ;
179
225
d *= rhs.d ;
180
226
normalize ();
181
227
return *this ;
182
228
}
183
- rational& operator *=(double rhs) { return *this *= rational<nbits,bt>(rhs); }
184
- rational& operator /=(const rational& rhs) {
229
+ rational& operator *=(unsigned short rhs) { return *this *= rational (rhs); }
230
+ rational& operator *=(unsigned int rhs) { return *this *= rational (rhs); }
231
+ rational& operator *=(unsigned long rhs) { return *this *= rational (rhs); }
232
+ rational& operator *=(unsigned long long rhs) { return *this *= rational (rhs); }
233
+ rational& operator *=(short rhs) { return *this *= rational (rhs); }
234
+ rational& operator *=(int rhs) { return *this *= rational (rhs); }
235
+ rational& operator *=(long rhs) { return *this *= rational (rhs); }
236
+ rational& operator *=(long long rhs) { return *this *= rational (rhs); }
237
+ rational& operator *=(float rhs) { return *this *= rational (rhs); }
238
+ rational& operator *=(double rhs) { return *this *= rational (rhs); }
239
+ // in-place division
240
+ rational& operator /=(const rational& rhs) {
185
241
n *= rhs.d ;
186
242
d *= rhs.n ;
187
243
normalize ();
188
244
return *this ;
189
245
}
190
- rational& operator /=(double rhs) { return *this /= rational<nbits,bt>(rhs); }
246
+ rational& operator /=(unsigned short rhs) { return *this /= rational (rhs); }
247
+ rational& operator /=(unsigned int rhs) { return *this /= rational (rhs); }
248
+ rational& operator /=(unsigned long rhs) { return *this /= rational (rhs); }
249
+ rational& operator /=(unsigned long long rhs) { return *this /= rational (rhs); }
250
+ rational& operator /=(short rhs) { return *this /= rational (rhs); }
251
+ rational& operator /=(int rhs) { return *this /= rational (rhs); }
252
+ rational& operator /=(long rhs) { return *this /= rational (rhs); }
253
+ rational& operator /=(long long rhs) { return *this /= rational (rhs); }
254
+ rational& operator /=(float rhs) { return *this /= rational (rhs); }
255
+ rational& operator /=(double rhs) { return *this /= rational (rhs); }
191
256
192
257
// modifiers
193
258
constexpr void clear () noexcept { n = 0 ; d = 1 ; }
@@ -266,8 +331,13 @@ class rational {
266
331
a = b;
267
332
b = r;
268
333
}
269
- n /= (sign ? -b : b);
270
- d /= (dsign ? -b : b);
334
+ n /= b;
335
+ d /= b;
336
+ if (sign && dsign) {
337
+ // move the sign to the numerator
338
+ n = -n; d = -d;
339
+ }
340
+
271
341
}
272
342
273
343
// //////////////////////////////////////////////////////////////////////////////////////////
@@ -382,7 +452,7 @@ class rational {
382
452
uint64_t maxDownShift = find_msb (b);
383
453
uint64_t scale = static_cast <uint64_t >(exponent);
384
454
if (scale > maxUpShift) {
385
- if (maxUpShift < (scale - maxDownShift)) {
455
+ if (scale > (maxUpShift + maxDownShift)) {
386
456
// overflow, saturate to maxpos
387
457
std::cerr << " overflow: scale = " << exponent << ' \n ' ;
388
458
maxpos ();
@@ -524,27 +594,86 @@ inline rational<nbits, bt> operator+(const rational<nbits, bt>& lhs, const ratio
524
594
sum += rhs;
525
595
return sum;
526
596
}
597
+ template <unsigned nbits, typename bt> inline rational<nbits, bt> operator +(const rational<nbits, bt>& lhs, signed char rhs) { return lhs + rational<nbits, bt>(rhs); }
598
+ template <unsigned nbits, typename bt> inline rational<nbits, bt> operator +(const rational<nbits, bt>& lhs, short rhs) { return lhs + rational<nbits, bt>(rhs); }
599
+ template <unsigned nbits, typename bt> inline rational<nbits, bt> operator +(const rational<nbits, bt>& lhs, int rhs) { return lhs + rational<nbits, bt>(rhs); }
600
+ template <unsigned nbits, typename bt> inline rational<nbits, bt> operator +(const rational<nbits, bt>& lhs, long rhs) { return lhs + rational<nbits, bt>(rhs); }
601
+ template <unsigned nbits, typename bt> inline rational<nbits, bt> operator +(const rational<nbits, bt>& lhs, long long rhs) { return lhs + rational<nbits, bt>(rhs); }
602
+ template <unsigned nbits, typename bt> inline rational<nbits, bt> operator +(const rational<nbits, bt>& lhs, float rhs) { return lhs + rational<nbits, bt>(rhs); }
603
+ template <unsigned nbits, typename bt> inline rational<nbits, bt> operator +(const rational<nbits, bt>& lhs, double rhs) { return lhs + rational<nbits, bt>(rhs); }
604
+ template <unsigned nbits, typename bt> inline rational<nbits, bt> operator +(signed char lhs, const rational<nbits, bt>& rhs) { return rational<nbits, bt>(lhs) + rhs; }
605
+ template <unsigned nbits, typename bt> inline rational<nbits, bt> operator +(short lhs, const rational<nbits, bt>& rhs) { return rational<nbits, bt>(lhs) + rhs; }
606
+ template <unsigned nbits, typename bt> inline rational<nbits, bt> operator +(int lhs, const rational<nbits, bt>& rhs) { return rational<nbits, bt>(lhs) + rhs; }
607
+ template <unsigned nbits, typename bt> inline rational<nbits, bt> operator +(long lhs, const rational<nbits, bt>& rhs) { return rational<nbits, bt>(lhs) + rhs; }
608
+ template <unsigned nbits, typename bt> inline rational<nbits, bt> operator +(long long lhs, const rational<nbits, bt>& rhs) { return rational<nbits, bt>(lhs) + rhs; }
609
+ template <unsigned nbits, typename bt> inline rational<nbits, bt> operator +(float lhs, const rational<nbits, bt>& rhs) { return rational<nbits, bt>(lhs) + rhs; }
610
+ template <unsigned nbits, typename bt> inline rational<nbits, bt> operator +(double lhs, const rational<nbits, bt>& rhs) { return rational<nbits, bt>(lhs) + rhs; }
611
+
527
612
// BINARY SUBTRACTION
528
613
template <unsigned nbits, typename bt>
529
614
inline rational<nbits, bt> operator -(const rational<nbits, bt>& lhs, const rational<nbits, bt>& rhs) {
530
615
rational<nbits,bt> diff (lhs);
531
616
diff -= rhs;
532
617
return diff;
533
618
}
619
+ template <unsigned nbits, typename bt> inline rational<nbits, bt> operator -(const rational<nbits, bt>& lhs, signed char rhs) { return lhs - rational<nbits, bt>(rhs); }
620
+ template <unsigned nbits, typename bt> inline rational<nbits, bt> operator -(const rational<nbits, bt>& lhs, short rhs) { return lhs - rational<nbits, bt>(rhs); }
621
+ template <unsigned nbits, typename bt> inline rational<nbits, bt> operator -(const rational<nbits, bt>& lhs, int rhs) { return lhs - rational<nbits, bt>(rhs); }
622
+ template <unsigned nbits, typename bt> inline rational<nbits, bt> operator -(const rational<nbits, bt>& lhs, long rhs) { return lhs - rational<nbits, bt>(rhs); }
623
+ template <unsigned nbits, typename bt> inline rational<nbits, bt> operator -(const rational<nbits, bt>& lhs, long long rhs) { return lhs - rational<nbits, bt>(rhs); }
624
+ template <unsigned nbits, typename bt> inline rational<nbits, bt> operator -(const rational<nbits, bt>& lhs, float rhs) { return lhs - rational<nbits, bt>(rhs); }
625
+ template <unsigned nbits, typename bt> inline rational<nbits, bt> operator -(const rational<nbits, bt>& lhs, double rhs) { return lhs - rational<nbits, bt>(rhs); }
626
+ template <unsigned nbits, typename bt> inline rational<nbits, bt> operator -(signed char lhs, const rational<nbits, bt>& rhs) { return rational<nbits, bt>(lhs) - rhs; }
627
+ template <unsigned nbits, typename bt> inline rational<nbits, bt> operator -(short lhs, const rational<nbits, bt>& rhs) { return rational<nbits, bt>(lhs) - rhs; }
628
+ template <unsigned nbits, typename bt> inline rational<nbits, bt> operator -(int lhs, const rational<nbits, bt>& rhs) { return rational<nbits, bt>(lhs) - rhs; }
629
+ template <unsigned nbits, typename bt> inline rational<nbits, bt> operator -(long lhs, const rational<nbits, bt>& rhs) { return rational<nbits, bt>(lhs) - rhs; }
630
+ template <unsigned nbits, typename bt> inline rational<nbits, bt> operator -(long long lhs, const rational<nbits, bt>& rhs) { return rational<nbits, bt>(lhs) - rhs; }
631
+ template <unsigned nbits, typename bt> inline rational<nbits, bt> operator -(float lhs, const rational<nbits, bt>& rhs) { return rational<nbits, bt>(lhs) - rhs; }
632
+ template <unsigned nbits, typename bt> inline rational<nbits, bt> operator -(double lhs, const rational<nbits, bt>& rhs) { return rational<nbits, bt>(lhs) - rhs; }
633
+
534
634
// BINARY MULTIPLICATION
535
635
template <unsigned nbits, typename bt>
536
636
inline rational<nbits, bt> operator *(const rational<nbits, bt>& lhs, const rational<nbits, bt>& rhs) {
537
637
rational<nbits,bt> mul (lhs);
538
638
mul *= rhs;
539
639
return mul;
540
640
}
641
+ template <unsigned nbits, typename bt> inline rational<nbits, bt> operator *(const rational<nbits, bt>& lhs, signed char rhs) { return lhs * rational<nbits, bt>(rhs); }
642
+ template <unsigned nbits, typename bt> inline rational<nbits, bt> operator *(const rational<nbits, bt>& lhs, short rhs) { return lhs * rational<nbits, bt>(rhs); }
643
+ template <unsigned nbits, typename bt> inline rational<nbits, bt> operator *(const rational<nbits, bt>& lhs, int rhs) { return lhs * rational<nbits, bt>(rhs); }
644
+ template <unsigned nbits, typename bt> inline rational<nbits, bt> operator *(const rational<nbits, bt>& lhs, long rhs) { return lhs * rational<nbits, bt>(rhs); }
645
+ template <unsigned nbits, typename bt> inline rational<nbits, bt> operator *(const rational<nbits, bt>& lhs, long long rhs) { return lhs * rational<nbits, bt>(rhs); }
646
+ template <unsigned nbits, typename bt> inline rational<nbits, bt> operator *(const rational<nbits, bt>& lhs, float rhs) { return lhs * rational<nbits, bt>(rhs); }
647
+ template <unsigned nbits, typename bt> inline rational<nbits, bt> operator *(const rational<nbits, bt>& lhs, double rhs) { return lhs * rational<nbits, bt>(rhs); }
648
+ template <unsigned nbits, typename bt> inline rational<nbits, bt> operator *(signed char lhs, const rational<nbits, bt>& rhs) { return rational<nbits, bt>(lhs) * rhs; }
649
+ template <unsigned nbits, typename bt> inline rational<nbits, bt> operator *(short lhs, const rational<nbits, bt>& rhs) { return rational<nbits, bt>(lhs) * rhs; }
650
+ template <unsigned nbits, typename bt> inline rational<nbits, bt> operator *(int lhs, const rational<nbits, bt>& rhs) { return rational<nbits, bt>(lhs) * rhs; }
651
+ template <unsigned nbits, typename bt> inline rational<nbits, bt> operator *(long lhs, const rational<nbits, bt>& rhs) { return rational<nbits, bt>(lhs) * rhs; }
652
+ template <unsigned nbits, typename bt> inline rational<nbits, bt> operator *(long long lhs, const rational<nbits, bt>& rhs) { return rational<nbits, bt>(lhs) * rhs; }
653
+ template <unsigned nbits, typename bt> inline rational<nbits, bt> operator *(float lhs, const rational<nbits, bt>& rhs) { return rational<nbits, bt>(lhs)* rhs; }
654
+ template <unsigned nbits, typename bt> inline rational<nbits, bt> operator *(double lhs, const rational<nbits, bt>& rhs) { return rational<nbits, bt>(lhs)* rhs; }
655
+
541
656
// BINARY DIVISION
542
657
template <unsigned nbits, typename bt>
543
658
inline rational<nbits, bt> operator /(const rational<nbits, bt>& lhs, const rational<nbits, bt>& rhs) {
544
659
rational<nbits,bt> ratio (lhs);
545
660
ratio /= rhs;
546
661
return ratio;
547
662
}
663
+ template <unsigned nbits, typename bt> inline rational<nbits, bt> operator /(const rational<nbits, bt>& lhs, signed char rhs) { return lhs / rational<nbits, bt>(rhs); }
664
+ template <unsigned nbits, typename bt> inline rational<nbits, bt> operator /(const rational<nbits, bt>& lhs, short rhs) { return lhs / rational<nbits, bt>(rhs); }
665
+ template <unsigned nbits, typename bt> inline rational<nbits, bt> operator /(const rational<nbits, bt>& lhs, int rhs) { return lhs / rational<nbits, bt>(rhs); }
666
+ template <unsigned nbits, typename bt> inline rational<nbits, bt> operator /(const rational<nbits, bt>& lhs, long rhs) { return lhs / rational<nbits, bt>(rhs); }
667
+ template <unsigned nbits, typename bt> inline rational<nbits, bt> operator /(const rational<nbits, bt>& lhs, long long rhs) { return lhs / rational<nbits, bt>(rhs); }
668
+ template <unsigned nbits, typename bt> inline rational<nbits, bt> operator /(const rational<nbits, bt>& lhs, float rhs) { return lhs / rational<nbits, bt>(rhs); }
669
+ template <unsigned nbits, typename bt> inline rational<nbits, bt> operator /(const rational<nbits, bt>& lhs, double rhs) { return lhs / rational<nbits, bt>(rhs); }
670
+ template <unsigned nbits, typename bt> inline rational<nbits, bt> operator /(signed char lhs, const rational<nbits, bt>& rhs) { return rational<nbits, bt>(lhs) / rhs; }
671
+ template <unsigned nbits, typename bt> inline rational<nbits, bt> operator /(short lhs, const rational<nbits, bt>& rhs) { return rational<nbits, bt>(lhs) / rhs; }
672
+ template <unsigned nbits, typename bt> inline rational<nbits, bt> operator /(int lhs, const rational<nbits, bt>& rhs) { return rational<nbits, bt>(lhs) / rhs; }
673
+ template <unsigned nbits, typename bt> inline rational<nbits, bt> operator /(long lhs, const rational<nbits, bt>& rhs) { return rational<nbits, bt>(lhs) / rhs; }
674
+ template <unsigned nbits, typename bt> inline rational<nbits, bt> operator /(long long lhs, const rational<nbits, bt>& rhs) { return rational<nbits, bt>(lhs) / rhs; }
675
+ template <unsigned nbits, typename bt> inline rational<nbits, bt> operator /(float lhs, const rational<nbits, bt>& rhs) { return rational<nbits, bt>(lhs) / rhs; }
676
+ template <unsigned nbits, typename bt> inline rational<nbits, bt> operator /(double lhs, const rational<nbits, bt>& rhs) { return rational<nbits, bt>(lhs) / rhs; }
548
677
549
678
// ///////////////////////////////////////////////////////////////////////////////////////////////////////
550
679
// / math functions
0 commit comments