Documentation of CSL
precision_float.h
Go to the documentation of this file.
1 // This file is part of MARTY.
2 //
3 // MARTY is free software: you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation, either version 3 of the License, or
6 // (at your option) any later version.
7 //
8 // MARTY is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // GNU General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License
14 // along with MARTY. If not, see <https://www.gnu.org/licenses/>.
15 
23 #ifndef PRECISION_FLOAT_H_INCLUDED
24 #define PRECISION_FLOAT_H_INCLUDED
25 
26 #include "precision_int.h"
27 #include "floatFormatter.h"
28 #include <algorithm>
29 
30 namespace csl {
31 
32 const int maxMantisseSize = 64;
33 
34 std::pair<int_ap<2>, int> decomposeLongFloat(long double number);
35 
36 template<size_t base>
37 float_sap<base> decomposeLongFloat(long double number)
38 {
39  std::pair<int_ap<2>, int> res = decomposeLongFloat(number);
40  int_ap<base> convertedMantissa = res.first.convert<base>();
41  int exponent = res.second - res.first.size();
42 
43  float_sap<base> baseFactor;
44  int_ap<base> baseNum(1), baseDenom(1);
45  if (exponent > 0) {
46  baseDenom = int_ap(1);
47  baseNum = pow(int_ap<base>(2), int_ap<base>(exponent));
48  }
49  else if (exponent < 0){
50  baseNum = int_ap(1);
51  baseDenom = pow(int_ap<base>(2), int_ap<base>(-exponent));
52  }
53  int_ap<base> baseMantissa, baseExponent;
54  dividePrecision(baseNum, baseDenom, baseMantissa, baseExponent);
55  baseFactor = float_sap<base>(baseMantissa, baseExponent);
56  float_sap<base> result(convertedMantissa,
57  int_ap<base>(convertedMantissa.size())-1);
58  result *= baseFactor;
59  return result;
60 }
61 
62 template<size_t base>
63 class float_sap {
64 
65  public:
66 
67  int_ap<base> mantissa;
68 
69  int_ap<base> exponent;
70 
71  public:
72 
73  float_sap();
74 
75  explicit
76  float_sap(long double value);
77 
78  explicit
79  float_sap(const std::vector<short>& t_digits);
80 
81  float_sap(bool t_minusSign,
82  const std::vector<short>& t_digits,
83  const int_ap<base>& t_exponent);
84 
85  float_sap(const int_ap<base>& t_mantissa,
86  const int_ap<base>& t_exponent);
87 
88  float_sap(const int_ap<base>& other);
89 
90  ~float_sap(){};
91 
92  float_sap<base>& operator=(long double value);
93 
94  float_sap<base>& operator=(const float_sap<base>& value);
95 
96  float_sap<base>& format(std::string const& f);
97 
98  bool getMinusSign() const;
99 
100  void setMinusSign(bool t_sign);
101 
102  void adjustOnExponent(const float_sap<base>& number);
103 
104  void adjustOnExponent(const int_ap<base>& t_exponent);
105 
106  private:
107 
108  int_ap<base> getFloatingPointPos() const;
109 
110  friend
111  float_sap<base> abs(const float_sap<base>& a)
112  {
113  float_sap<base> copy = a;
114  copy.setMinusSign(false);
115  return copy;
116  }
117 
118  friend
119  float_sap<base> floor(const float_sap<base>& a)
120  {
121  if (a.exponent < 1) {
122  if (a.getMinusSign())
123  return -float_sap<base>(1);
124  return float_sap<base>(0);
125  }
126  int_ap<base> nDigits = a.exponent;
127  if (a.exponent > a.mantissa.size())
128  nDigits = a.mantissa.size();
129  std::vector<short> digits(a.mantissa.digits.rend()-nDigits,
130  a.mantissa.digits.rend());
131  if (a.getMinusSign()) {
132  return int_ap<base>(true, digits) - 1;
133  }
134  else
135  return int_ap<base>(digits);
136  }
137 
138  friend
139  float_sap<base> ceil(const float_sap<base>& a)
140  {
141  if (a.exponent >= a.mantissa.size()) {
142  std::vector<short> digits(a.exponent.toCInteger(), 0);
143  for (int i = 0; i != a.mantissa.size(); ++i)
144  digits[i] = a.mantissa[i];
145  return int_ap<base>(a.getMinusSign(), digits);
146  }
147  return 1 + floor(a);
148  }
149 
150  friend
151  float_sap<base> round(const float_sap<base>& a)
152  {
153  if (a.exponent >= a.mantissa.size())
154  return floor(a);
155  short firstDigit = a.mantissa[a.exponent.toCInteger()];
156  if (firstDigit > base/2)
157  return ceil(a);
158  return floor(a);
159  }
160 
161  friend
162  std::ostream& operator<<(std::ostream& fout, const float_sap<base>& floating)
163  {
164  csl::format f = csl::Formatter::getFormat();
165  if (floating.getMinusSign())
166  fout << "-";
167  if (base == 16)
168  fout << "0x";
169  if (f.isScientific()) {
170  fout << convertDigit(floating.mantissa[
171  floating.mantissa.size()-1]) << ".";
172  for (size_t i = 1; i != floating.mantissa.size(); ++i)
173  if (i > f.getMaxDigits())
174  break;
175  else
176  fout << floating.mantissa[
177  floating.mantissa.size()-i-1];
178  fout << " x " << base << "^" << floating.exponent - 1;
179 
180  return fout;
181  }
182  if (floating.exponent <= 0) {
183  fout << "0.";
184  int nDigits = 0;
185  for (int i = 0; i != abs(floating.exponent.toCInteger()); ++i) {
186  if (i > f.getMaxDigits())
187  break;
188  fout << "0";
189  ++nDigits;
190  }
191  if (nDigits > f.getMaxDigits())
192  return fout;
193  for (size_t i = 0; i != floating.mantissa.size(); ++i)
194  if (i + nDigits > f.getMaxDigits())
195  break;
196  else
197  fout << convertDigit(floating.mantissa[
198  floating.mantissa.size()-i-1]);
199  return fout;
200  }
201  int nDigits = 0;
202  bool floatingPoint = false;
203  for (size_t i = 0; i != floating.mantissa.size(); ++i) {
204  if (i == floating.exponent) {
205  floatingPoint = true;
206  fout << ".";
207  }
208  if (floatingPoint) {
209  if (nDigits > f.getMaxDigits())
210  return fout;
211  ++nDigits;
212  fout << convertDigit(floating.mantissa[
213  floating.mantissa.size()-i-1]);
214  }
215  else
216  fout << convertDigit(floating.mantissa[
217  floating.mantissa.size()-1-i]);
218  }
219 
220  return fout;
221  }
222 
223  friend
224  float_sap<base> operator+(long long int a, const float_sap<base>& b)
225  {
226  return float_sap<base>(a)+b;
227  }
228 
229  friend
230  float_sap<base> operator+(const float_sap<base>& a, long long int b)
231  {
232  return a+float_sap<base>(b);
233  }
234 
235  friend
236  float_sap<base> operator+(const float_sap<base>& a, const float_sap<base>& b)
237  {
238  float_sap<base> c = a;
239  return c += b;
240  }
241 
242  friend
244  {
245  int diff;
246  if (a.exponent > b.exponent) {
247  diff = (a.exponent - b.exponent
248  - (a.mantissa.size() - b.mantissa.size())).toCInteger();
249  }
250  else if (b.exponent > a.exponent) {
251  diff = (b.exponent - a.exponent
252  - (b.mantissa.size() - a.mantissa.size())).toCInteger();
253  }
254  else
255  diff = 0;
256  if (diff > 0)
257  a.mantissa.shiftLeft(diff);
258  else
259  b.mantissa.shiftLeft(-diff);
260  int_ap<base> newMantissa = a.mantissa + b.mantissa;
261  a.exponent += (newMantissa.size() - a.mantissa.size());
262  a.mantissa = newMantissa;
263  return a;
264  }
265 
266  friend
267  float_sap<base>& operator+=(float_sap<base>& a, long long int b)
268  {
269  return a += float_sap<base>(b);
270  }
271 
272  friend
273  float_sap<base> operator-(long long int a, const float_sap<base>& b)
274  {
275  return float_sap<base>(a) - b;
276  }
277 
278  friend
279  float_sap<base> operator-(const float_sap<base>& a, long long int b)
280  {
281  return a - float_sap<base>(b);
282  }
283 
284  friend
285  float_sap<base> operator-(const float_sap<base>& a, const float_sap<base>& b)
286  {
287  float_sap<base> c = a;
288  return c -= b;
289  }
290 
291  friend
293  {
294  return a += -b;
295  }
296 
297  friend
298  float_sap<base>& operator-=(float_sap<base>& a, long long int b)
299  {
300  return a -= float_sap<base>(b);
301  }
302 
303  friend
304  float_sap<base> operator++(float_sap<base>& a, int)
305  {
306  float_sap<base> b = a;
307  a += 1;
308  return b;
309  }
310 
311  friend
312  float_sap<base>& operator++(float_sap<base>& a)
313  {
314  a += 1;
315  return a;
316  }
317 
318  friend
319  float_sap<base> operator--(float_sap<base>& a, int)
320  {
321  float_sap<base> b = a;
322  a -= 1;
323  return b;
324  }
325 
326  friend
327  float_sap<base>& operator--(float_sap<base>& a)
328  {
329  a -= 1;
330  return a;
331  }
332 
333  friend
334  float_sap<base> operator-(const float_sap<base>& a)
335  {
336  float_sap<base> b = a;
337  b.setMinusSign(not a.getMinusSign());
338  return b;
339  }
340 
341  friend
342  float_sap<base> operator*(long long int a, const float_sap<base>& b)
343  {
344  return float_sap<base>(a)*b;
345  }
346 
347  friend
348  float_sap<base> operator*(const float_sap<base>& a, long long int b)
349  {
350  return a*float_sap<base>(b);
351  }
352 
353  friend
354  float_sap<base> operator*(const float_sap<base>& a, const float_sap<base>& b)
355  {
356  float_sap<base> c = a;
357  return c *= b;
358  }
359 
360  friend
361  float_sap<base>& operator*=(float_sap<base>& a, long long int b)
362  {
363  return a *= float_sap<base>(b);
364  }
365 
366  friend
368  {
369  int_ap<base> newMantissa = a.mantissa * b.mantissa;
370  a.exponent = a.exponent + b.exponent
371  + (newMantissa.size() - a.mantissa.size());
372  a.mantissa = std::move(newMantissa);
373 
374  return a;
375  }
376 
377  friend
378  float_sap<base> operator/(const float_sap<base>& a, const float_sap<base>& b)
379  {
380  if (b == 0) {
381  std::cout << "Division by 0 encountered in float_sap<"
382  << base << ">.\n";
383  std::raise(SIGFPE);
384  }
385  int_ap<base> divisor, rest;
386  divide(a.mantissa, b.mantissa, divisor, rest);
387  int_ap<base> newExponent = a.exponent - b.exponent;
388  float_sap<base> result(std::move(divisor), newExponent);
389  size_t nDigits = result.mantissa.size();
390  while (rest != 0 and nDigits < PRECISION) {
391  rest *= base;
392  divide(rest, b.mantissa, divisor, rest);
393  float_sap<base> floatRest(rest, 1-b.exponent);
394  result += floatRest;
395  ++nDigits;
396  }
397  return result;
398  }
399 
400  friend
401  float_sap<base> operator/(const float_sap<base>& a, long long int b)
402  {
403  return a / float_sap<base>(b);
404  }
405 
406  friend
407  float_sap<base> operator/(long long int a, const float_sap<base>& b)
408  {
409  return float_sap<base>(a) / b;
410  }
411 
412  friend
413  float_sap<base>& operator/=(float_sap<base>& a, long long int b)
414  {
415  return a /= float_sap<base>(b);
416  }
417 
418  friend
419  float_sap<base>& operator/=(float_sap<base>& a, const float_sap<base>& b)
420  {
421  return a = (a / b);
422  }
423 
424  friend
425  float_sap<base> operator%(const float_sap<base>& a, const float_sap<base>& b)
426  {
427  float_sap<base> divisor, rest;
428  divide(a, b, divisor, rest);
429 
430  return rest;
431  }
432 
433  friend
434  float_sap<base> operator%(const float_sap<base>& a, long long int b)
435  {
436  return a % float_sap<base>(b);
437  }
438 
439  friend
440  float_sap<base> operator%(long long int a, const float_sap<base>& b)
441  {
442  return float_sap<base>(a) % b;
443  }
444 
445  friend
446  float_sap<base>& operator%=(float_sap<base>& a, long long int b)
447  {
448  return a %= float_sap<base>(b);
449  }
450 
451  friend
452  float_sap<base>& operator%=(float_sap<base>& a, const float_sap<base>& b)
453  {
454  return a = (a % b);
455  }
456 
457  friend
458  float_sap<base> pow(long long int a, const float_sap<base>& b)
459  {
460  return pow(float_sap<base>(a), b);
461  }
462 
463  friend
464  float_sap<base> pow(const float_sap<base>& a, long long int b)
465  {
466  return pow(a, float_sap<base>(b));
467  }
468 
469  friend
470  float_sap<base> pow(const float_sap<base>& a, const float_sap<base>& b)
471  {
472  if (b <= 0) {
473  if (b == 0) {
474  if (a != 0)
475  return int_ap<base>(1);
476  std::cout << "Error: 0^0 is not defined." << std::endl;
477  std::raise(SIGFPE);
478  }
479  return 1 / (pow(a, -b));
480  }
481  if (b == 1)
482  return a;
483  float_sap<base> res = a;
484  int_ap<base> totalPow(1);
485  while (true) {
486  if (totalPow*2 <= b) {
487  res *= res;
488  totalPow *= 2;
489  }
490  else if (totalPow == b)
491  return res;
492  else {
493  return res *= pow(a, b-totalPow);
494  }
495  }
496  }
497 
498  friend
499  bool operator==(long long int a, const float_sap<base>& b)
500  {
501  return float_sap<base>(a)==b;
502  }
503 
504  friend
505  bool operator==(const float_sap<base>& a, long long int b)
506  {
507  return a==float_sap<base>(b);
508  }
509 
510  friend
511  bool operator==(const float_sap<base>& a, const float_sap<base>& b)
512  {
513  return (a.exponent == b.exponent) and (a.mantissa == b.mantissa);
514  }
515 
516  friend
517  bool operator!=(long long int a, const float_sap<base>& b)
518  {
519  return float_sap<base>(a)!=b;
520  }
521 
522  friend
523  bool operator!=(const float_sap<base>& a, long long int b)
524  {
525  return a!=float_sap<base>(b);
526  }
527 
528  friend
529  bool operator!=(const float_sap<base>& a, const float_sap<base>& b)
530  {
531  return not (a == b);
532  }
533 
534  friend
535  bool operator<(long long int a, const float_sap<base>& b)
536  {
537  return float_sap<base>(a)<b;
538  }
539 
540  friend
541  bool operator<(const float_sap<base>& a, long long int b)
542  {
543  return a<float_sap<base>(b);
544  }
545 
546  friend
547  bool operator<(const float_sap<base>& a, const float_sap<base>& b)
548  {
549  if (a.exponent < b.exponent)
550  return true;
551  if (b.exponent < a.exponent)
552  return false;
553  return a.mantissa < b.mantissa;
554  }
555 
556  friend
557  bool operator<=(long long int a, const float_sap<base>& b)
558  {
559  return (a<b or a==b);
560  }
561 
562  friend
563  bool operator<=(const float_sap<base>& a, long long int b)
564  {
565  return (a<b or a==b);
566  }
567 
568  friend
569  bool operator<=(const float_sap<base>& a, const float_sap<base>& b)
570  {
571  return (a<b or a==b);
572  }
573 
574  friend
575  bool operator>(long long int a, const float_sap<base>& b)
576  {
577  return float_sap<base>(a)>b;
578  }
579 
580  friend
581  bool operator>(const float_sap<base>& a, long long int b)
582  {
583  return a>float_sap<base>(b);
584  }
585 
586  friend
587  bool operator>(const float_sap<base>& a, const float_sap<base>& b)
588  {
589  return b < a;
590  }
591 
592  friend
593  bool operator>=(long long int a, const float_sap<base>& b)
594  {
595  return (a>b or a==b);
596  }
597 
598  friend
599  bool operator>=(const float_sap<base>& a, long long int b)
600  {
601  return (a>b or a==b);
602  }
603 
604  friend
605  bool operator>=(const float_sap<base>& a, const float_sap<base>& b)
606  {
607  return (a>b or a==b);
608  }
609 };
610 
611 template<size_t base>
613  :mantissa(int_ap<base>(1)),
614  exponent(int_ap<base>(0))
615 {
616 
617 }
618 
619 template<size_t base>
620 float_sap<base>::float_sap(long double other)
621 {
622  *this = other;
623 }
624 
625 template<size_t base>
626 float_sap<base>::float_sap(const int_ap<base>& other)
627 {
628  mantissa = other;
629  exponent = mantissa / base + 1;
630 }
631 
632 template<size_t base>
633 float_sap<base>::float_sap(const int_ap<base>& t_mantissa,
634  const int_ap<base>& t_exponent)
635  :mantissa(t_mantissa),
636  exponent(t_exponent)
637 {
638 
639 }
640 
641 template<size_t base>
643 {
644  return mantissa.getMinusSign();
645 }
646 
647 template<size_t base>
648 void float_sap<base>::setMinusSign(bool t_sign)
649 {
650  mantissa.setMinusSign(t_sign);
651 }
652 
653 template<size_t base>
655 {
656  adjustOnExponent(number.exponent);
657 }
658 
659 template<size_t base>
660 void float_sap<base>::adjustOnExponent(const int_ap<base>& t_exponent)
661 {
662  int diff = (exponent - t_exponent).toCInteger();
663  if (diff < 0) {
664  std::cout << "Adjusting a float_sap on bigger exponent. No meant to do"
665  << " do that." << std::endl;
666  std::raise(SIGTERM);
667  }
668  mantissa.shiftLeft(diff);
669 }
670 
671 template<size_t base>
673 {
674  if (other == 0)
675  return *this = float_sap(0);
676  bool sign = false;
677  if (other < 0) {
678  other = -other;
679  sign = true;
680  }
681  *this = decomposeLongFloat<base>(other);
682  setMinusSign(sign);
683 
684  return *this;
685 }
686 
687 template<size_t base>
689 {
690  mantissa = other.mantissa;
691  exponent = other.exponent;
692  return *this;
693 }
694 
695 template<size_t base>
697 {
698  return exponent;
699 }
700 
701 template<size_t base>
702 float_sap<base>& float_sap<base>::format(std::string const& f)
703 {
704  csl::Formatter::setFormat(f);
705  return *this;
706 }
707 
708 template<>
709 class float_sap<0> {
710  public:
711  float_sap<0>() = delete;
712 };
713 
714 template<>
715 class float_sap<1> {
716  public:
717  float_sap<1>() = delete;
718 };
719 
720 } // End of namespace csl
721 
722 #endif
Namespace for csl library.
Definition: abreviation.h:34
Definition: floatFormatter.h:33
Definition: precision_int.h:53
Definition: precision_float.h:709
Definition: precision_float.h:63
Definition: precision_float.h:715