1/*****************************************************************************
2
3  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
4  more contributor license agreements.  See the NOTICE file distributed
5  with this work for additional information regarding copyright ownership.
6  Accellera licenses this file to you under the Apache License, Version 2.0
7  (the "License"); you may not use this file except in compliance with the
8  License.  You may obtain a copy of the License at
9
10    http://www.apache.org/licenses/LICENSE-2.0
11
12  Unless required by applicable law or agreed to in writing, software
13  distributed under the License is distributed on an "AS IS" BASIS,
14  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
15  implied.  See the License for the specific language governing
16  permissions and limitations under the License.
17
18 *****************************************************************************/
19
20/*****************************************************************************
21
22  sc_fxval.h -
23
24  Original Author: Martin Janssen, Synopsys, Inc.
25
26 *****************************************************************************/
27
28/*****************************************************************************
29
30  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
31  changes you are making here.
32
33      Name, Affiliation, Date:
34  Description of Modification:
35
36 *****************************************************************************/
37
38// $Log: sc_fxval.h,v $
39// Revision 1.3  2011/01/19 18:57:40  acg
40//  Andy Goodrich: changes for IEEE_1666_2011.
41//
42// Revision 1.2  2010/12/07 20:09:08  acg
43// Andy Goodrich: Philipp Hartmann's constructor disambiguation fix
44//
45// Revision 1.1.1.1  2006/12/15 20:20:04  acg
46// SystemC 2.3
47//
48// Revision 1.3  2006/01/13 18:53:58  acg
49// Andy Goodrich: added $Log command so that CVS comments are reproduced in
50// the source.
51//
52
53#ifndef SC_FXVAL_H
54#define SC_FXVAL_H
55
56
57#include "sysc/datatypes/fx/scfx_rep.h"
58#ifndef SC_FX_EXCLUDE_OTHER
59#include "sysc/datatypes/int/sc_int_base.h"
60#include "sysc/datatypes/int/sc_uint_base.h"
61#include "sysc/datatypes/int/sc_signed.h"
62#include "sysc/datatypes/int/sc_unsigned.h"
63#endif
64#include "sysc/datatypes/fx/sc_fxval_observer.h"
65
66#ifdef SC_FXVAL_IMPLICIT_CONV
67#   define SCFX_EXPLICIT_ // nothing
68#else
69#   define SCFX_EXPLICIT_ explicit
70#endif
71#ifdef SC_FXVAL_IMPLICIT_OTHER
72#  define SCFX_EXPLICIT_OTHER_
73#else
74#  define SCFX_EXPLICIT_OTHER_ explicit
75#endif
76
77namespace sc_dt
78{
79
80// classes defined in this module
81class sc_fxval;
82class sc_fxval_fast;
83
84// forward class declarations
85class sc_fxnum;
86class sc_fxnum_fast;
87
88
89// ----------------------------------------------------------------------------
90//  CLASS : sc_fxval
91//
92//  Fixed-point value type; arbitrary precision.
93// ----------------------------------------------------------------------------
94
95class sc_fxval
96{
97
98    friend class sc_fxnum;
99
100protected:
101
102    sc_fxval_observer* observer() const;
103
104public:
105
106    // internal use only;
107    explicit sc_fxval( scfx_rep* );
108
109
110    explicit       sc_fxval( sc_fxval_observer* = 0 );
111    SCFX_EXPLICIT_ sc_fxval( int, sc_fxval_observer* = 0 );
112    SCFX_EXPLICIT_ sc_fxval( unsigned int, sc_fxval_observer* = 0 );
113    SCFX_EXPLICIT_ sc_fxval( long, sc_fxval_observer* = 0 );
114    SCFX_EXPLICIT_ sc_fxval( unsigned long, sc_fxval_observer* = 0 );
115    SCFX_EXPLICIT_ sc_fxval( float, sc_fxval_observer* = 0 );
116    SCFX_EXPLICIT_ sc_fxval( double, sc_fxval_observer* = 0 );
117    SCFX_EXPLICIT_ sc_fxval( const char*, sc_fxval_observer* = 0 );
118                   sc_fxval( const sc_fxval&, sc_fxval_observer* = 0 );
119                   sc_fxval( const sc_fxval_fast&, sc_fxval_observer* = 0 );
120                   sc_fxval( const sc_fxnum&, sc_fxval_observer* = 0 );
121                   sc_fxval( const sc_fxnum_fast&, sc_fxval_observer* = 0 );
122#ifndef SC_FX_EXCLUDE_OTHER
123    SCFX_EXPLICIT_OTHER_ sc_fxval( int64, sc_fxval_observer* = 0 );
124    SCFX_EXPLICIT_OTHER_ sc_fxval( uint64, sc_fxval_observer* = 0 );
125    SCFX_EXPLICIT_OTHER_ sc_fxval( const sc_int_base&, sc_fxval_observer* = 0 );
126    SCFX_EXPLICIT_OTHER_ sc_fxval( const sc_uint_base&, sc_fxval_observer* = 0 );
127    SCFX_EXPLICIT_OTHER_ sc_fxval( const sc_signed&, sc_fxval_observer* = 0 );
128    SCFX_EXPLICIT_OTHER_ sc_fxval( const sc_unsigned&, sc_fxval_observer* = 0 );
129#endif
130
131    ~sc_fxval();
132
133
134    // internal use only;
135    const scfx_rep* get_rep() const;
136    void            set_rep( scfx_rep* );
137
138
139    // unary operators
140
141    const sc_fxval  operator - () const;
142    const sc_fxval& operator + () const;
143
144
145    // unary functions
146
147    friend void neg( sc_fxval&, const sc_fxval& );
148
149
150    // binary operators
151
152#define DECL_BIN_OP_T(op,tp)                                                  \
153    friend const sc_fxval operator op ( const sc_fxval&, tp );                \
154    friend const sc_fxval operator op ( tp, const sc_fxval& );
155
156#ifndef SC_FX_EXCLUDE_OTHER
157#define DECL_BIN_OP_OTHER(op)                                                 \
158    DECL_BIN_OP_T(op,int64)                                                   \
159    DECL_BIN_OP_T(op,uint64)                                                  \
160    DECL_BIN_OP_T(op,const sc_int_base&)                                      \
161    DECL_BIN_OP_T(op,const sc_uint_base&)                                     \
162    DECL_BIN_OP_T(op,const sc_signed&)                                        \
163    DECL_BIN_OP_T(op,const sc_unsigned&)
164#else
165#define DECL_BIN_OP_OTHER(op)
166#endif
167
168#define DECL_BIN_OP(op,dummy)                                                 \
169    friend const sc_fxval operator op ( const sc_fxval&, const sc_fxval& );   \
170    DECL_BIN_OP_T(op,int)                                                     \
171    DECL_BIN_OP_T(op,unsigned int)                                            \
172    DECL_BIN_OP_T(op,long)                                                    \
173    DECL_BIN_OP_T(op,unsigned long)                                           \
174    DECL_BIN_OP_T(op,float)                                                  \
175    DECL_BIN_OP_T(op,double)                                                  \
176    DECL_BIN_OP_T(op,const char*)                                             \
177    DECL_BIN_OP_T(op,const sc_fxval_fast&)                                    \
178    DECL_BIN_OP_T(op,const sc_fxnum_fast&)                                    \
179    DECL_BIN_OP_OTHER(op)
180
181    DECL_BIN_OP(*,mult)
182    DECL_BIN_OP(+,add)
183    DECL_BIN_OP(-,sub)
184// declaration below doesn't compile with BCB5 (E2206)
185//    DECL_BIN_OP(/,div)
186// previous macro expanded
187    friend const sc_fxval operator / ( const sc_fxval&, const sc_fxval& );
188    DECL_BIN_OP_T(/,int)
189    DECL_BIN_OP_T(/,unsigned int)
190    DECL_BIN_OP_T(/,long)
191    DECL_BIN_OP_T(/,unsigned long)
192    DECL_BIN_OP_T(/,float)
193    DECL_BIN_OP_T(/,double)
194    DECL_BIN_OP_T(/,const char*)
195    DECL_BIN_OP_T(/,const sc_fxval_fast&)
196    DECL_BIN_OP_T(/,const sc_fxnum_fast&)
197//    DECL_BIN_OP_OTHER(/)
198#ifndef SC_FX_EXCLUDE_OTHER
199    DECL_BIN_OP_T(/,int64)                                                   \
200    DECL_BIN_OP_T(/,uint64)                                                  \
201    DECL_BIN_OP_T(/,const sc_int_base&)                                      \
202    DECL_BIN_OP_T(/,const sc_uint_base&)                                     \
203    DECL_BIN_OP_T(/,const sc_signed&)                                        \
204    DECL_BIN_OP_T(/,const sc_unsigned&)
205#endif
206
207
208#undef DECL_BIN_OP_T
209#undef DECL_BIN_OP_OTHER
210#undef DECL_BIN_OP
211
212    friend const sc_fxval operator << ( const sc_fxval&, int );
213    friend const sc_fxval operator >> ( const sc_fxval&, int );
214
215
216    // binary functions
217
218#define DECL_BIN_FNC_T(fnc,tp)                                                \
219    friend void fnc ( sc_fxval&, const sc_fxval&, tp );                       \
220    friend void fnc ( sc_fxval&, tp, const sc_fxval& );
221
222#ifndef SC_FX_EXCLUDE_OTHER
223#define DECL_BIN_FNC_OTHER(fnc)                                               \
224    DECL_BIN_FNC_T(fnc,int64)                                                 \
225    DECL_BIN_FNC_T(fnc,uint64)                                                \
226    DECL_BIN_FNC_T(fnc,const sc_int_base&)                                    \
227    DECL_BIN_FNC_T(fnc,const sc_uint_base&)                                   \
228    DECL_BIN_FNC_T(fnc,const sc_signed&)                                      \
229    DECL_BIN_FNC_T(fnc,const sc_unsigned&)
230#else
231#define DECL_BIN_FNC_OTHER(fnc)
232#endif
233
234#define DECL_BIN_FNC(fnc)                                                     \
235    friend void fnc ( sc_fxval&, const sc_fxval&, const sc_fxval& );          \
236    DECL_BIN_FNC_T(fnc,int)                                                   \
237    DECL_BIN_FNC_T(fnc,unsigned int)                                          \
238    DECL_BIN_FNC_T(fnc,long)                                                  \
239    DECL_BIN_FNC_T(fnc,unsigned long)                                         \
240    DECL_BIN_FNC_T(fnc,float)                                                \
241    DECL_BIN_FNC_T(fnc,double)                                                \
242    DECL_BIN_FNC_T(fnc,const char*)                                           \
243    DECL_BIN_FNC_T(fnc,const sc_fxval_fast&)                                  \
244    DECL_BIN_FNC_T(fnc,const sc_fxnum_fast&)                                  \
245    DECL_BIN_FNC_OTHER(fnc)
246
247    DECL_BIN_FNC(mult)
248    DECL_BIN_FNC(div)
249    DECL_BIN_FNC(add)
250    DECL_BIN_FNC(sub)
251
252#undef DECL_BIN_FNC_T
253#undef DECL_BIN_FNC_OTHER
254#undef DECL_BIN_FNC
255
256    friend void lshift( sc_fxval&, const sc_fxval&, int );
257    friend void rshift( sc_fxval&, const sc_fxval&, int );
258
259
260    // relational (including equality) operators
261
262#define DECL_REL_OP_T(op,tp)                                                  \
263    friend bool operator op ( const sc_fxval&, tp );                          \
264    friend bool operator op ( tp, const sc_fxval& );
265
266#ifndef SC_FX_EXCLUDE_OTHER
267#define DECL_REL_OP_OTHER(op)                                                 \
268    DECL_REL_OP_T(op,int64)                                                   \
269    DECL_REL_OP_T(op,uint64)                                                  \
270    DECL_REL_OP_T(op,const sc_int_base&)                                      \
271    DECL_REL_OP_T(op,const sc_uint_base&)                                     \
272    DECL_REL_OP_T(op,const sc_signed&)                                        \
273    DECL_REL_OP_T(op,const sc_unsigned&)
274#else
275#define DECL_REL_OP_OTHER(op)
276#endif
277
278#define DECL_REL_OP(op)                                                       \
279    friend bool operator op ( const sc_fxval&, const sc_fxval& );             \
280    DECL_REL_OP_T(op,int)                                                     \
281    DECL_REL_OP_T(op,unsigned int)                                            \
282    DECL_REL_OP_T(op,long)                                                    \
283    DECL_REL_OP_T(op,unsigned long)                                           \
284    DECL_REL_OP_T(op,float)                                                  \
285    DECL_REL_OP_T(op,double)                                                  \
286    DECL_REL_OP_T(op,const char*)                                             \
287    DECL_REL_OP_T(op,const sc_fxval_fast&)                                    \
288    DECL_REL_OP_T(op,const sc_fxnum_fast&)                                    \
289    DECL_REL_OP_OTHER(op)
290
291    DECL_REL_OP(<)
292    DECL_REL_OP(<=)
293    DECL_REL_OP(>)
294    DECL_REL_OP(>=)
295    DECL_REL_OP(==)
296    DECL_REL_OP(!=)
297
298#undef DECL_REL_OP_T
299#undef DECL_REL_OP_OTHER
300#undef DECL_REL_OP
301
302
303    // assignment operators
304
305#define DECL_ASN_OP_T(op,tp)                                                  \
306    sc_fxval& operator op( tp );
307
308#ifndef SC_FX_EXCLUDE_OTHER
309#define DECL_ASN_OP_OTHER(op)                                                 \
310    DECL_ASN_OP_T(op,int64)                                                   \
311    DECL_ASN_OP_T(op,uint64)                                                  \
312    DECL_ASN_OP_T(op,const sc_int_base&)                                      \
313    DECL_ASN_OP_T(op,const sc_uint_base&)                                     \
314    DECL_ASN_OP_T(op,const sc_signed&)                                        \
315    DECL_ASN_OP_T(op,const sc_unsigned&)
316#else
317#define DECL_ASN_OP_OTHER(op)
318#endif
319
320#define DECL_ASN_OP(op)                                                       \
321    DECL_ASN_OP_T(op,int)                                                     \
322    DECL_ASN_OP_T(op,unsigned int)                                            \
323    DECL_ASN_OP_T(op,long)                                                    \
324    DECL_ASN_OP_T(op,unsigned long)                                           \
325    DECL_ASN_OP_T(op,float)                                                  \
326    DECL_ASN_OP_T(op,double)                                                  \
327    DECL_ASN_OP_T(op,const char*)                                             \
328    DECL_ASN_OP_T(op,const sc_fxval&)                                         \
329    DECL_ASN_OP_T(op,const sc_fxval_fast&)                                    \
330    DECL_ASN_OP_T(op,const sc_fxnum&)                                         \
331    DECL_ASN_OP_T(op,const sc_fxnum_fast&)                                    \
332    DECL_ASN_OP_OTHER(op)
333
334    DECL_ASN_OP(=)
335
336    DECL_ASN_OP(*=)
337    DECL_ASN_OP(/=)
338    DECL_ASN_OP(+=)
339    DECL_ASN_OP(-=)
340
341    DECL_ASN_OP_T(<<=,int)
342    DECL_ASN_OP_T(>>=,int)
343
344#undef DECL_ASN_OP_T
345#undef DECL_ASN_OP_OTHER
346#undef DECL_ASN_OP
347
348
349    // auto-increment and auto-decrement
350
351    const sc_fxval operator ++ ( int );
352    const sc_fxval operator -- ( int );
353
354    sc_fxval& operator ++ ();
355    sc_fxval& operator -- ();
356
357
358    // implicit conversion
359
360    operator double() const;            // necessary evil!
361
362
363    // explicit conversion to primitive types
364
365    short          to_short() const;
366    unsigned short to_ushort() const;
367    int            to_int() const;
368    unsigned int   to_uint() const;
369    long           to_long() const;
370    unsigned long  to_ulong() const;
371    int64          to_int64() const;
372    uint64         to_uint64() const;
373    float          to_float() const;
374    double         to_double() const;
375
376
377    // explicit conversion to character string
378
379    const std::string to_string() const;
380    const std::string to_string( sc_numrep ) const;
381    const std::string to_string( sc_numrep, bool ) const;
382    const std::string to_string( sc_fmt ) const;
383    const std::string to_string( sc_numrep, sc_fmt ) const;
384    const std::string to_string( sc_numrep, bool, sc_fmt ) const;
385
386    const std::string to_dec() const;
387    const std::string to_bin() const;
388    const std::string to_oct() const;
389    const std::string to_hex() const;
390
391
392    // query value
393
394    bool is_neg() const;
395    bool is_zero() const;
396    bool is_nan() const;
397    bool is_inf() const;
398    bool is_normal() const;
399
400    bool rounding_flag() const;
401
402
403    // print or dump content
404
405    void print( ::std::ostream& = ::std::cout ) const;
406    void scan( ::std::istream& = ::std::cin );
407    void dump( ::std::ostream& = ::std::cout ) const;
408
409
410    // internal use only;
411    bool get_bit( int ) const;
412
413protected:
414
415    sc_fxval_observer* lock_observer() const;
416    void unlock_observer( sc_fxval_observer* ) const;
417
418
419    void get_type( int&, int&, sc_enc& ) const;
420
421    const sc_fxval quantization( const scfx_params&, bool& ) const;
422    const sc_fxval     overflow( const scfx_params&, bool& ) const;
423
424private:
425
426    scfx_rep*                  m_rep;
427
428    mutable sc_fxval_observer* m_observer;
429
430};
431
432
433// ----------------------------------------------------------------------------
434//  CLASS : sc_fxval_fast
435//
436//  Fixed-point value type; limited precision.
437// ----------------------------------------------------------------------------
438
439class sc_fxval_fast
440{
441
442    friend class sc_fxnum_fast;
443
444protected:
445
446    sc_fxval_fast_observer* observer() const;
447
448public:
449
450    explicit       sc_fxval_fast( sc_fxval_fast_observer* = 0 );
451    SCFX_EXPLICIT_ sc_fxval_fast( int, sc_fxval_fast_observer* = 0 );
452    SCFX_EXPLICIT_ sc_fxval_fast( unsigned int, sc_fxval_fast_observer* = 0 );
453    SCFX_EXPLICIT_ sc_fxval_fast( long, sc_fxval_fast_observer* = 0 );
454    SCFX_EXPLICIT_ sc_fxval_fast( unsigned long, sc_fxval_fast_observer* = 0 );
455    SCFX_EXPLICIT_ sc_fxval_fast( float, sc_fxval_fast_observer* = 0 );
456    SCFX_EXPLICIT_ sc_fxval_fast( double, sc_fxval_fast_observer* = 0 );
457    SCFX_EXPLICIT_ sc_fxval_fast( const char*, sc_fxval_fast_observer* = 0 );
458    sc_fxval_fast( const sc_fxval&, sc_fxval_fast_observer* = 0 );
459    sc_fxval_fast( const sc_fxval_fast&, sc_fxval_fast_observer* = 0 );
460    sc_fxval_fast( const sc_fxnum&, sc_fxval_fast_observer* = 0 );
461    sc_fxval_fast( const sc_fxnum_fast&, sc_fxval_fast_observer* = 0 );
462#ifndef SC_FX_EXCLUDE_OTHER
463    SCFX_EXPLICIT_OTHER_ sc_fxval_fast( int64, sc_fxval_fast_observer* = 0 );
464    SCFX_EXPLICIT_OTHER_ sc_fxval_fast( uint64, sc_fxval_fast_observer* = 0 );
465    SCFX_EXPLICIT_OTHER_ sc_fxval_fast( const sc_int_base&, sc_fxval_fast_observer* = 0 );
466    SCFX_EXPLICIT_OTHER_ sc_fxval_fast( const sc_uint_base&, sc_fxval_fast_observer* = 0 );
467    SCFX_EXPLICIT_OTHER_ sc_fxval_fast( const sc_signed&, sc_fxval_fast_observer* = 0 );
468    SCFX_EXPLICIT_OTHER_ sc_fxval_fast( const sc_unsigned&, sc_fxval_fast_observer* = 0 );
469#endif
470
471    ~sc_fxval_fast();
472
473    // internal use only;
474    double get_val() const;
475    void set_val( double );
476
477
478    // unary operators
479
480    const sc_fxval_fast  operator - () const;
481    const sc_fxval_fast& operator + () const;
482
483
484    // unary functions
485
486    friend void neg( sc_fxval_fast&, const sc_fxval_fast& );
487
488
489    // binary operators
490
491#define DECL_BIN_OP_T(op,tp)                                                  \
492    friend const sc_fxval_fast operator op ( const sc_fxval_fast&, tp );      \
493    friend const sc_fxval_fast operator op ( tp, const sc_fxval_fast& );
494
495#ifndef SC_FX_EXCLUDE_OTHER
496#define DECL_BIN_OP_OTHER(op)                                                 \
497    DECL_BIN_OP_T(op,int64)                                                   \
498    DECL_BIN_OP_T(op,uint64)                                                  \
499    DECL_BIN_OP_T(op,const sc_int_base&)                                      \
500    DECL_BIN_OP_T(op,const sc_uint_base&)                                     \
501    DECL_BIN_OP_T(op,const sc_signed&)                                        \
502    DECL_BIN_OP_T(op,const sc_unsigned&)
503#else
504#define DECL_BIN_OP_OTHER(op)
505#endif
506
507#define DECL_BIN_OP(op,dummy)                                                 \
508    friend const sc_fxval_fast operator op ( const sc_fxval_fast&,            \
509					     const sc_fxval_fast& );          \
510    DECL_BIN_OP_T(op,int)                                                     \
511    DECL_BIN_OP_T(op,unsigned int)                                            \
512    DECL_BIN_OP_T(op,long)                                                    \
513    DECL_BIN_OP_T(op,unsigned long)                                           \
514    DECL_BIN_OP_T(op,float)                                                  \
515    DECL_BIN_OP_T(op,double)                                                  \
516    DECL_BIN_OP_T(op,const char*)                                             \
517    DECL_BIN_OP_OTHER(op)
518
519    DECL_BIN_OP(*,mult)
520    DECL_BIN_OP(+,add)
521    DECL_BIN_OP(-,sub)
522// don't use macro
523//    DECL_BIN_OP(/,div)
524    friend const sc_fxval_fast operator / ( const sc_fxval_fast&,
525					     const sc_fxval_fast& );
526    DECL_BIN_OP_T(/,int)
527    DECL_BIN_OP_T(/,unsigned int)
528    DECL_BIN_OP_T(/,long)
529    DECL_BIN_OP_T(/,unsigned long)
530    DECL_BIN_OP_T(/,float)
531    DECL_BIN_OP_T(/,double)
532    DECL_BIN_OP_T(/,const char*)
533//    DECL_BIN_OP_OTHER(/)
534#ifndef SC_FX_EXCLUDE_OTHER
535    DECL_BIN_OP_T(/,int64)                                                   \
536    DECL_BIN_OP_T(/,uint64)                                                  \
537    DECL_BIN_OP_T(/,const sc_int_base&)                                      \
538    DECL_BIN_OP_T(/,const sc_uint_base&)                                     \
539    DECL_BIN_OP_T(/,const sc_signed&)                                        \
540    DECL_BIN_OP_T(/,const sc_unsigned&)
541#endif
542
543#undef DECL_BIN_OP_T
544#undef DECL_BIN_OP_OTHER
545#undef DECL_BIN_OP
546
547    friend const sc_fxval_fast operator << ( const sc_fxval_fast&, int );
548    friend const sc_fxval_fast operator >> ( const sc_fxval_fast&, int );
549
550
551    // binary functions
552
553#define DECL_BIN_FNC_T(fnc,tp)                                                \
554    friend void fnc ( sc_fxval_fast&, const sc_fxval_fast&, tp );             \
555    friend void fnc ( sc_fxval_fast&, tp, const sc_fxval_fast& );
556
557#ifndef SC_FX_EXCLUDE_OTHER
558#define DECL_BIN_FNC_OTHER(fnc)                                               \
559    DECL_BIN_FNC_T(fnc,int64)                                                 \
560    DECL_BIN_FNC_T(fnc,uint64)                                                \
561    DECL_BIN_FNC_T(fnc,const sc_int_base&)                                    \
562    DECL_BIN_FNC_T(fnc,const sc_uint_base&)                                   \
563    DECL_BIN_FNC_T(fnc,const sc_signed&)                                      \
564    DECL_BIN_FNC_T(fnc,const sc_unsigned&)
565#else
566#define DECL_BIN_FNC_OTHER(fnc)
567#endif
568
569#define DECL_BIN_FNC(fnc)                                                     \
570    friend void fnc ( sc_fxval_fast&, const sc_fxval_fast&,                   \
571                      const sc_fxval_fast& );                                 \
572    DECL_BIN_FNC_T(fnc,int)                                                   \
573    DECL_BIN_FNC_T(fnc,unsigned int)                                          \
574    DECL_BIN_FNC_T(fnc,long)                                                  \
575    DECL_BIN_FNC_T(fnc,unsigned long)                                         \
576    DECL_BIN_FNC_T(fnc,float)                                                \
577    DECL_BIN_FNC_T(fnc,double)                                                \
578    DECL_BIN_FNC_T(fnc,const char*)                                           \
579    DECL_BIN_FNC_T(fnc,const sc_fxval&)                                       \
580    DECL_BIN_FNC_T(fnc,const sc_fxnum&)                                       \
581    DECL_BIN_FNC_OTHER(fnc)
582
583    DECL_BIN_FNC(mult)
584    DECL_BIN_FNC(div)
585    DECL_BIN_FNC(add)
586    DECL_BIN_FNC(sub)
587
588#undef DECL_BIN_FNC_T
589#undef DECL_BIN_FNC_OTHER
590#undef DECL_BIN_FNC
591
592    friend void lshift( sc_fxval_fast&, const sc_fxval_fast&, int );
593    friend void rshift( sc_fxval_fast&, const sc_fxval_fast&, int );
594
595
596    // relational (including equality) operators
597
598#define DECL_REL_OP_T(op,tp)                                                  \
599    friend bool operator op ( const sc_fxval_fast&, tp );                     \
600    friend bool operator op ( tp, const sc_fxval_fast& );
601
602#ifndef SC_FX_EXCLUDE_OTHER
603#define DECL_REL_OP_OTHER(op)                                                 \
604    DECL_REL_OP_T(op,int64)                                                   \
605    DECL_REL_OP_T(op,uint64)                                                  \
606    DECL_REL_OP_T(op,const sc_int_base&)                                      \
607    DECL_REL_OP_T(op,const sc_uint_base&)                                     \
608    DECL_REL_OP_T(op,const sc_signed&)                                        \
609    DECL_REL_OP_T(op,const sc_unsigned&)
610#else
611#define DECL_REL_OP_OTHER(op)
612#endif
613
614#define DECL_REL_OP(op)                                                       \
615    friend bool operator op ( const sc_fxval_fast&, const sc_fxval_fast& );   \
616    DECL_REL_OP_T(op,int)                                                     \
617    DECL_REL_OP_T(op,unsigned int)                                            \
618    DECL_REL_OP_T(op,long)                                                    \
619    DECL_REL_OP_T(op,unsigned long)                                           \
620    DECL_REL_OP_T(op,float)                                                  \
621    DECL_REL_OP_T(op,double)                                                  \
622    DECL_REL_OP_T(op,const char*)                                             \
623    DECL_REL_OP_OTHER(op)
624
625    DECL_REL_OP(<)
626    DECL_REL_OP(<=)
627    DECL_REL_OP(>)
628    DECL_REL_OP(>=)
629    DECL_REL_OP(==)
630    DECL_REL_OP(!=)
631
632#undef DECL_REL_OP_T
633#undef DECL_REL_OP_OTHER
634#undef DECL_REL_OP
635
636
637    // assignment operators
638
639#define DECL_ASN_OP_T(op,tp)                                                  \
640    sc_fxval_fast& operator op( tp );
641
642#ifndef SC_FX_EXCLUDE_OTHER
643#define DECL_ASN_OP_OTHER(op)                                                 \
644    DECL_ASN_OP_T(op,int64)                                                   \
645    DECL_ASN_OP_T(op,uint64)                                                  \
646    DECL_ASN_OP_T(op,const sc_int_base&)                                      \
647    DECL_ASN_OP_T(op,const sc_uint_base&)                                     \
648    DECL_ASN_OP_T(op,const sc_signed&)                                        \
649    DECL_ASN_OP_T(op,const sc_unsigned&)
650#else
651#define DECL_ASN_OP_OTHER(op)
652#endif
653
654#define DECL_ASN_OP(op)                                                       \
655    DECL_ASN_OP_T(op,int)                                                     \
656    DECL_ASN_OP_T(op,unsigned int)                                            \
657    DECL_ASN_OP_T(op,long)                                                    \
658    DECL_ASN_OP_T(op,unsigned long)                                           \
659    DECL_ASN_OP_T(op,float)                                                  \
660    DECL_ASN_OP_T(op,double)                                                  \
661    DECL_ASN_OP_T(op,const char*)                                             \
662    DECL_ASN_OP_T(op,const sc_fxval&)                                         \
663    DECL_ASN_OP_T(op,const sc_fxval_fast&)                                    \
664    DECL_ASN_OP_T(op,const sc_fxnum&)                                         \
665    DECL_ASN_OP_T(op,const sc_fxnum_fast&)                                    \
666    DECL_ASN_OP_OTHER(op)
667
668    DECL_ASN_OP(=)
669
670    DECL_ASN_OP(*=)
671    DECL_ASN_OP(/=)
672    DECL_ASN_OP(+=)
673    DECL_ASN_OP(-=)
674
675    DECL_ASN_OP_T(<<=,int)
676    DECL_ASN_OP_T(>>=,int)
677
678#undef DECL_ASN_OP_T
679#undef DECL_ASN_OP_OTHER
680#undef DECL_ASN_OP
681
682
683    // auto-increment and auto-decrement
684
685    const sc_fxval_fast operator ++ ( int );
686    const sc_fxval_fast operator -- ( int );
687
688    sc_fxval_fast& operator ++ ();
689    sc_fxval_fast& operator -- ();
690
691
692    // implicit conversion
693
694    operator double() const;            // necessary evil!
695
696
697    // explicit conversion to primitive types
698
699    short          to_short() const;
700    unsigned short to_ushort() const;
701    int            to_int() const;
702    unsigned int   to_uint() const;
703    long           to_long() const;
704    unsigned long  to_ulong() const;
705    int64          to_int64() const;
706    uint64         to_uint64() const;
707    float          to_float() const;
708    double         to_double() const;
709
710
711    // explicit conversion to character string
712
713    const std::string to_string() const;
714    const std::string to_string( sc_numrep ) const;
715    const std::string to_string( sc_numrep, bool ) const;
716    const std::string to_string( sc_fmt ) const;
717    const std::string to_string( sc_numrep, sc_fmt ) const;
718    const std::string to_string( sc_numrep, bool, sc_fmt ) const;
719
720    const std::string to_dec() const;
721    const std::string to_bin() const;
722    const std::string to_oct() const;
723    const std::string to_hex() const;
724
725
726    // query value
727
728    bool is_neg() const;
729    bool is_zero() const;
730    bool is_nan() const;
731    bool is_inf() const;
732    bool is_normal() const;
733
734    bool rounding_flag() const;
735
736
737    // print or dump content
738
739    void print( ::std::ostream& = ::std::cout ) const;
740    void scan( ::std::istream& = ::std::cin );
741    void dump( ::std::ostream& = ::std::cout ) const;
742
743
744    // internal use only;
745    bool get_bit( int ) const;
746
747protected:
748
749    sc_fxval_fast_observer* lock_observer() const;
750    void unlock_observer( sc_fxval_fast_observer* ) const;
751
752
753    static double from_string( const char* );
754
755private:
756
757    double                          m_val;
758
759    mutable sc_fxval_fast_observer* m_observer;
760
761};
762
763
764// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
765
766// ----------------------------------------------------------------------------
767//  CLASS : sc_fxval
768//
769//  Fixed-point value type; arbitrary precision.
770// ----------------------------------------------------------------------------
771
772// protected method
773
774inline
775sc_fxval_observer*
776sc_fxval::observer() const
777{
778    return m_observer;
779}
780
781
782// internal use only;
783inline
784sc_fxval::sc_fxval( scfx_rep* a )
785: m_rep( a != 0 ? a : new scfx_rep ),
786  m_observer( 0 )
787{}
788
789
790// public constructors
791
792inline
793sc_fxval::sc_fxval( sc_fxval_observer* observer_ )
794: m_rep( new scfx_rep ),
795  m_observer( observer_ )
796{
797    SC_FXVAL_OBSERVER_DEFAULT_
798    SC_FXVAL_OBSERVER_CONSTRUCT_( *this )
799}
800
801inline
802sc_fxval::sc_fxval( const sc_fxval& a,
803		    sc_fxval_observer* observer_ )
804: m_rep( new scfx_rep( *a.m_rep ) ),
805  m_observer( observer_ )
806{
807    SC_FXVAL_OBSERVER_DEFAULT_
808    SC_FXVAL_OBSERVER_READ_( a )
809    SC_FXVAL_OBSERVER_CONSTRUCT_( *this )
810    SC_FXVAL_OBSERVER_WRITE_( *this )
811}
812
813#define DEFN_CTOR_T(tp,arg)                                                   \
814inline                                                                        \
815sc_fxval::sc_fxval( tp a,                                                     \
816                    sc_fxval_observer* observer_ )                            \
817: m_rep( new scfx_rep( arg ) ),                                               \
818  m_observer( observer_ )                                                     \
819{                                                                             \
820    SC_FXVAL_OBSERVER_DEFAULT_                                                \
821    SC_FXVAL_OBSERVER_CONSTRUCT_( *this )                                     \
822    SC_FXVAL_OBSERVER_WRITE_( *this )                                         \
823}
824
825#define DEFN_CTOR_T_A(tp) DEFN_CTOR_T(tp,a)
826#define DEFN_CTOR_T_B(tp) DEFN_CTOR_T(tp,a.to_double())
827#define DEFN_CTOR_T_C(tp) DEFN_CTOR_T(tp,a.value())
828
829DEFN_CTOR_T_A(int)
830DEFN_CTOR_T_A(unsigned int)
831DEFN_CTOR_T_A(long)
832DEFN_CTOR_T_A(unsigned long)
833DEFN_CTOR_T_A(float)
834DEFN_CTOR_T_A(double)
835DEFN_CTOR_T_A(const char*)
836DEFN_CTOR_T_B(const sc_fxval_fast&)
837#ifndef SC_FX_EXCLUDE_OTHER
838DEFN_CTOR_T_A(int64)
839DEFN_CTOR_T_A(uint64)
840DEFN_CTOR_T_C(const sc_int_base&)
841DEFN_CTOR_T_C(const sc_uint_base&)
842DEFN_CTOR_T_A(const sc_signed&)
843DEFN_CTOR_T_A(const sc_unsigned&)
844#endif
845
846#undef DEFN_CTOR_T
847#undef DEFN_CTOR_T_A
848#undef DEFN_CTOR_T_B
849#undef DEFN_CTOR_T_C
850
851
852inline
853sc_fxval::~sc_fxval()
854{
855    SC_FXVAL_OBSERVER_DESTRUCT_( *this )
856    delete m_rep;
857}
858
859
860// internal use only;
861inline
862const scfx_rep*
863sc_fxval::get_rep() const
864{
865    SC_FXVAL_OBSERVER_READ_( *this )
866    return m_rep;
867}
868
869// internal use only;
870inline
871void
872sc_fxval::set_rep( scfx_rep* rep_ )
873{
874    delete m_rep;
875    m_rep = rep_;
876    SC_FXVAL_OBSERVER_WRITE_( *this )
877}
878
879
880// unary operators
881
882inline
883const sc_fxval
884sc_fxval::operator - () const
885{
886    SC_FXVAL_OBSERVER_READ_( *this )
887    return sc_fxval( sc_dt::neg_scfx_rep( *m_rep ) );
888}
889
890inline
891const sc_fxval&
892sc_fxval::operator + () const
893{
894    // SC_FXVAL_OBSERVER_READ_( *this )
895    return *this;
896}
897
898
899// unary functions
900
901inline
902void
903neg( sc_fxval& c, const sc_fxval& a )
904{
905    SC_FXVAL_OBSERVER_READ_( a )
906    delete c.m_rep;
907    c.m_rep = sc_dt::neg_scfx_rep( *a.m_rep );
908    SC_FXVAL_OBSERVER_WRITE_( c )
909}
910
911
912// binary operators
913
914#define DEFN_BIN_OP_T(op,fnc,tp)                                              \
915inline                                                                        \
916const sc_fxval                                                                \
917operator op ( const sc_fxval& a, tp b )                                       \
918{                                                                             \
919    SC_FXVAL_OBSERVER_READ_( a )                                              \
920    sc_fxval tmp( b );                                                        \
921    return sc_fxval( sc_dt::fnc ## _scfx_rep( *a.m_rep, *tmp.m_rep ) );      \
922}                                                                             \
923                                                                              \
924inline                                                                        \
925const sc_fxval                                                                \
926operator op ( tp a, const sc_fxval& b )                                       \
927{                                                                             \
928    SC_FXVAL_OBSERVER_READ_( b )                                              \
929    sc_fxval tmp( a );                                                        \
930    return sc_fxval( sc_dt::fnc ## _scfx_rep( *tmp.m_rep, *b.m_rep ) );      \
931}
932
933#ifndef SC_FX_EXCLUDE_OTHER
934#define DEFN_BIN_OP_OTHER(op,fnc)                                             \
935DEFN_BIN_OP_T(op,fnc,int64)                                                   \
936DEFN_BIN_OP_T(op,fnc,uint64)                                                  \
937DEFN_BIN_OP_T(op,fnc,const sc_int_base&)                                      \
938DEFN_BIN_OP_T(op,fnc,const sc_uint_base&)                                     \
939DEFN_BIN_OP_T(op,fnc,const sc_signed&)                                        \
940DEFN_BIN_OP_T(op,fnc,const sc_unsigned&)
941#else
942#define DEFN_BIN_OP_OTHER(op,fnc)
943#endif
944
945#define DEFN_BIN_OP(op,fnc)                                                   \
946inline                                                                        \
947const sc_fxval                                                                \
948operator op ( const sc_fxval& a, const sc_fxval& b )                          \
949{                                                                             \
950    SC_FXVAL_OBSERVER_READ_( a )                                              \
951    SC_FXVAL_OBSERVER_READ_( b )                                              \
952    return sc_fxval( sc_dt::fnc ## _scfx_rep( *a.m_rep, *b.m_rep ) );        \
953}                                                                             \
954                                                                              \
955DEFN_BIN_OP_T(op,fnc,int)                                                     \
956DEFN_BIN_OP_T(op,fnc,unsigned int)                                            \
957DEFN_BIN_OP_T(op,fnc,long)                                                    \
958DEFN_BIN_OP_T(op,fnc,unsigned long)                                           \
959DEFN_BIN_OP_T(op,fnc,float)                                                  \
960DEFN_BIN_OP_T(op,fnc,double)                                                  \
961DEFN_BIN_OP_T(op,fnc,const char*)                                             \
962DEFN_BIN_OP_T(op,fnc,const sc_fxval_fast&)                                    \
963DEFN_BIN_OP_OTHER(op,fnc)
964
965DEFN_BIN_OP(*,mult)
966DEFN_BIN_OP(+,add)
967DEFN_BIN_OP(-,sub)
968// don't use macro
969//DEFN_BIN_OP(/,div)
970inline
971const sc_fxval
972operator / ( const sc_fxval& a, const sc_fxval& b )
973{
974    SC_FXVAL_OBSERVER_READ_( a )
975    SC_FXVAL_OBSERVER_READ_( b )
976    return sc_fxval( sc_dt::div_scfx_rep( *a.m_rep, *b.m_rep ) );
977}
978
979DEFN_BIN_OP_T(/,div,int)
980DEFN_BIN_OP_T(/,div,unsigned int)
981DEFN_BIN_OP_T(/,div,long)
982DEFN_BIN_OP_T(/,div,unsigned long)
983DEFN_BIN_OP_T(/,div,float)
984DEFN_BIN_OP_T(/,div,double)
985DEFN_BIN_OP_T(/,div,const char*)
986DEFN_BIN_OP_T(/,div,const sc_fxval_fast&)
987//DEFN_BIN_OP_OTHER(/,div)
988#ifndef SC_FX_EXCLUDE_OTHER
989DEFN_BIN_OP_T(/,div,int64)                                                   \
990DEFN_BIN_OP_T(/,div,uint64)                                                  \
991DEFN_BIN_OP_T(/,div,const sc_int_base&)                                      \
992DEFN_BIN_OP_T(/,div,const sc_uint_base&)                                     \
993DEFN_BIN_OP_T(/,div,const sc_signed&)                                        \
994DEFN_BIN_OP_T(/,div,const sc_unsigned&)
995#endif
996
997#undef DEFN_BIN_OP_T
998#undef DEFN_BIN_OP_OTHER
999#undef DEFN_BIN_OP
1000
1001
1002inline
1003const sc_fxval
1004operator << ( const sc_fxval& a, int b )
1005{
1006    SC_FXVAL_OBSERVER_READ_( a )
1007    return sc_fxval( sc_dt::lsh_scfx_rep( *a.m_rep, b ) );
1008}
1009
1010inline
1011const sc_fxval
1012operator >> ( const sc_fxval& a, int b )
1013{
1014    SC_FXVAL_OBSERVER_READ_( a )
1015    return sc_fxval( sc_dt::rsh_scfx_rep( *a.m_rep, b ) );
1016}
1017
1018
1019// binary functions
1020
1021#define DEFN_BIN_FNC_T(fnc,tp)                                                \
1022inline                                                                        \
1023void                                                                          \
1024fnc ( sc_fxval& c, const sc_fxval& a, tp b )                                  \
1025{                                                                             \
1026    SC_FXVAL_OBSERVER_READ_( a )                                              \
1027    sc_fxval tmp( b );                                                        \
1028    delete c.m_rep;                                                           \
1029    c.m_rep = sc_dt::fnc ## _scfx_rep( *a.m_rep, *tmp.m_rep );               \
1030    SC_FXVAL_OBSERVER_WRITE_( c )                                             \
1031}                                                                             \
1032                                                                              \
1033inline                                                                        \
1034void                                                                          \
1035fnc ( sc_fxval& c, tp a, const sc_fxval& b )                                  \
1036{                                                                             \
1037    SC_FXVAL_OBSERVER_READ_( b )                                              \
1038    sc_fxval tmp( a );                                                        \
1039    delete c.m_rep;                                                           \
1040    c.m_rep = sc_dt::fnc ## _scfx_rep( *tmp.m_rep, *b.m_rep );               \
1041    SC_FXVAL_OBSERVER_WRITE_( c )                                             \
1042}
1043
1044#ifndef SC_FX_EXCLUDE_OTHER
1045#define DEFN_BIN_FNC_OTHER(fnc)                                               \
1046DEFN_BIN_FNC_T(fnc,int64)                                                     \
1047DEFN_BIN_FNC_T(fnc,uint64)                                                    \
1048DEFN_BIN_FNC_T(fnc,const sc_int_base&)                                        \
1049DEFN_BIN_FNC_T(fnc,const sc_uint_base&)                                       \
1050DEFN_BIN_FNC_T(fnc,const sc_signed&)                                          \
1051DEFN_BIN_FNC_T(fnc,const sc_unsigned&)
1052#else
1053#define DEFN_BIN_FNC_OTHER(fnc)
1054#endif
1055
1056#define DEFN_BIN_FNC(fnc)                                                     \
1057inline                                                                        \
1058void                                                                          \
1059fnc( sc_fxval& c, const sc_fxval& a, const sc_fxval& b )                      \
1060{                                                                             \
1061    SC_FXVAL_OBSERVER_READ_( a )                                              \
1062    SC_FXVAL_OBSERVER_READ_( b )                                              \
1063    delete c.m_rep;                                                           \
1064    c.m_rep = sc_dt::fnc ## _scfx_rep( *a.m_rep, *b.m_rep );                 \
1065    SC_FXVAL_OBSERVER_WRITE_( c )                                             \
1066}                                                                             \
1067                                                                              \
1068DEFN_BIN_FNC_T(fnc,int)                                                       \
1069DEFN_BIN_FNC_T(fnc,unsigned int)                                              \
1070DEFN_BIN_FNC_T(fnc,long)                                                      \
1071DEFN_BIN_FNC_T(fnc,unsigned long)                                             \
1072DEFN_BIN_FNC_T(fnc,float)                                                    \
1073DEFN_BIN_FNC_T(fnc,double)                                                    \
1074DEFN_BIN_FNC_T(fnc,const char*)                                               \
1075DEFN_BIN_FNC_T(fnc,const sc_fxval_fast&)                                      \
1076DEFN_BIN_FNC_OTHER(fnc)
1077
1078DEFN_BIN_FNC(mult)
1079DEFN_BIN_FNC(div)
1080DEFN_BIN_FNC(add)
1081DEFN_BIN_FNC(sub)
1082
1083#undef DEFN_BIN_FNC_T
1084#undef DEFN_BIN_FNC_OTHER
1085#undef DEFN_BIN_FNC
1086
1087
1088inline
1089void
1090lshift( sc_fxval& c, const sc_fxval& a, int b )
1091{
1092    SC_FXVAL_OBSERVER_READ_( a )
1093    delete c.m_rep;
1094    c.m_rep = sc_dt::lsh_scfx_rep( *a.m_rep, b );
1095    SC_FXVAL_OBSERVER_WRITE_( c )
1096}
1097
1098inline
1099void
1100rshift( sc_fxval& c, const sc_fxval& a, int b )
1101{
1102    SC_FXVAL_OBSERVER_READ_( a )
1103    delete c.m_rep;
1104    c.m_rep = sc_dt::rsh_scfx_rep( *a.m_rep, b );
1105    SC_FXVAL_OBSERVER_WRITE_( c )
1106}
1107
1108
1109// relational (including equality) operators
1110
1111#define DEFN_REL_OP_T(op,ret,tp)                                              \
1112inline                                                                        \
1113bool                                                                          \
1114operator op ( const sc_fxval& a, tp b )                                       \
1115{                                                                             \
1116    SC_FXVAL_OBSERVER_READ_( a )                                              \
1117    sc_fxval tmp( b );                                                        \
1118    int result = sc_dt::cmp_scfx_rep( *a.m_rep, *tmp.m_rep );                \
1119    return ( ret );                                                           \
1120}                                                                             \
1121                                                                              \
1122inline                                                                        \
1123bool                                                                          \
1124operator op ( tp a, const sc_fxval& b )                                       \
1125{                                                                             \
1126    SC_FXVAL_OBSERVER_READ_( b )                                              \
1127    sc_fxval tmp( a );                                                        \
1128    int result = sc_dt::cmp_scfx_rep( *tmp.m_rep, *b.m_rep );                \
1129    return ( ret );                                                           \
1130}
1131
1132#ifndef SC_FX_EXCLUDE_OTHER
1133#define DEFN_REL_OP_OTHER(op,ret)                                             \
1134DEFN_REL_OP_T(op,ret,int64)                                                   \
1135DEFN_REL_OP_T(op,ret,uint64)                                                  \
1136DEFN_REL_OP_T(op,ret,const sc_int_base&)                                      \
1137DEFN_REL_OP_T(op,ret,const sc_uint_base&)                                     \
1138DEFN_REL_OP_T(op,ret,const sc_signed&)                                        \
1139DEFN_REL_OP_T(op,ret,const sc_unsigned&)
1140#else
1141#define DEFN_REL_OP_OTHER(op,ret)
1142#endif
1143
1144#define DEFN_REL_OP(op,ret)                                                   \
1145inline                                                                        \
1146bool                                                                          \
1147operator op ( const sc_fxval& a, const sc_fxval& b)                           \
1148{                                                                             \
1149    SC_FXVAL_OBSERVER_READ_( a )                                              \
1150    SC_FXVAL_OBSERVER_READ_( b )                                              \
1151    int result = sc_dt::cmp_scfx_rep( *a.m_rep, *b.m_rep );                  \
1152    return ( ret );                                                           \
1153}                                                                             \
1154                                                                              \
1155DEFN_REL_OP_T(op,ret,int)                                                     \
1156DEFN_REL_OP_T(op,ret,unsigned int)                                            \
1157DEFN_REL_OP_T(op,ret,long)                                                    \
1158DEFN_REL_OP_T(op,ret,unsigned long)                                           \
1159DEFN_REL_OP_T(op,ret,float)                                                  \
1160DEFN_REL_OP_T(op,ret,double)                                                  \
1161DEFN_REL_OP_T(op,ret,const char*)                                             \
1162DEFN_REL_OP_T(op,ret,const sc_fxval_fast&)                                    \
1163DEFN_REL_OP_OTHER(op,ret)
1164
1165DEFN_REL_OP(<,result < 0)
1166DEFN_REL_OP(<=,result <= 0)
1167DEFN_REL_OP(>,result > 0 && result != 2)
1168DEFN_REL_OP(>=,result >= 0 && result != 2)
1169DEFN_REL_OP(==,result == 0)
1170DEFN_REL_OP(!=,result != 0)
1171
1172#undef DEFN_REL_OP_T
1173#undef DEFN_REL_OP_OTHER
1174#undef DEFN_REL_OP
1175
1176
1177// assignment operators
1178
1179inline
1180sc_fxval&
1181sc_fxval::operator = ( const sc_fxval& a )
1182{
1183    if( &a != this )
1184    {
1185	SC_FXVAL_OBSERVER_READ_( a )
1186	*m_rep = *a.m_rep;
1187	SC_FXVAL_OBSERVER_WRITE_( *this )
1188    }
1189    return *this;
1190}
1191
1192#define DEFN_ASN_OP_T(tp)                                                     \
1193inline                                                                        \
1194sc_fxval&                                                                     \
1195sc_fxval::operator = ( tp b )                                                 \
1196{                                                                             \
1197    sc_fxval tmp( b );                                                        \
1198    *m_rep = *tmp.m_rep;                                                      \
1199    SC_FXVAL_OBSERVER_WRITE_( *this )                                         \
1200    return *this;                                                             \
1201}
1202
1203DEFN_ASN_OP_T(int)
1204DEFN_ASN_OP_T(unsigned int)
1205DEFN_ASN_OP_T(long)
1206DEFN_ASN_OP_T(unsigned long)
1207DEFN_ASN_OP_T(float)
1208DEFN_ASN_OP_T(double)
1209DEFN_ASN_OP_T(const char*)
1210DEFN_ASN_OP_T(const sc_fxval_fast&)
1211#ifndef SC_FX_EXCLUDE_OTHER
1212DEFN_ASN_OP_T(int64)
1213DEFN_ASN_OP_T(uint64)
1214DEFN_ASN_OP_T(const sc_int_base&)
1215DEFN_ASN_OP_T(const sc_uint_base&)
1216DEFN_ASN_OP_T(const sc_signed&)
1217DEFN_ASN_OP_T(const sc_unsigned&)
1218#endif
1219
1220#undef DEFN_ASN_OP_T
1221
1222
1223#define DEFN_ASN_OP_T(op,fnc,tp)                                              \
1224inline                                                                        \
1225sc_fxval&                                                                     \
1226sc_fxval::operator op ( tp b )                                                \
1227{                                                                             \
1228    SC_FXVAL_OBSERVER_READ_( *this )                                          \
1229    sc_fxval tmp( b );                                                        \
1230    scfx_rep* new_rep = sc_dt::fnc ## _scfx_rep( *m_rep, *tmp.m_rep );       \
1231    delete m_rep;                                                             \
1232    m_rep = new_rep;                                                          \
1233    SC_FXVAL_OBSERVER_WRITE_( *this )                                         \
1234    return *this;                                                             \
1235}
1236
1237#ifndef SC_FX_EXCLUDE_OTHER
1238#define DEFN_ASN_OP_OTHER(op,fnc)                                             \
1239DEFN_ASN_OP_T(op,fnc,int64)                                                   \
1240DEFN_ASN_OP_T(op,fnc,uint64)                                                  \
1241DEFN_ASN_OP_T(op,fnc,const sc_int_base&)                                      \
1242DEFN_ASN_OP_T(op,fnc,const sc_uint_base&)                                     \
1243DEFN_ASN_OP_T(op,fnc,const sc_signed&)                                        \
1244DEFN_ASN_OP_T(op,fnc,const sc_unsigned&)
1245#else
1246#define DEFN_ASN_OP_OTHER(op,fnc)
1247#endif
1248
1249#define DEFN_ASN_OP(op,fnc)                                                   \
1250inline                                                                        \
1251sc_fxval&                                                                     \
1252sc_fxval::operator op ( const sc_fxval& b )                                   \
1253{                                                                             \
1254    SC_FXVAL_OBSERVER_READ_( *this )                                          \
1255    SC_FXVAL_OBSERVER_READ_( b )                                              \
1256    scfx_rep* new_rep = sc_dt::fnc ## _scfx_rep( *m_rep, *b.m_rep );         \
1257    delete m_rep;                                                             \
1258    m_rep = new_rep;                                                          \
1259    SC_FXVAL_OBSERVER_WRITE_( *this )                                         \
1260    return *this;                                                             \
1261}                                                                             \
1262                                                                              \
1263DEFN_ASN_OP_T(op,fnc,int)                                                     \
1264DEFN_ASN_OP_T(op,fnc,unsigned int)                                            \
1265DEFN_ASN_OP_T(op,fnc,long)                                                    \
1266DEFN_ASN_OP_T(op,fnc,unsigned long)                                           \
1267DEFN_ASN_OP_T(op,fnc,float)                                                  \
1268DEFN_ASN_OP_T(op,fnc,double)                                                  \
1269DEFN_ASN_OP_T(op,fnc,const char*)                                             \
1270DEFN_ASN_OP_T(op,fnc,const sc_fxval_fast&)                                    \
1271DEFN_ASN_OP_OTHER(op,fnc)
1272
1273DEFN_ASN_OP(*=,mult)
1274DEFN_ASN_OP(/=,div)
1275DEFN_ASN_OP(+=,add)
1276DEFN_ASN_OP(-=,sub)
1277
1278#undef DEFN_ASN_OP_T
1279#undef DEFN_ASN_OP_OTHER
1280#undef DEFN_ASN_OP
1281
1282
1283inline
1284sc_fxval&
1285sc_fxval::operator <<= ( int b )
1286{
1287    SC_FXVAL_OBSERVER_READ_( *this )
1288    m_rep->lshift( b );
1289    SC_FXVAL_OBSERVER_WRITE_( *this )
1290    return *this;
1291}
1292
1293inline
1294sc_fxval&
1295sc_fxval::operator >>= ( int b )
1296{
1297    SC_FXVAL_OBSERVER_READ_( *this )
1298    m_rep->rshift( b );
1299    SC_FXVAL_OBSERVER_WRITE_( *this )
1300    return *this;
1301}
1302
1303
1304// auto-increment and auto-decrement
1305
1306inline
1307const sc_fxval
1308sc_fxval::operator ++ ( int )
1309{
1310    sc_fxval c = *this;
1311    (*this) += 1;
1312    return c;
1313}
1314
1315inline
1316const sc_fxval
1317sc_fxval::operator -- ( int )
1318{
1319    sc_fxval c = *this;
1320    (*this) -= 1;
1321    return c;
1322}
1323
1324inline
1325sc_fxval&
1326sc_fxval::operator ++ ()
1327{
1328    (*this) += 1;
1329    return *this;
1330}
1331
1332inline
1333sc_fxval&
1334sc_fxval::operator -- ()
1335{
1336    (*this) -= 1;
1337    return *this;
1338}
1339
1340
1341// implicit conversion
1342
1343inline
1344sc_fxval::operator double() const
1345{
1346    SC_FXVAL_OBSERVER_READ_( *this )
1347    return m_rep->to_double();
1348}
1349
1350
1351// explicit conversion to primitive types
1352
1353inline
1354short
1355sc_fxval::to_short() const
1356{
1357    SC_FXVAL_OBSERVER_READ_( *this )
1358    return static_cast<short>( m_rep->to_double() );
1359}
1360
1361inline
1362unsigned short
1363sc_fxval::to_ushort() const
1364{
1365    SC_FXVAL_OBSERVER_READ_( *this )
1366    return static_cast<unsigned short>( m_rep->to_double() );
1367}
1368
1369inline
1370int
1371sc_fxval::to_int() const
1372{
1373    SC_FXVAL_OBSERVER_READ_( *this )
1374    return static_cast<int>( m_rep->to_double() );
1375}
1376
1377inline
1378int64
1379sc_fxval::to_int64() const
1380{
1381    SC_FXVAL_OBSERVER_READ_( *this )
1382    return static_cast<int64>( m_rep->to_double() );
1383}
1384
1385inline
1386uint64
1387sc_fxval::to_uint64() const
1388{
1389    SC_FXVAL_OBSERVER_READ_( *this )
1390    return static_cast<uint64>( m_rep->to_double() );
1391}
1392
1393inline
1394long
1395sc_fxval::to_long() const
1396{
1397    SC_FXVAL_OBSERVER_READ_( *this )
1398    return static_cast<long>( m_rep->to_double() );
1399}
1400
1401inline
1402unsigned int
1403sc_fxval::to_uint() const
1404{
1405    SC_FXVAL_OBSERVER_READ_( *this )
1406    return static_cast<unsigned int>( m_rep->to_double() );
1407}
1408
1409inline
1410unsigned long
1411sc_fxval::to_ulong() const
1412{
1413    SC_FXVAL_OBSERVER_READ_( *this )
1414    return static_cast<unsigned long>( m_rep->to_double() );
1415}
1416
1417inline
1418float
1419sc_fxval::to_float() const
1420{
1421    SC_FXVAL_OBSERVER_READ_( *this )
1422    return static_cast<float>( m_rep->to_double() );
1423}
1424
1425inline
1426double
1427sc_fxval::to_double() const
1428{
1429    SC_FXVAL_OBSERVER_READ_( *this )
1430    return m_rep->to_double();
1431}
1432
1433
1434// query value
1435
1436inline
1437bool
1438sc_fxval::is_neg() const
1439{
1440    SC_FXVAL_OBSERVER_READ_( *this )
1441    return m_rep->is_neg();
1442}
1443
1444inline
1445bool
1446sc_fxval::is_zero() const
1447{
1448    SC_FXVAL_OBSERVER_READ_( *this )
1449    return m_rep->is_zero();
1450}
1451
1452inline
1453bool
1454sc_fxval::is_nan() const
1455{
1456    SC_FXVAL_OBSERVER_READ_( *this )
1457    return m_rep->is_nan();
1458}
1459
1460inline
1461bool
1462sc_fxval::is_inf() const
1463{
1464    SC_FXVAL_OBSERVER_READ_( *this )
1465    return m_rep->is_inf();
1466}
1467
1468inline
1469bool
1470sc_fxval::is_normal() const
1471{
1472    SC_FXVAL_OBSERVER_READ_( *this )
1473    return m_rep->is_normal();
1474}
1475
1476
1477inline
1478bool
1479sc_fxval::rounding_flag() const
1480{
1481    return m_rep->rounding_flag();
1482}
1483
1484
1485// internal use only;
1486inline
1487bool
1488sc_fxval::get_bit( int i ) const
1489{
1490    return m_rep->get_bit( i );
1491}
1492
1493
1494// protected methods and friend functions
1495
1496inline
1497void
1498sc_fxval::get_type( int& wl, int& iwl, sc_enc& enc ) const
1499{
1500    m_rep->get_type( wl, iwl, enc );
1501}
1502
1503
1504inline
1505const sc_fxval
1506sc_fxval::quantization( const scfx_params& params, bool& q_flag ) const
1507{
1508    return sc_fxval( sc_dt::quantization_scfx_rep( *m_rep, params, q_flag ) );
1509}
1510
1511inline
1512const sc_fxval
1513sc_fxval::overflow( const scfx_params& params, bool& o_flag ) const
1514{
1515    return sc_fxval( sc_dt::overflow_scfx_rep( *m_rep, params, o_flag ) );
1516}
1517
1518
1519inline
1520::std::ostream&
1521operator << ( ::std::ostream& os, const sc_fxval& a )
1522{
1523    a.print( os );
1524    return os;
1525}
1526
1527inline
1528::std::istream&
1529operator >> ( ::std::istream& is, sc_fxval& a )
1530{
1531    a.scan( is );
1532    return is;
1533}
1534
1535
1536// ----------------------------------------------------------------------------
1537//  CLASS : sc_fxval_fast
1538//
1539//  Fixed-point value type; limited precision.
1540// ----------------------------------------------------------------------------
1541
1542// protected method
1543
1544inline
1545sc_fxval_fast_observer*
1546sc_fxval_fast::observer() const
1547{
1548    return m_observer;
1549}
1550
1551
1552// public constructors
1553
1554inline
1555sc_fxval_fast::sc_fxval_fast( sc_fxval_fast_observer* observer_ )
1556: m_val( 0.0 ),
1557  m_observer( observer_ )
1558{
1559    SC_FXVAL_FAST_OBSERVER_DEFAULT_
1560    SC_FXVAL_FAST_OBSERVER_CONSTRUCT_( *this )
1561}
1562
1563inline
1564sc_fxval_fast::sc_fxval_fast( const sc_fxval_fast& a,
1565			      sc_fxval_fast_observer* observer_ )
1566: m_val( a.m_val ),
1567  m_observer( observer_ )
1568{
1569    SC_FXVAL_FAST_OBSERVER_DEFAULT_
1570    SC_FXVAL_FAST_OBSERVER_READ_( a )
1571    SC_FXVAL_FAST_OBSERVER_CONSTRUCT_( *this )
1572    SC_FXVAL_FAST_OBSERVER_WRITE_( *this )
1573}
1574
1575#define DEFN_CTOR_T(tp,arg)                                                   \
1576inline                                                                        \
1577sc_fxval_fast::sc_fxval_fast( tp a,                                           \
1578                              sc_fxval_fast_observer* observer_ )             \
1579: m_val( arg ),                                                               \
1580  m_observer( observer_ )                                                     \
1581{                                                                             \
1582    SC_FXVAL_FAST_OBSERVER_DEFAULT_                                           \
1583    SC_FXVAL_FAST_OBSERVER_CONSTRUCT_( *this )                                \
1584    SC_FXVAL_FAST_OBSERVER_WRITE_( *this )                                    \
1585}
1586
1587#define DEFN_CTOR_T_A(tp) DEFN_CTOR_T(tp,static_cast<double>( a ))
1588#define DEFN_CTOR_T_B(tp) DEFN_CTOR_T(tp,from_string( a ))
1589#define DEFN_CTOR_T_C(tp) DEFN_CTOR_T(tp,a.to_double())
1590
1591DEFN_CTOR_T_A(int)
1592DEFN_CTOR_T_A(unsigned int)
1593DEFN_CTOR_T_A(long)
1594DEFN_CTOR_T_A(unsigned long)
1595DEFN_CTOR_T_A(float)
1596DEFN_CTOR_T_A(double)
1597DEFN_CTOR_T_B(const char*)
1598DEFN_CTOR_T_C(const sc_fxval&)
1599#ifndef SC_FX_EXCLUDE_OTHER
1600DEFN_CTOR_T_A(int64)
1601DEFN_CTOR_T_A(uint64)
1602DEFN_CTOR_T_C(const sc_int_base&)
1603DEFN_CTOR_T_C(const sc_uint_base&)
1604DEFN_CTOR_T_C(const sc_signed&)
1605DEFN_CTOR_T_C(const sc_unsigned&)
1606#endif
1607
1608#undef DEFN_CTOR_T
1609#undef DEFN_CTOR_T_A
1610#undef DEFN_CTOR_T_B
1611#undef DEFN_CTOR_T_C
1612#undef DEFN_CTOR_T_D
1613#undef DEFN_CTOR_T_E
1614
1615
1616inline
1617sc_fxval_fast::~sc_fxval_fast()
1618{
1619    SC_FXVAL_FAST_OBSERVER_DESTRUCT_( *this )
1620}
1621
1622
1623// internal use only;
1624inline
1625double
1626sc_fxval_fast::get_val() const
1627{
1628    SC_FXVAL_FAST_OBSERVER_READ_( *this )
1629    return m_val;
1630}
1631
1632// internal use only;
1633inline
1634void
1635sc_fxval_fast::set_val( double val_ )
1636{
1637    m_val = val_;
1638    SC_FXVAL_FAST_OBSERVER_WRITE_( *this )
1639}
1640
1641
1642// unary operators
1643
1644inline
1645const sc_fxval_fast
1646sc_fxval_fast::operator - () const
1647{
1648    SC_FXVAL_FAST_OBSERVER_READ_( *this )
1649    return sc_fxval_fast( - m_val );
1650}
1651
1652inline
1653const sc_fxval_fast&
1654sc_fxval_fast::operator + () const
1655{
1656    // SC_FXVAL_FAST_OBSERVER_READ_( *this )
1657    return *this;
1658}
1659
1660
1661// unary functions
1662
1663inline
1664void
1665neg( sc_fxval_fast& c, const sc_fxval_fast& a )
1666{
1667    SC_FXVAL_FAST_OBSERVER_READ_( a )
1668    c.m_val = - a.m_val;
1669    SC_FXVAL_FAST_OBSERVER_WRITE_( c )
1670}
1671
1672
1673// binary operators
1674
1675#define DEFN_BIN_OP_T(op,tp)                                                  \
1676inline                                                                        \
1677const sc_fxval_fast                                                           \
1678operator op ( const sc_fxval_fast& a, tp b )                                  \
1679{                                                                             \
1680    SC_FXVAL_FAST_OBSERVER_READ_( a )                                         \
1681    sc_fxval_fast tmp( b );                                                   \
1682    return sc_fxval_fast( a.m_val op tmp.m_val );                             \
1683}                                                                             \
1684                                                                              \
1685inline                                                                        \
1686const sc_fxval_fast                                                           \
1687operator op ( tp a, const sc_fxval_fast& b )                                  \
1688{                                                                             \
1689    SC_FXVAL_FAST_OBSERVER_READ_( b )                                         \
1690    sc_fxval_fast tmp( a );                                                   \
1691    return sc_fxval_fast( tmp.m_val op b.m_val );                             \
1692}
1693
1694#ifndef SC_FX_EXCLUDE_OTHER
1695#define DEFN_BIN_OP_OTHER(op)                                                 \
1696DEFN_BIN_OP_T(op,int64)                                                       \
1697DEFN_BIN_OP_T(op,uint64)                                                      \
1698DEFN_BIN_OP_T(op,const sc_int_base&)                                          \
1699DEFN_BIN_OP_T(op,const sc_uint_base&)                                         \
1700DEFN_BIN_OP_T(op,const sc_signed&)                                            \
1701DEFN_BIN_OP_T(op,const sc_unsigned&)
1702#else
1703#define DEFN_BIN_OP_OTHER(op)
1704#endif
1705
1706#define DEFN_BIN_OP(op,dummy)                                                 \
1707inline                                                                        \
1708const sc_fxval_fast                                                           \
1709operator op ( const sc_fxval_fast& a, const sc_fxval_fast& b )                \
1710{                                                                             \
1711    SC_FXVAL_FAST_OBSERVER_READ_( a )                                         \
1712    SC_FXVAL_FAST_OBSERVER_READ_( b )                                         \
1713    return sc_fxval_fast( a.m_val op b.m_val );                               \
1714}                                                                             \
1715                                                                              \
1716DEFN_BIN_OP_T(op,int)                                                         \
1717DEFN_BIN_OP_T(op,unsigned int)                                                \
1718DEFN_BIN_OP_T(op,long)                                                        \
1719DEFN_BIN_OP_T(op,unsigned long)                                               \
1720DEFN_BIN_OP_T(op,float)                                                      \
1721DEFN_BIN_OP_T(op,double)                                                      \
1722DEFN_BIN_OP_T(op,const char*)                                                 \
1723DEFN_BIN_OP_OTHER(op)
1724
1725DEFN_BIN_OP(*,mult)
1726DEFN_BIN_OP(+,add)
1727DEFN_BIN_OP(-,sub)
1728//DEFN_BIN_OP(/,div)
1729inline
1730const sc_fxval_fast
1731operator / ( const sc_fxval_fast& a, const sc_fxval_fast& b )
1732{
1733    SC_FXVAL_FAST_OBSERVER_READ_( a )
1734    SC_FXVAL_FAST_OBSERVER_READ_( b )
1735    return sc_fxval_fast( a.m_val / b.m_val );
1736}
1737
1738DEFN_BIN_OP_T(/,int)
1739DEFN_BIN_OP_T(/,unsigned int)
1740DEFN_BIN_OP_T(/,long)
1741DEFN_BIN_OP_T(/,unsigned long)
1742DEFN_BIN_OP_T(/,float)
1743DEFN_BIN_OP_T(/,double)
1744DEFN_BIN_OP_T(/,const char*)
1745//DEFN_BIN_OP_OTHER(/)
1746#ifndef SC_FX_EXCLUDE_OTHER
1747DEFN_BIN_OP_T(/,int64)
1748DEFN_BIN_OP_T(/,uint64)
1749DEFN_BIN_OP_T(/,const sc_int_base&)
1750DEFN_BIN_OP_T(/,const sc_uint_base&)
1751DEFN_BIN_OP_T(/,const sc_signed&)
1752DEFN_BIN_OP_T(/,const sc_unsigned&)
1753#endif
1754
1755
1756#undef DEFN_BIN_OP_T
1757#undef DEFN_BIN_OP_OTHER
1758#undef DEFN_BIN_OP
1759
1760
1761inline
1762const sc_fxval_fast
1763operator << ( const sc_fxval_fast& a, int b )
1764{
1765    SC_FXVAL_FAST_OBSERVER_READ_( a )
1766    return sc_fxval_fast( a.m_val * scfx_pow2( b ) );
1767}
1768
1769inline
1770const sc_fxval_fast
1771operator >> ( const sc_fxval_fast& a, int b )
1772{
1773    SC_FXVAL_FAST_OBSERVER_READ_( a )
1774    return sc_fxval_fast( a.m_val * scfx_pow2( -b ) );
1775}
1776
1777
1778// binary functions
1779
1780#define DEFN_BIN_FNC_T(fnc,op,tp)                                             \
1781inline                                                                        \
1782void                                                                          \
1783fnc ( sc_fxval_fast& c, const sc_fxval_fast& a, tp b )                        \
1784{                                                                             \
1785    SC_FXVAL_FAST_OBSERVER_READ_( a )                                         \
1786    sc_fxval_fast tmp( b );                                                   \
1787    c.m_val = a.m_val op tmp.m_val;                                           \
1788    SC_FXVAL_FAST_OBSERVER_WRITE_( c )                                        \
1789}                                                                             \
1790                                                                              \
1791inline                                                                        \
1792void                                                                          \
1793fnc ( sc_fxval_fast& c, tp a, const sc_fxval_fast& b )                        \
1794{                                                                             \
1795    SC_FXVAL_FAST_OBSERVER_READ_( b )                                         \
1796    sc_fxval_fast tmp( a );                                                   \
1797    c.m_val = tmp.m_val op b.m_val;                                           \
1798    SC_FXVAL_FAST_OBSERVER_WRITE_( c )                                        \
1799}
1800
1801#ifndef SC_FX_EXCLUDE_OTHER
1802#define DEFN_BIN_FNC_OTHER(fnc,op)                                            \
1803DEFN_BIN_FNC_T(fnc,op,int64)                                                  \
1804DEFN_BIN_FNC_T(fnc,op,uint64)                                                 \
1805DEFN_BIN_FNC_T(fnc,op,const sc_int_base&)                                     \
1806DEFN_BIN_FNC_T(fnc,op,const sc_uint_base&)                                    \
1807DEFN_BIN_FNC_T(fnc,op,const sc_signed&)                                       \
1808DEFN_BIN_FNC_T(fnc,op,const sc_unsigned&)
1809#else
1810#define DEFN_BIN_FNC_OTHER(fnc,op)
1811#endif
1812
1813#define DEFN_BIN_FNC(fnc,op)                                                  \
1814inline                                                                        \
1815void                                                                          \
1816fnc ( sc_fxval_fast& c, const sc_fxval_fast& a, const sc_fxval_fast& b )      \
1817{                                                                             \
1818    SC_FXVAL_FAST_OBSERVER_READ_( a )                                         \
1819    SC_FXVAL_FAST_OBSERVER_READ_( b )                                         \
1820    c.m_val = a.m_val op b.m_val;                                             \
1821    SC_FXVAL_FAST_OBSERVER_WRITE_( c )                                        \
1822}                                                                             \
1823                                                                              \
1824DEFN_BIN_FNC_T(fnc,op,int)                                                    \
1825DEFN_BIN_FNC_T(fnc,op,unsigned int)                                           \
1826DEFN_BIN_FNC_T(fnc,op,long)                                                   \
1827DEFN_BIN_FNC_T(fnc,op,unsigned long)                                          \
1828DEFN_BIN_FNC_T(fnc,op,float)                                                 \
1829DEFN_BIN_FNC_T(fnc,op,double)                                                 \
1830DEFN_BIN_FNC_T(fnc,op,const char*)                                            \
1831DEFN_BIN_FNC_OTHER(fnc,op)
1832
1833DEFN_BIN_FNC(mult,*)
1834DEFN_BIN_FNC(div,/)
1835DEFN_BIN_FNC(add,+)
1836DEFN_BIN_FNC(sub,-)
1837
1838#undef DEFN_BIN_FNC_T
1839#undef DEFN_BIN_FNC_OTHER
1840#undef DEFN_BIN_FNC
1841
1842
1843inline
1844void
1845lshift( sc_fxval_fast& c, const sc_fxval_fast& a, int b )
1846{
1847    SC_FXVAL_FAST_OBSERVER_READ_( a )
1848    c.m_val = a.m_val * scfx_pow2( b );
1849    SC_FXVAL_FAST_OBSERVER_WRITE_( c )
1850}
1851
1852inline
1853void
1854rshift( sc_fxval_fast& c, const sc_fxval_fast& a, int b )
1855{
1856    SC_FXVAL_FAST_OBSERVER_READ_( a )
1857    c.m_val = a.m_val * scfx_pow2( -b );
1858    SC_FXVAL_FAST_OBSERVER_WRITE_( c )
1859}
1860
1861
1862// relational (including equality) operators
1863
1864#define DEFN_REL_OP_T(op,tp)                                                  \
1865inline                                                                        \
1866bool                                                                          \
1867operator op ( const sc_fxval_fast& a, tp b )                                  \
1868{                                                                             \
1869    SC_FXVAL_FAST_OBSERVER_READ_( a )                                         \
1870    sc_fxval_fast tmp( b );                                                   \
1871    return ( a.m_val op tmp.m_val );                                          \
1872}                                                                             \
1873                                                                              \
1874inline                                                                        \
1875bool                                                                          \
1876operator op ( tp a, const sc_fxval_fast& b )                                  \
1877{                                                                             \
1878    SC_FXVAL_FAST_OBSERVER_READ_( b )                                         \
1879    sc_fxval_fast tmp( a );                                                   \
1880    return ( tmp.m_val op b.m_val );                                          \
1881}
1882
1883#ifndef SC_FX_EXCLUDE_OTHER
1884#define DEFN_REL_OP_OTHER(op)                                                 \
1885DEFN_REL_OP_T(op,int64)                                                       \
1886DEFN_REL_OP_T(op,uint64)                                                      \
1887DEFN_REL_OP_T(op,const sc_int_base&)                                          \
1888DEFN_REL_OP_T(op,const sc_uint_base&)                                         \
1889DEFN_REL_OP_T(op,const sc_signed&)                                            \
1890DEFN_REL_OP_T(op,const sc_unsigned&)
1891#else
1892#define DEFN_REL_OP_OTHER(op)
1893#endif
1894
1895#define DEFN_REL_OP(op)                                                       \
1896inline                                                                        \
1897bool                                                                          \
1898operator op ( const sc_fxval_fast& a, const sc_fxval_fast& b )                \
1899{                                                                             \
1900    SC_FXVAL_FAST_OBSERVER_READ_( a )                                         \
1901    SC_FXVAL_FAST_OBSERVER_READ_( b )                                         \
1902    return ( a.m_val op b.m_val );                                            \
1903}                                                                             \
1904                                                                              \
1905DEFN_REL_OP_T(op,int)                                                         \
1906DEFN_REL_OP_T(op,unsigned int)                                                \
1907DEFN_REL_OP_T(op,long)                                                        \
1908DEFN_REL_OP_T(op,unsigned long)                                               \
1909DEFN_REL_OP_T(op,float)                                                      \
1910DEFN_REL_OP_T(op,double)                                                      \
1911DEFN_REL_OP_T(op,const char*)                                                 \
1912DEFN_REL_OP_OTHER(op)
1913
1914DEFN_REL_OP(<)
1915DEFN_REL_OP(<=)
1916DEFN_REL_OP(>)
1917DEFN_REL_OP(>=)
1918DEFN_REL_OP(==)
1919DEFN_REL_OP(!=)
1920
1921#undef DEFN_REL_OP_T
1922#undef DEFN_REL_OP_OTHER
1923#undef DEFN_REL_OP
1924
1925
1926// assignment operators
1927
1928inline
1929sc_fxval_fast&
1930sc_fxval_fast::operator = ( const sc_fxval_fast& a )
1931{
1932    if( &a != this )
1933    {
1934	SC_FXVAL_FAST_OBSERVER_READ_( a )
1935	m_val = a.m_val;
1936	SC_FXVAL_FAST_OBSERVER_WRITE_( *this )
1937    }
1938    return *this;
1939}
1940
1941#define DEFN_ASN_OP_T(tp)                                                     \
1942inline                                                                        \
1943sc_fxval_fast&                                                                \
1944sc_fxval_fast::operator = ( tp a )                                            \
1945{                                                                             \
1946    sc_fxval_fast tmp( a );                                                   \
1947    m_val = tmp.m_val;                                                        \
1948    SC_FXVAL_FAST_OBSERVER_WRITE_( *this )                                    \
1949    return *this;                                                             \
1950}
1951
1952DEFN_ASN_OP_T(int)
1953DEFN_ASN_OP_T(unsigned int)
1954DEFN_ASN_OP_T(long)
1955DEFN_ASN_OP_T(unsigned long)
1956DEFN_ASN_OP_T(float)
1957DEFN_ASN_OP_T(double)
1958DEFN_ASN_OP_T(const char*)
1959DEFN_ASN_OP_T(const sc_fxval&)
1960#ifndef SC_FX_EXCLUDE_OTHER
1961DEFN_ASN_OP_T(int64)
1962DEFN_ASN_OP_T(uint64)
1963DEFN_ASN_OP_T(const sc_int_base&)
1964DEFN_ASN_OP_T(const sc_uint_base&)
1965DEFN_ASN_OP_T(const sc_signed&)
1966DEFN_ASN_OP_T(const sc_unsigned&)
1967#endif
1968
1969#undef DEFN_ASN_OP_T
1970
1971
1972#define DEFN_ASN_OP_T(op,tp)                                                  \
1973inline                                                                        \
1974sc_fxval_fast&                                                                \
1975sc_fxval_fast::operator op ( tp b )                                           \
1976{                                                                             \
1977    SC_FXVAL_FAST_OBSERVER_READ_( *this )                                     \
1978    sc_fxval_fast tmp( b );                                                   \
1979    m_val op tmp.m_val;                                                       \
1980    SC_FXVAL_FAST_OBSERVER_WRITE_( *this )                                    \
1981    return *this;                                                             \
1982}
1983
1984#ifndef SC_FX_EXCLUDE_OTHER
1985#define DEFN_ASN_OP_OTHER(op)                                                 \
1986DEFN_ASN_OP_T(op,int64)                                                       \
1987DEFN_ASN_OP_T(op,uint64)                                                      \
1988DEFN_ASN_OP_T(op,const sc_int_base&)                                          \
1989DEFN_ASN_OP_T(op,const sc_uint_base&)                                         \
1990DEFN_ASN_OP_T(op,const sc_signed&)                                            \
1991DEFN_ASN_OP_T(op,const sc_unsigned&)
1992#else
1993#define DEFN_ASN_OP_OTHER(op)
1994#endif
1995
1996#define DEFN_ASN_OP(op)                                                       \
1997inline                                                                        \
1998sc_fxval_fast&                                                                \
1999sc_fxval_fast::operator op ( const sc_fxval_fast& b )                         \
2000{                                                                             \
2001    SC_FXVAL_FAST_OBSERVER_READ_( *this )                                     \
2002    SC_FXVAL_FAST_OBSERVER_READ_( b )                                         \
2003    m_val op b.m_val;                                                         \
2004    SC_FXVAL_FAST_OBSERVER_WRITE_( *this )                                    \
2005    return *this;                                                             \
2006}                                                                             \
2007                                                                              \
2008DEFN_ASN_OP_T(op,int)                                                         \
2009DEFN_ASN_OP_T(op,unsigned int)                                                \
2010DEFN_ASN_OP_T(op,long)                                                        \
2011DEFN_ASN_OP_T(op,unsigned long)                                               \
2012DEFN_ASN_OP_T(op,float)                                                      \
2013DEFN_ASN_OP_T(op,double)                                                      \
2014DEFN_ASN_OP_T(op,const char*)                                                 \
2015DEFN_ASN_OP_T(op,const sc_fxval&)                                             \
2016DEFN_ASN_OP_OTHER(op)
2017
2018DEFN_ASN_OP(*=)
2019DEFN_ASN_OP(/=)
2020DEFN_ASN_OP(+=)
2021DEFN_ASN_OP(-=)
2022
2023#undef DEFN_ASN_OP_T
2024#undef DEFN_ASN_OP_OTHER
2025#undef DEFN_ASN_OP
2026
2027
2028inline
2029sc_fxval_fast&
2030sc_fxval_fast::operator <<= ( int b )
2031{
2032    SC_FXVAL_FAST_OBSERVER_READ_( *this )
2033    m_val *= scfx_pow2( b );
2034    SC_FXVAL_FAST_OBSERVER_WRITE_( *this )
2035    return *this;
2036}
2037
2038inline
2039sc_fxval_fast&
2040sc_fxval_fast::operator >>= ( int b )
2041{
2042    SC_FXVAL_FAST_OBSERVER_READ_( *this )
2043    m_val *= scfx_pow2( -b );
2044    SC_FXVAL_FAST_OBSERVER_WRITE_( *this )
2045    return *this;
2046}
2047
2048
2049// auto-increment and auto-decrement
2050
2051inline
2052const sc_fxval_fast
2053sc_fxval_fast::operator ++ ( int )
2054{
2055    SC_FXVAL_FAST_OBSERVER_READ_( *this )
2056    SC_FXVAL_FAST_OBSERVER_READ_( *this )
2057    double c = m_val;
2058    m_val = m_val + 1;
2059    SC_FXVAL_FAST_OBSERVER_WRITE_( *this )
2060    return sc_fxval_fast( c );
2061}
2062
2063inline
2064const sc_fxval_fast
2065sc_fxval_fast::operator -- ( int )
2066{
2067    SC_FXVAL_FAST_OBSERVER_READ_( *this )
2068    SC_FXVAL_FAST_OBSERVER_READ_( *this )
2069    double c = m_val;
2070    m_val = m_val - 1;
2071    SC_FXVAL_FAST_OBSERVER_WRITE_( *this )
2072    return sc_fxval_fast( c );
2073}
2074
2075inline
2076sc_fxval_fast&
2077sc_fxval_fast::operator ++ ()
2078{
2079    SC_FXVAL_FAST_OBSERVER_READ_( *this )
2080    m_val = m_val + 1;
2081    SC_FXVAL_FAST_OBSERVER_WRITE_( *this )
2082    return *this;
2083}
2084
2085inline
2086sc_fxval_fast&
2087sc_fxval_fast::operator -- ()
2088{
2089    SC_FXVAL_FAST_OBSERVER_READ_( *this )
2090    m_val = m_val - 1;
2091    SC_FXVAL_FAST_OBSERVER_WRITE_( *this )
2092    return *this;
2093}
2094
2095
2096// implicit conversion
2097
2098inline
2099sc_fxval_fast::operator double() const
2100{
2101    SC_FXVAL_FAST_OBSERVER_READ_( *this )
2102    return m_val;
2103}
2104
2105
2106// explicit conversion to primitive types
2107
2108inline
2109short
2110sc_fxval_fast::to_short() const
2111{
2112    SC_FXVAL_FAST_OBSERVER_READ_( *this )
2113    return static_cast<short>( m_val );
2114}
2115
2116inline
2117unsigned short
2118sc_fxval_fast::to_ushort() const
2119{
2120    SC_FXVAL_FAST_OBSERVER_READ_( *this )
2121    return static_cast<unsigned short>( m_val );
2122}
2123
2124inline
2125int64
2126sc_fxval_fast::to_int64() const
2127{
2128    SC_FXVAL_FAST_OBSERVER_READ_( *this )
2129    return static_cast<int64>( m_val );
2130}
2131
2132inline
2133int
2134sc_fxval_fast::to_int() const
2135{
2136    SC_FXVAL_FAST_OBSERVER_READ_( *this )
2137    return static_cast<int>( m_val );
2138}
2139
2140inline
2141unsigned int
2142sc_fxval_fast::to_uint() const
2143{
2144    SC_FXVAL_FAST_OBSERVER_READ_( *this )
2145    return static_cast<unsigned int>( m_val );
2146}
2147
2148inline
2149uint64
2150sc_fxval_fast::to_uint64() const
2151{
2152    SC_FXVAL_FAST_OBSERVER_READ_( *this )
2153    return static_cast<uint64>( m_val );
2154}
2155
2156inline
2157long
2158sc_fxval_fast::to_long() const
2159{
2160    SC_FXVAL_FAST_OBSERVER_READ_( *this )
2161    return static_cast<long>( m_val );
2162}
2163
2164inline
2165unsigned long
2166sc_fxval_fast::to_ulong() const
2167{
2168    SC_FXVAL_FAST_OBSERVER_READ_( *this )
2169    return static_cast<unsigned long>( m_val );
2170}
2171
2172inline
2173float
2174sc_fxval_fast::to_float() const
2175{
2176    SC_FXVAL_FAST_OBSERVER_READ_( *this )
2177    return static_cast<float>( m_val );
2178}
2179
2180inline
2181double
2182sc_fxval_fast::to_double() const
2183{
2184    SC_FXVAL_FAST_OBSERVER_READ_( *this )
2185    return m_val;
2186}
2187
2188
2189// query value
2190
2191inline
2192bool
2193sc_fxval_fast::is_neg() const
2194{
2195    SC_FXVAL_FAST_OBSERVER_READ_( *this )
2196    scfx_ieee_double id( m_val );
2197    return ( id.negative() != 0 );
2198}
2199
2200inline
2201bool
2202sc_fxval_fast::is_zero() const
2203{
2204    SC_FXVAL_FAST_OBSERVER_READ_( *this )
2205    scfx_ieee_double id( m_val );
2206    return id.is_zero();
2207}
2208
2209inline
2210bool
2211sc_fxval_fast::is_nan() const
2212{
2213    SC_FXVAL_FAST_OBSERVER_READ_( *this )
2214    scfx_ieee_double id( m_val );
2215    return id.is_nan();
2216}
2217
2218inline
2219bool
2220sc_fxval_fast::is_inf() const
2221{
2222    SC_FXVAL_FAST_OBSERVER_READ_( *this )
2223    scfx_ieee_double id( m_val );
2224    return id.is_inf();
2225}
2226
2227inline
2228bool
2229sc_fxval_fast::is_normal() const
2230{
2231    SC_FXVAL_FAST_OBSERVER_READ_( *this )
2232    scfx_ieee_double id( m_val );
2233    return ( id.is_normal() || id.is_subnormal() || id.is_zero() );
2234}
2235
2236
2237inline
2238bool
2239sc_fxval_fast::rounding_flag() const
2240{
2241    // does not apply to sc_fxval_fast; included for API compatibility
2242    return false;
2243}
2244
2245
2246inline
2247::std::ostream&
2248operator << ( ::std::ostream& os, const sc_fxval_fast& a )
2249{
2250    a.print( os );
2251    return os;
2252}
2253
2254inline
2255::std::istream&
2256operator >> ( ::std::istream& is, sc_fxval_fast& a )
2257{
2258    a.scan( is );
2259    return is;
2260}
2261
2262} // namespace sc_dt
2263
2264#undef SCFX_EXPLICIT_
2265#undef SCFX_EXPLICIT_OTHER_
2266
2267#endif
2268
2269// Taf!
2270