]>
git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/multiprecision/example/constexpr_float_arithmetic_examples.cpp
1 // (C) Copyright John Maddock 2019.
2 // Use, modification and distribution are subject to the
3 // Boost Software License, Version 1.0. (See accompanying file
4 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 #include <boost/math/constants/constants.hpp>
8 #ifdef BOOST_HAS_FLOAT128
9 #include <boost/multiprecision/float128.hpp>
15 inline constexpr T
circumference ( T radius
)
17 return 2 * boost :: math :: constants :: pi
< T
>() * radius
;
21 inline constexpr T
area ( T radius
)
23 return boost :: math :: constants :: pi
< T
>() * radius
* radius
;
27 template < class T
, unsigned Order
>
28 struct const_polynomial
34 constexpr const_polynomial ( T val
= 0 ) : data
{ val
} {}
35 constexpr const_polynomial ( const std :: initializer_list
< T
>& init
) : data
{}
37 if ( init
. size () > Order
+ 1 )
38 throw std :: range_error ( "Too many initializers in list" );
39 for ( unsigned i
= 0 ; i
< init
. size (); ++ i
)
40 data
[ i
] = init
. begin ()[ i
];
42 constexpr T
& operator []( std :: size_t N
)
46 constexpr const T
& operator []( std :: size_t N
) const
51 constexpr T
operator ()( U val
) const
53 T result
= data
[ Order
];
54 for ( unsigned i
= Order
; i
> 0 ; -- i
)
57 result
+= data
[ i
- 1 ];
61 constexpr const_polynomial
< T
, Order
- 1 > derivative () const
63 const_polynomial
< T
, Order
- 1 > result
;
64 for ( unsigned i
= 1 ; i
<= Order
; ++ i
)
66 result
[ i
- 1 ] = (* this )[ i
] * i
;
70 constexpr const_polynomial
operator -()
72 const_polynomial
t (* this );
73 for ( unsigned i
= 0 ; i
<= Order
; ++ i
)
78 constexpr const_polynomial
& operator *=( U val
)
80 for ( unsigned i
= 0 ; i
<= Order
; ++ i
)
81 data
[ i
] = data
[ i
] * val
;
85 constexpr const_polynomial
& operator /=( U val
)
87 for ( unsigned i
= 0 ; i
<= Order
; ++ i
)
88 data
[ i
] = data
[ i
] / val
;
92 constexpr const_polynomial
& operator +=( U val
)
98 constexpr const_polynomial
& operator -=( U val
)
105 template < class T
, unsigned Order1
, unsigned Order2
>
106 inline constexpr const_polynomial
< T
, ( Order1
> Order2
? Order1
: Order2
)> operator +( const const_polynomial
< T
, Order1
>& a
, const const_polynomial
< T
, Order2
>& b
)
109 constexpr ( Order1
> Order2
)
111 const_polynomial
< T
, Order1
> result ( a
);
112 for ( unsigned i
= 0 ; i
<= Order2
; ++ i
)
118 const_polynomial
< T
, Order2
> result ( b
);
119 for ( unsigned i
= 0 ; i
<= Order1
; ++ i
)
124 template < class T
, unsigned Order1
, unsigned Order2
>
125 inline constexpr const_polynomial
< T
, ( Order1
> Order2
? Order1
: Order2
)> operator -( const const_polynomial
< T
, Order1
>& a
, const const_polynomial
< T
, Order2
>& b
)
128 constexpr ( Order1
> Order2
)
130 const_polynomial
< T
, Order1
> result ( a
);
131 for ( unsigned i
= 0 ; i
<= Order2
; ++ i
)
137 const_polynomial
< T
, Order2
> result ( b
);
138 for ( unsigned i
= 0 ; i
<= Order1
; ++ i
)
139 result
[ i
] = a
[ i
] - b
[ i
];
143 template < class T
, unsigned Order1
, unsigned Order2
>
144 inline constexpr const_polynomial
< T
, Order1
+ Order2
> operator *( const const_polynomial
< T
, Order1
>& a
, const const_polynomial
< T
, Order2
>& b
)
146 const_polynomial
< T
, Order1
+ Order2
> result
;
147 for ( unsigned i
= 0 ; i
<= Order1
; ++ i
)
149 for ( unsigned j
= 0 ; j
<= Order2
; ++ j
)
151 result
[ i
+ j
] += a
[ i
] * b
[ j
];
156 template < class T
, unsigned Order
, class U
>
157 inline constexpr const_polynomial
< T
, Order
> operator *( const const_polynomial
< T
, Order
>& a
, const U
& b
)
159 const_polynomial
< T
, Order
> result ( a
);
160 for ( unsigned i
= 0 ; i
<= Order
; ++ i
)
166 template < class U
, class T
, unsigned Order
>
167 inline constexpr const_polynomial
< T
, Order
> operator *( const U
& b
, const const_polynomial
< T
, Order
>& a
)
169 const_polynomial
< T
, Order
> result ( a
);
170 for ( unsigned i
= 0 ; i
<= Order
; ++ i
)
176 template < class T
, unsigned Order
, class U
>
177 inline constexpr const_polynomial
< T
, Order
> operator /( const const_polynomial
< T
, Order
>& a
, const U
& b
)
179 const_polynomial
< T
, Order
> result
;
180 for ( unsigned i
= 0 ; i
<= Order
; ++ i
)
188 template < class T
, unsigned Order
>
189 class hermite_polynomial
191 const_polynomial
< T
, Order
> m_data
;
194 constexpr hermite_polynomial () : m_data ( hermite_polynomial
< T
, Order
- 1 >(). data () * const_polynomial
< T
, 1 >{ 0 , 2 } - hermite_polynomial
< T
, Order
- 1 >(). data (). derivative ())
197 constexpr const const_polynomial
< T
, Order
>& data () const
201 constexpr const T
& operator []( std :: size_t N
) const
206 constexpr T
operator ()( U val
) const
214 class hermite_polynomial
< T
, 0 >
216 const_polynomial
< T
, 0 > m_data
;
219 constexpr hermite_polynomial () : m_data
{ 1 } {}
220 constexpr const const_polynomial
< T
, 0 >& data () const
224 constexpr const T
& operator []( std :: size_t N
) const
229 constexpr T
operator ()( U val
)
236 class hermite_polynomial
< T
, 1 >
238 const_polynomial
< T
, 1 > m_data
;
241 constexpr hermite_polynomial () : m_data
{ 0 , 2 } {}
242 constexpr const const_polynomial
< T
, 1 >& data () const
246 constexpr const T
& operator []( std :: size_t N
) const
251 constexpr T
operator ()( U val
)
260 constexpr double radius
= 2.25 ;
261 constexpr double c
= circumference ( radius
);
262 constexpr double a
= area ( radius
);
264 std :: cout
<< "Circumference = " << c
<< std :: endl
;
265 std :: cout
<< "Area = " << a
<< std :: endl
;
267 constexpr const_polynomial
< double , 2 > pa
= { 3 , 4 };
268 constexpr const_polynomial
< double , 2 > pb
= { 5 , 6 };
269 static_assert ( pa
[ 0 ] == 3 );
270 static_assert ( pa
[ 1 ] == 4 );
271 constexpr auto pc
= pa
* 2 ;
272 static_assert ( pc
[ 0 ] == 6 );
273 static_assert ( pc
[ 1 ] == 8 );
274 constexpr auto pd
= 3 * pa
;
275 static_assert ( pd
[ 0 ] == 3 * 3 );
276 static_assert ( pd
[ 1 ] == 4 * 3 );
277 constexpr auto pe
= pa
+ pb
;
278 static_assert ( pe
[ 0 ] == 3 + 5 );
279 static_assert ( pe
[ 1 ] == 4 + 6 );
280 constexpr auto pf
= pa
- pb
;
281 static_assert ( pf
[ 0 ] == 3 - 5 );
282 static_assert ( pf
[ 1 ] == 4 - 6 );
283 constexpr auto pg
= pa
* pb
;
284 static_assert ( pg
[ 0 ] == 15 );
285 static_assert ( pg
[ 1 ] == 38 );
286 static_assert ( pg
[ 2 ] == 24 );
288 constexpr hermite_polynomial
< double , 2 > h1
;
289 static_assert ( h1
[ 0 ] == - 2 );
290 static_assert ( h1
[ 1 ] == 0 );
291 static_assert ( h1
[ 2 ] == 4 );
293 constexpr hermite_polynomial
< double , 3 > h3
;
294 static_assert ( h3
[ 0 ] == 0 );
295 static_assert ( h3
[ 1 ] == - 12 );
296 static_assert ( h3
[ 2 ] == 0 );
297 static_assert ( h3
[ 3 ] == 8 );
299 constexpr hermite_polynomial
< double , 9 > h9
;
300 static_assert ( h9
[ 0 ] == 0 );
301 static_assert ( h9
[ 1 ] == 30240 );
302 static_assert ( h9
[ 2 ] == 0 );
303 static_assert ( h9
[ 3 ] == - 80640 );
304 static_assert ( h9
[ 4 ] == 0 );
305 static_assert ( h9
[ 5 ] == 48384 );
306 static_assert ( h9
[ 6 ] == 0 );
307 static_assert ( h9
[ 7 ] == - 9216 );
308 static_assert ( h9
[ 8 ] == 0 );
309 static_assert ( h9
[ 9 ] == 512 );
311 static_assert ( h9 ( 0.5 ) == 6481 );
317 #ifdef BOOST_HAS_FLOAT128
318 //[constexpr_circle_usage
320 using boost :: multiprecision :: float128
;
322 constexpr float128 radius
= 2.25 ;
323 constexpr float128 c
= circumference ( radius
);
324 constexpr float128 a
= area ( radius
);
326 std :: cout
<< "Circumference = " << c
<< std :: endl
;
327 std :: cout
<< "Area = " << a
<< std :: endl
;
331 constexpr hermite_polynomial
< float128
, 2 > h1
;
332 static_assert ( h1
[ 0 ] == - 2 );
333 static_assert ( h1
[ 1 ] == 0 );
334 static_assert ( h1
[ 2 ] == 4 );
336 constexpr hermite_polynomial
< float128
, 3 > h3
;
337 static_assert ( h3
[ 0 ] == 0 );
338 static_assert ( h3
[ 1 ] == - 12 );
339 static_assert ( h3
[ 2 ] == 0 );
340 static_assert ( h3
[ 3 ] == 8 );
343 constexpr hermite_polynomial
< float128
, 9 > h9
;
345 // Verify that the polynomial's coefficients match the known values:
347 static_assert ( h9
[ 0 ] == 0 );
348 static_assert ( h9
[ 1 ] == 30240 );
349 static_assert ( h9
[ 2 ] == 0 );
350 static_assert ( h9
[ 3 ] == - 80640 );
351 static_assert ( h9
[ 4 ] == 0 );
352 static_assert ( h9
[ 5 ] == 48384 );
353 static_assert ( h9
[ 6 ] == 0 );
354 static_assert ( h9
[ 7 ] == - 9216 );
355 static_assert ( h9
[ 8 ] == 0 );
356 static_assert ( h9
[ 9 ] == 512 );
358 // Define an abscissa value to evaluate at:
360 constexpr float128
abscissa ( 0.5 );
362 // Evaluate H_9(0.5) using all constexpr arithmetic:
364 static_assert ( h9 ( abscissa
) == 6481 );
373 std :: cout
<< "Done!" << std :: endl
;