Leonardus
Loading...
Searching...
No Matches
soq.h
Go to the documentation of this file.
1
17#pragma once
18
19// Inc Library
20#include <string>
21#include <gmp.h>
22
23// Inc HAA
24#include "adapter128.h"
25#include "dbc.h"
26#include "helper.h"
27#include "error.h"
28
29// Inc Rich
30#include "so.h"
31
32
38class SOQ : public SO {
39
40 mpq_t q_;
43 size_t str_length() const {
44 const size_t num_size = mpz_sizeinbase(mpq_numref(q_), 10);
45 const size_t den_size = mpz_sizeinbase(mpq_denref(q_), 10);
46 // +3 for opional '-' and '/' and '\0'
47 return num_size + den_size + 3;
48 }
49
50protected:
51#ifndef DBC_IS_VOID
55 bool invariant() const noexcept override { /* LCOV_EXCL_START */
56 if( mpz_sgn( mpq_denref( q_ ) ) != 1 )
57 return false;
58 mpz_t g;
59 mpz_init( g );
60 mpz_gcd( g, mpq_numref(q_), mpq_denref(q_) );
61 int rv = mpz_cmp_si( g, 1 );
62 mpz_clear( g );
63 return rv == 0;
64 } /* LCOV_EXCL_STOP */
65#endif
66
67public:
69 SOQ() {
70 mpq_init( q_ );
71
73 }
74
76 SOQ( const mpq_t p_q ) {
77 mpq_init( q_ );
78 mpq_set( q_, p_q );
79
81 }
82
88 SOQ( const __int128 p_num, const __int128 p_den ) {
89 DBC_PRE( p_den != 0 );
90
91 mpq_init( q_ );
92
93 __int128_to_mpz_t( mpq_numref( q_ ), p_num );
94 __int128_to_mpz_t( mpq_denref( q_ ), p_den );
95 mpq_canonicalize( q_ );
96
98 }
99
102 DBC_INV;
103
104 mpq_clear( q_ );
105 }
106
107public: /* virtual */
108 [[nodiscard]] SOQ * dup() const override { return new SOQ( q_ ); }
109
110 std::string opequal() const override {
111 char * buffer = new char[ str_length() ];
112 mpq_get_str( buffer, 10, q_ );
113 std::string str( buffer );
114 delete[] buffer;
115 return str;
116 }
117
118 OTCode ot() const override { return OTCode::Q; }
119
120 std::string type() const override { return "rationaltype"; }
121
122 bool equal( const SO * p_other ) const override {
123 auto o = dynamic_cast<const SOQ*>( p_other );
124 return o ? mpq_equal( q_, o->q_) : false;
125 }
126
127 bool gt( const SO * p_other ) const override {
128 auto o = dynamic_cast<const SOQ*>( p_other );
129 if( o == nullptr )
131 return mpq_cmp( q_, o->q_) > 0;
132 }
133
134 bool ge( const SO * p_other ) const override {
135 auto o = dynamic_cast<const SOQ*>( p_other );
136 if( o == nullptr )
138 return mpq_cmp( q_, o->q_) >= 0;
139 }
140
141public: /* accessor */
143 void getRational( mpq_t p_q ) const {
144 mpq_set( p_q, q_ );
145 }
146
148 void setRational( const mpq_t p_q ) {
149 mpq_set( q_, p_q );
150
151 DBC_INV;
152 }
153
155 void getNumerator( mpz_t p_z ) const {
156 mpz_set( p_z, mpq_numref(q_) );
157 }
158
160 void setNumerator( mpz_t p_z ) {
161 mpz_set( mpq_numref(q_), p_z );
162 mpq_canonicalize( q_ );
163
164 DBC_INV;
165 }
166
170 bool getComponents( __int128 & p_num, __int128 & p_den ) const {
171 if( ! mpz_t_to___int128( p_num, mpq_numref( q_ ) ) )
172 return false;
173 if( ! mpz_t_to___int128( p_den, mpq_denref( q_ ) ) )
174 return false;
175 return true;
176 }
177
178public: /* other */
181 bool isunitfraction() const {
182 return mpz_cmp_ui( mpq_numref(q_), 1u ) == 0;
183 }
184
187 bool iszero() const {
188 return mpz_cmp_ui( mpq_numref(q_), 0u ) == 0;
189 }
190
193 bool isinteger() const {
194 return mpz_cmp_ui( mpq_denref(q_), 1u ) == 0;
195 }
196
199 void divqr( mpq_t p_q, mpq_t p_r ) const {
200 mpz_set_ui( mpq_denref( p_q ), 1u ); // set the denominator of p_q = 1
201 mpz_set( mpq_denref( p_r ), mpq_denref( q_ ) ); // set the denominator of p_r = denominator of q_
202 mpz_fdiv_qr( mpq_numref(p_q), mpq_numref(p_r), mpq_numref(q_), mpq_denref(q_) );
203 }
204
211 bool parse( std::string p_str ) {
212 if( mpq_set_str( q_, p_str.c_str(), 10 ) != 0 )
213 return false;
214 if( mpz_sgn( mpq_denref( q_ ) ) == 0 )
215 return false;
216 mpq_canonicalize( q_ );
217
218 DBC_INV;
219 return true;
220 }
221
223 void abs() {
224 mpq_abs( q_, q_ );
225
226 DBC_INV;
227 }
228
230 void neg() {
231 mpq_neg( q_, q_ );
232
233 DBC_INV;
234 }
235
237 void reciprocal() {
238 if( mpz_sgn( mpq_numref( q_ ) ) == 0 )
240 mpq_inv( q_, q_ );
241
242 DBC_INV;
243 }
244
248 __float128 float128() const;
249};
void __int128_to_mpz_t(mpz_t p_dst, __int128 p_src)
Converts an __int128 into a mpz_t.
Definition adapter128.cpp:120
bool mpz_t_to___int128(__int128 &p_dst, const mpz_t p_src)
Converts a mpz_t into an __int128.
Definition adapter128.cpp:82
Adapters for 128 bit versions of standard functions.
Semantic Object Rational Number.
Definition soq.h:38
std::string opequal() const override
For operators '=', 'cvs' and 'stack'.
Definition soq.h:110
SOQ(const mpq_t p_q)
Ctor.
Definition soq.h:76
void getNumerator(mpz_t p_z) const
Set the parameter to our numerator value.
Definition soq.h:155
SOQ(const __int128 p_num, const __int128 p_den)
Ctor.
Definition soq.h:88
void reciprocal()
Inplace reciprocal.
Definition soq.h:237
void abs()
Inplace abs.
Definition soq.h:223
bool gt(const SO *p_other) const override
Greater than.
Definition soq.h:127
std::string type() const override
Returns a type name.
Definition soq.h:120
OTCode ot() const override
Returns an OTCode.
Definition soq.h:118
void setNumerator(mpz_t p_z)
Replaces numerator.
Definition soq.h:160
bool isinteger() const
Checks denominator == 1.
Definition soq.h:193
bool getComponents(__int128 &p_num, __int128 &p_den) const
Set the parameters to numerator and denominator.
Definition soq.h:170
SOQ * dup() const override
Creates a new instance as copy following the red book definition.
Definition soq.h:108
bool parse(std::string p_str)
Parses the string for a presentation of a rational.
Definition soq.h:211
~SOQ()
Dtor.
Definition soq.h:101
void divqr(mpq_t p_q, mpq_t p_r) const
Calculates quotient and remainder.
Definition soq.h:199
bool ge(const SO *p_other) const override
Greater or equal.
Definition soq.h:134
size_t str_length() const
Size of the string representation in characters.
Definition soq.h:43
bool invariant() const noexcept override
Checks class invariants.
Definition soq.h:55
void neg()
Inplace neg.
Definition soq.h:230
void getRational(mpq_t p_q) const
Set the parameter to our value.
Definition soq.h:143
bool iszero() const
Checks numerator == 0.
Definition soq.h:187
void setRational(const mpq_t p_q)
Replaces the rational by the parameter.
Definition soq.h:148
__float128 float128() const
A real representation of the rational.
Definition soq.cpp:30
bool equal(const SO *p_other) const override
Equality.
Definition soq.h:122
SOQ()
Ctor.
Definition soq.h:69
bool isunitfraction() const
Checks numerator == 1.
Definition soq.h:181
mpq_t q_
The rational number by GMP.
Definition soq.h:40
Semantic Object.
Definition so.h:58
Helpers for design by contract idioms.
#define DBC_INV_CTOR(T)
Assert for invariant checks in ctors and dtors.
Definition dbc.h:89
#define DBC_INV
Assert for invariant checks in member functions.
Definition dbc.h:84
#define DBC_PRE(XXX)
Assert for preconditions.
Definition dbc.h:78
void opErrExit(OpError p_err, const std::string &p_details, const std::source_location p_location)
Operator error message to interpreter cout_ and exit( EC_OPERATOR ).
Definition error.cpp:31
Error handling.
@ undefinedresult
PS operator error undefinedresult.
Definition error.h:37
@ typecheck
PS operator error typecheck.
Definition error.h:34
Miscellaneous definitions and functions.
The class SO - semantic object.
OTCode
OTCode - the Object Type Code.
Definition so.h:33
@ o
SOo.
@ Q
SOQ.