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