1/* Test precision of mpf_class expressions. 2 3Copyright 2001-2003, 2008 Free Software Foundation, Inc. 4 5This file is part of the GNU MP Library test suite. 6 7The GNU MP Library test suite is free software; you can redistribute it 8and/or modify it under the terms of the GNU General Public License as 9published by the Free Software Foundation; either version 3 of the License, 10or (at your option) any later version. 11 12The GNU MP Library test suite is distributed in the hope that it will be 13useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 15Public License for more details. 16 17You should have received a copy of the GNU General Public License along with 18the GNU MP Library test suite. If not, see https://www.gnu.org/licenses/. */ 19 20#include "config.h" 21 22#include <iostream> 23 24#include "gmpxx.h" 25#include "gmp-impl.h" 26#include "tests.h" 27 28using namespace std; 29 30 31const int 32small_prec = 64, medium_prec = 128, large_prec = 192, very_large_prec = 256; 33 34#define ASSERT_ALWAYS_PREC(a, s, prec) \ 35{ \ 36 mpf_srcptr _a = a.get_mpf_t(); \ 37 mpf_class _b(s, prec); \ 38 mpf_srcptr _c = _b.get_mpf_t(); \ 39 ASSERT_ALWAYS(mpf_eq(_a, _c, prec)); \ 40} 41 42 43 44void 45check_mpf (void) 46{ 47 mpf_set_default_prec(medium_prec); 48 49 // simple expressions 50 { 51 mpf_class f(3.0, small_prec); 52 mpf_class g(1 / f, very_large_prec); 53 ASSERT_ALWAYS_PREC 54 (g, "0.33333 33333 33333 33333 33333 33333 33333 33333 33333 33333" 55 " 33333 33333 33333 33333 33333 333", very_large_prec); 56 } 57 { 58 mpf_class f(9.0, medium_prec); 59 mpf_class g(0.0, very_large_prec); 60 g = 1 / f; 61 ASSERT_ALWAYS_PREC 62 (g, "0.11111 11111 11111 11111 11111 11111 11111 11111 11111 11111" 63 " 11111 11111 11111 11111 11111 111", very_large_prec); 64 } 65 { 66 mpf_class f(15.0, large_prec); 67 mpf_class g(0.0, very_large_prec); 68 g = 1 / f; 69 ASSERT_ALWAYS_PREC 70 (g, "0.06666 66666 66666 66666 66666 66666 66666 66666 66666 66666" 71 " 66666 66666 66666 66666 66666 667", very_large_prec); 72 } 73 74 // compound expressions 75 { 76 mpf_class f(3.0, small_prec); 77 mpf_class g(-(-(-1 / f)), very_large_prec); 78 ASSERT_ALWAYS_PREC 79 (g, "-0.33333 33333 33333 33333 33333 33333 33333 33333 33333 33333" 80 " 33333 33333 33333 33333 33333 333", very_large_prec); 81 } 82 { 83 mpf_class f(3.0, small_prec), g(9.0, medium_prec); 84 mpf_class h(0.0, very_large_prec); 85 h = 1/f + 1/g; 86 ASSERT_ALWAYS_PREC 87 (h, "0.44444 44444 44444 44444 44444 44444 44444 44444 44444 44444" 88 " 44444 44444 44444 44444 44444 444", very_large_prec); 89 } 90 { 91 mpf_class f(3.0, small_prec), g(9.0, medium_prec), h(15.0, large_prec); 92 mpf_class i(0.0, very_large_prec); 93 i = f / g + h; 94 ASSERT_ALWAYS_PREC 95 (i, "15.33333 33333 33333 33333 33333 33333 33333 33333 33333 33333" 96 " 33333 33333 33333 33333 33333 3", very_large_prec); 97 } 98 { 99 mpf_class f(3.0, small_prec); 100 mpf_class g(-(1 + f) / 3, very_large_prec); 101 ASSERT_ALWAYS_PREC 102 (g, "-1.33333 33333 33333 33333 33333 33333 33333 33333 33333 33333" 103 " 33333 33333 33333 33333 33333 33", very_large_prec); 104 } 105 { 106 mpf_class f(9.0, medium_prec); 107 mpf_class g(0.0, very_large_prec); 108 g = sqrt(1 / f); 109 ASSERT_ALWAYS_PREC 110 (g, "0.33333 33333 33333 33333 33333 33333 33333 33333 33333 33333" 111 " 33333 33333 33333 33333 33333 333", very_large_prec); 112 } 113 { 114 mpf_class f(15.0, large_prec); 115 mpf_class g(0.0, very_large_prec); 116 g = hypot(1 + 5 / f, 1.0); 117 ASSERT_ALWAYS_PREC 118 (g, "1.66666 66666 66666 66666 66666 66666 66666 66666 66666 66666" 119 " 66666 66666 66666 66666 66666 67", very_large_prec); 120 } 121 122 // compound assignments 123 { 124 mpf_class f(3.0, small_prec), g(9.0, medium_prec); 125 mpf_class h(1.0, very_large_prec); 126 h -= f / g; 127 ASSERT_ALWAYS_PREC 128 (h, "0.66666 66666 66666 66666 66666 66666 66666 66666 66666 66666" 129 " 66666 66666 66666 66666 66666 667", very_large_prec); 130 } 131 132 // construction from expressions 133 { 134 mpf_class f(3.0, small_prec); 135 mpf_class g(0.0, very_large_prec); 136 g = mpf_class(1 / f); 137 ASSERT_ALWAYS_PREC(g, "0.33333 33333 33333 33333", small_prec); 138 } 139 { 140 mpf_class f(9.0, medium_prec); 141 mpf_class g(0.0, very_large_prec); 142 g = mpf_class(1 / f); 143 ASSERT_ALWAYS_PREC 144 (g, "0.11111 11111 11111 11111 11111 11111 11111 1111", medium_prec); 145 } 146 { 147 mpf_class f(15.0, large_prec); 148 mpf_class g(0.0, very_large_prec); 149 g = mpf_class(1 / f); 150 ASSERT_ALWAYS_PREC 151 (g, "0.06666 66666 66666 66666 66666 66666 66666 66666 66666 66666" 152 " 66666 6667", large_prec); 153 } 154 155 { 156 mpf_class f(3.0, small_prec), g(9.0, medium_prec); 157 mpf_class h(0.0, very_large_prec); 158 h = mpf_class(f / g + 1, large_prec); 159 ASSERT_ALWAYS_PREC 160 (h, "1.33333 33333 33333 33333 33333 33333 33333 33333 33333 33333" 161 " 33333 333", 162 large_prec); 163 } 164 165 // mixed mpf/mpq expressions 166 { 167 mpf_class f(3.0, small_prec); 168 mpq_class q(1, 3); 169 mpf_class g(0.0, very_large_prec); 170 g = f - q; 171 ASSERT_ALWAYS_PREC 172 (g, "2.66666 66666 66666 66666 66666 66666 66666 66666 66666 66666" 173 " 66666 66666 66666 66666 66666 67", very_large_prec); 174 } 175 176 { 177 mpf_class f(3.0, small_prec); 178 mpq_class q(1, 3); 179 mpf_class g(0.0, very_large_prec); 180 g = mpf_class(f - q, large_prec); 181 ASSERT_ALWAYS_PREC 182 (g, "2.66666 66666 66666 66666 66666 66666 66666 66666 66666 66666" 183 " 66666 667", 184 large_prec); 185 } 186 { 187 mpf_class f(3.0, small_prec); 188 mpq_class q(1, 3); 189 mpf_class g(0.0, very_large_prec); 190 g = mpf_class(f - q); 191 ASSERT_ALWAYS_PREC 192 (g, "2.66666 66666 66666 66666 66666 66666 66666 667", medium_prec); 193 } 194 { 195 mpf_class f(15.0, large_prec); 196 mpq_class q(1, 3); 197 mpf_class g(0.0, very_large_prec); 198 g = mpf_class(f + q); 199 ASSERT_ALWAYS_PREC 200 (g, "15.33333 33333 33333 33333 33333 33333 33333 33333 33333 33333" 201 " 33333 33", 202 large_prec); 203 } 204} 205 206 207int 208main (void) 209{ 210 tests_start(); 211 212 check_mpf(); 213 214 tests_end(); 215 return 0; 216} 217