File: test_cpp_bin_float_round.cpp

package info (click to toggle)
boost1.62 1.62.0%2Bdfsg-4
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 686,420 kB
  • sloc: cpp: 2,609,004; xml: 972,558; ansic: 53,674; python: 32,437; sh: 8,829; asm: 3,071; cs: 2,121; makefile: 964; perl: 859; yacc: 472; php: 132; ruby: 94; f90: 55; sql: 13; csh: 6
file content (89 lines) | stat: -rw-r--r-- 2,771 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
// Copyright John Maddock 2016.

// Use, modification and distribution are subject to the
// Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt
// or copy at http://www.boost.org/LICENSE_1_0.txt)

//
// This file takes way too long to run to be part of the main regression test suite,
// but is useful in probing for errors in cpp_bin_float's rounding code.
// It cycles through every single value of type float, and rounds those numbers
// plus some closely related ones and compares the results to those produced by MPFR.
//
#ifdef _MSC_VER
#  define _SCL_SECURE_NO_WARNINGS
#endif

#include <boost/multiprecision/cpp_bin_float.hpp>
#include <boost/multiprecision/mpfr.hpp>
#include <boost/math/special_functions/next.hpp>
#include "test.hpp"

using namespace boost::multiprecision;

typedef number<mpfr_float_backend<35> > good_type;
typedef number<cpp_bin_float<std::numeric_limits<good_type>::digits, digit_base_2>, et_off> test_type;


int main()
{
   float f = std::numeric_limits<float>::max();

   do
   {
      float fr1, fr2;
      good_type gf(f), gf2(f);
      test_type tf(f), tf2(f);
      fr1 = gf.convert_to<float>();
      fr2 = tf.convert_to<float>();
      BOOST_CHECK_EQUAL(fr1, fr2);
      // next represenation:
      gf = boost::math::float_next(gf2);
      tf = boost::math::float_next(tf2);
      BOOST_CHECK_NE(gf, gf2);
      BOOST_CHECK_NE(tf, tf2);
      fr1 = gf.convert_to<float>();
      fr2 = tf.convert_to<float>();
      BOOST_CHECK_EQUAL(fr1, fr2);
      // previous representation:
      gf = boost::math::float_prior(gf2);
      tf = boost::math::float_prior(tf2);
      BOOST_CHECK_NE(gf, gf2);
      BOOST_CHECK_NE(tf, tf2);
      fr1 = gf.convert_to<float>();
      fr2 = tf.convert_to<float>();
      BOOST_CHECK_EQUAL(fr1, fr2);

      // Create ands test ties:
      int e;
      std::frexp(f, &e);
      float extra = std::ldexp(1.0f, e - std::numeric_limits<float>::digits - 1);
      gf = gf2 += extra;
      tf = tf2 += extra;
      fr1 = gf.convert_to<float>();
      fr2 = tf.convert_to<float>();
      BOOST_CHECK_EQUAL(fr1, fr2);
      // next represenation:
      gf = boost::math::float_next(gf2);
      tf = boost::math::float_next(tf2);
      BOOST_CHECK_NE(gf, gf2);
      BOOST_CHECK_NE(tf, tf2);
      fr1 = gf.convert_to<float>();
      fr2 = tf.convert_to<float>();
      BOOST_CHECK_EQUAL(fr1, fr2);
      // previous representation:
      gf = boost::math::float_prior(gf2);
      tf = boost::math::float_prior(tf2);
      BOOST_CHECK_NE(gf, gf2);
      BOOST_CHECK_NE(tf, tf2);
      fr1 = gf.convert_to<float>();
      fr2 = tf.convert_to<float>();
      BOOST_CHECK_EQUAL(fr1, fr2);

      f = boost::math::float_prior(f);
   } while(f);

   return boost::report_errors();
}