112853Sgabeblack@google.com/*****************************************************************************
212853Sgabeblack@google.com
312853Sgabeblack@google.com  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
412853Sgabeblack@google.com  more contributor license agreements.  See the NOTICE file distributed
512853Sgabeblack@google.com  with this work for additional information regarding copyright ownership.
612853Sgabeblack@google.com  Accellera licenses this file to you under the Apache License, Version 2.0
712853Sgabeblack@google.com  (the "License"); you may not use this file except in compliance with the
812853Sgabeblack@google.com  License.  You may obtain a copy of the License at
912853Sgabeblack@google.com
1012853Sgabeblack@google.com    http://www.apache.org/licenses/LICENSE-2.0
1112853Sgabeblack@google.com
1212853Sgabeblack@google.com  Unless required by applicable law or agreed to in writing, software
1312853Sgabeblack@google.com  distributed under the License is distributed on an "AS IS" BASIS,
1412853Sgabeblack@google.com  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
1512853Sgabeblack@google.com  implied.  See the License for the specific language governing
1612853Sgabeblack@google.com  permissions and limitations under the License.
1712853Sgabeblack@google.com
1812853Sgabeblack@google.com *****************************************************************************/
1912853Sgabeblack@google.com
2012853Sgabeblack@google.com/*****************************************************************************
2112853Sgabeblack@google.com
2212853Sgabeblack@google.com  sc_fxval.h -
2312853Sgabeblack@google.com
2412853Sgabeblack@google.com  Original Author: Martin Janssen, Synopsys, Inc.
2512853Sgabeblack@google.com
2612853Sgabeblack@google.com *****************************************************************************/
2712853Sgabeblack@google.com
2812853Sgabeblack@google.com/*****************************************************************************
2912853Sgabeblack@google.com
3012853Sgabeblack@google.com  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
3112853Sgabeblack@google.com  changes you are making here.
3212853Sgabeblack@google.com
3312853Sgabeblack@google.com      Name, Affiliation, Date:
3412853Sgabeblack@google.com  Description of Modification:
3512853Sgabeblack@google.com
3612853Sgabeblack@google.com *****************************************************************************/
3712853Sgabeblack@google.com
3812853Sgabeblack@google.com// $Log: sc_fxval.h,v $
3912853Sgabeblack@google.com// Revision 1.3  2011/01/19 18:57:40  acg
4012853Sgabeblack@google.com//  Andy Goodrich: changes for IEEE_1666_2011.
4112853Sgabeblack@google.com//
4212853Sgabeblack@google.com// Revision 1.2  2010/12/07 20:09:08  acg
4312853Sgabeblack@google.com// Andy Goodrich: Philipp Hartmann's constructor disambiguation fix
4412853Sgabeblack@google.com//
4512853Sgabeblack@google.com// Revision 1.1.1.1  2006/12/15 20:20:04  acg
4612853Sgabeblack@google.com// SystemC 2.3
4712853Sgabeblack@google.com//
4812853Sgabeblack@google.com// Revision 1.3  2006/01/13 18:53:58  acg
4912853Sgabeblack@google.com// Andy Goodrich: added $Log command so that CVS comments are reproduced in
5012853Sgabeblack@google.com// the source.
5112853Sgabeblack@google.com//
5212853Sgabeblack@google.com
5312853Sgabeblack@google.com#ifndef __SYSTEMC_EXT_DT_FX_SC_FXVAL_HH__
5412853Sgabeblack@google.com#define __SYSTEMC_EXT_DT_FX_SC_FXVAL_HH__
5512853Sgabeblack@google.com
5612853Sgabeblack@google.com#include <iostream>
5712853Sgabeblack@google.com
5812853Sgabeblack@google.com#include "../int/sc_int_base.hh"
5912853Sgabeblack@google.com#include "../int/sc_signed.hh"
6012853Sgabeblack@google.com#include "../int/sc_uint_base.hh"
6112853Sgabeblack@google.com#include "../int/sc_unsigned.hh"
6212853Sgabeblack@google.com#include "sc_fxval_observer.hh"
6312853Sgabeblack@google.com#include "scfx_rep.hh"
6412853Sgabeblack@google.com
6512853Sgabeblack@google.com#define SCFX_EXPLICIT_ explicit
6612853Sgabeblack@google.com#define SCFX_EXPLICIT_OTHER_ explicit
6712853Sgabeblack@google.com
6812853Sgabeblack@google.comnamespace sc_dt
6912853Sgabeblack@google.com{
7012853Sgabeblack@google.com
7112853Sgabeblack@google.com// classes defined in this module
7212853Sgabeblack@google.comclass sc_fxval;
7312853Sgabeblack@google.comclass sc_fxval_fast;
7412853Sgabeblack@google.com
7512853Sgabeblack@google.com// forward class declarations
7612853Sgabeblack@google.comclass sc_fxnum;
7712853Sgabeblack@google.comclass sc_fxnum_fast;
7812853Sgabeblack@google.com
7912853Sgabeblack@google.com
8012853Sgabeblack@google.com// ----------------------------------------------------------------------------
8112853Sgabeblack@google.com//  CLASS : sc_fxval
8212853Sgabeblack@google.com//
8312853Sgabeblack@google.com//  Fixed-point value type; arbitrary precision.
8412853Sgabeblack@google.com// ----------------------------------------------------------------------------
8512853Sgabeblack@google.com
8612853Sgabeblack@google.comclass sc_fxval
8712853Sgabeblack@google.com{
8812853Sgabeblack@google.com    friend class sc_fxnum;
8912853Sgabeblack@google.com
9012853Sgabeblack@google.com  protected:
9112853Sgabeblack@google.com    sc_fxval_observer* observer() const;
9212853Sgabeblack@google.com
9312853Sgabeblack@google.com  public:
9412853Sgabeblack@google.com    // internal use only;
9512853Sgabeblack@google.com    explicit sc_fxval(scfx_rep *);
9612853Sgabeblack@google.com
9712853Sgabeblack@google.com    explicit sc_fxval(sc_fxval_observer * =0);
9812853Sgabeblack@google.com    explicit sc_fxval(int, sc_fxval_observer * =0);
9912853Sgabeblack@google.com    explicit sc_fxval(unsigned int, sc_fxval_observer * =0);
10012853Sgabeblack@google.com    explicit sc_fxval(long, sc_fxval_observer * =0);
10112853Sgabeblack@google.com    explicit sc_fxval(unsigned long, sc_fxval_observer * =0);
10212853Sgabeblack@google.com    explicit sc_fxval(float, sc_fxval_observer* = 0);
10312853Sgabeblack@google.com    explicit sc_fxval(double, sc_fxval_observer* = 0);
10412853Sgabeblack@google.com    explicit sc_fxval(const char *, sc_fxval_observer* = 0);
10512853Sgabeblack@google.com    sc_fxval(const sc_fxval &, sc_fxval_observer* = 0);
10612853Sgabeblack@google.com    sc_fxval(const sc_fxval_fast &, sc_fxval_observer* = 0);
10712853Sgabeblack@google.com    sc_fxval(const sc_fxnum &, sc_fxval_observer* = 0);
10812853Sgabeblack@google.com    sc_fxval(const sc_fxnum_fast &, sc_fxval_observer* = 0);
10912853Sgabeblack@google.com
11012853Sgabeblack@google.com    explicit sc_fxval(int64, sc_fxval_observer* = 0);
11112853Sgabeblack@google.com    explicit sc_fxval(uint64, sc_fxval_observer* = 0);
11212853Sgabeblack@google.com    explicit sc_fxval(const sc_int_base &, sc_fxval_observer* = 0);
11312853Sgabeblack@google.com    explicit sc_fxval(const sc_uint_base &, sc_fxval_observer* = 0);
11412853Sgabeblack@google.com    explicit sc_fxval(const sc_signed &, sc_fxval_observer* = 0);
11512853Sgabeblack@google.com    explicit sc_fxval(const sc_unsigned &, sc_fxval_observer* = 0);
11612853Sgabeblack@google.com
11712853Sgabeblack@google.com    ~sc_fxval();
11812853Sgabeblack@google.com
11912853Sgabeblack@google.com    // internal use only;
12012853Sgabeblack@google.com    const scfx_rep *get_rep() const;
12112853Sgabeblack@google.com    void set_rep(scfx_rep *);
12212853Sgabeblack@google.com
12312853Sgabeblack@google.com    // unary operators
12412853Sgabeblack@google.com    const sc_fxval operator - () const;
12512853Sgabeblack@google.com    const sc_fxval &operator + () const;
12612853Sgabeblack@google.com
12712853Sgabeblack@google.com    // unary functions
12812853Sgabeblack@google.com    friend void neg(sc_fxval &, const sc_fxval &);
12912853Sgabeblack@google.com
13012853Sgabeblack@google.com    // binary operators
13112853Sgabeblack@google.com#define DECL_BIN_OP_T(op,tp) \
13212853Sgabeblack@google.com    friend const sc_fxval operator op (const sc_fxval &, tp); \
13312853Sgabeblack@google.com    friend const sc_fxval operator op (tp, const sc_fxval &);
13412853Sgabeblack@google.com
13512853Sgabeblack@google.com#define DECL_BIN_OP_OTHER(op) \
13612853Sgabeblack@google.com    DECL_BIN_OP_T(op, int64) \
13712853Sgabeblack@google.com    DECL_BIN_OP_T(op, uint64) \
13812853Sgabeblack@google.com    DECL_BIN_OP_T(op, const sc_int_base &) \
13912853Sgabeblack@google.com    DECL_BIN_OP_T(op, const sc_uint_base &) \
14012853Sgabeblack@google.com    DECL_BIN_OP_T(op, const sc_signed &) \
14112853Sgabeblack@google.com    DECL_BIN_OP_T(op, const sc_unsigned &)
14212853Sgabeblack@google.com
14312853Sgabeblack@google.com#define DECL_BIN_OP(op, dummy) \
14412853Sgabeblack@google.com    friend const sc_fxval operator op (const sc_fxval &, const sc_fxval &); \
14512853Sgabeblack@google.com    DECL_BIN_OP_T(op, int) \
14612853Sgabeblack@google.com    DECL_BIN_OP_T(op, unsigned int) \
14712853Sgabeblack@google.com    DECL_BIN_OP_T(op, long) \
14812853Sgabeblack@google.com    DECL_BIN_OP_T(op, unsigned long) \
14912853Sgabeblack@google.com    DECL_BIN_OP_T(op, float) \
15012853Sgabeblack@google.com    DECL_BIN_OP_T(op, double) \
15112853Sgabeblack@google.com    DECL_BIN_OP_T(op, const char *) \
15212853Sgabeblack@google.com    DECL_BIN_OP_T(op, const sc_fxval_fast &) \
15312853Sgabeblack@google.com    DECL_BIN_OP_T(op, const sc_fxnum_fast &) \
15412853Sgabeblack@google.com    DECL_BIN_OP_OTHER(op)
15512853Sgabeblack@google.com
15612853Sgabeblack@google.com    DECL_BIN_OP(*, mult)
15712853Sgabeblack@google.com    DECL_BIN_OP(+, add)
15812853Sgabeblack@google.com    DECL_BIN_OP(-, sub)
15912853Sgabeblack@google.com// declaration below doesn't compile with BCB5 (E2206)
16012853Sgabeblack@google.com//    DECL_BIN_OP(/, div)
16112853Sgabeblack@google.com// previous macro expanded
16212853Sgabeblack@google.com    friend const sc_fxval operator / (const sc_fxval &, const sc_fxval &);
16312853Sgabeblack@google.com    DECL_BIN_OP_T(/, int)
16412853Sgabeblack@google.com    DECL_BIN_OP_T(/, unsigned int)
16512853Sgabeblack@google.com    DECL_BIN_OP_T(/, long)
16612853Sgabeblack@google.com    DECL_BIN_OP_T(/, unsigned long)
16712853Sgabeblack@google.com    DECL_BIN_OP_T(/, float)
16812853Sgabeblack@google.com    DECL_BIN_OP_T(/, double)
16912853Sgabeblack@google.com    DECL_BIN_OP_T(/, const char *)
17012853Sgabeblack@google.com    DECL_BIN_OP_T(/, const sc_fxval_fast &)
17112853Sgabeblack@google.com    DECL_BIN_OP_T(/, const sc_fxnum_fast &)
17212853Sgabeblack@google.com//    DECL_BIN_OP_OTHER(/)
17312853Sgabeblack@google.com
17412853Sgabeblack@google.com    DECL_BIN_OP_T(/, int64)
17512853Sgabeblack@google.com    DECL_BIN_OP_T(/, uint64)
17612853Sgabeblack@google.com    DECL_BIN_OP_T(/, const sc_int_base &)
17712853Sgabeblack@google.com    DECL_BIN_OP_T(/, const sc_uint_base &)
17812853Sgabeblack@google.com    DECL_BIN_OP_T(/, const sc_signed &)
17912853Sgabeblack@google.com    DECL_BIN_OP_T(/, const sc_unsigned &)
18012853Sgabeblack@google.com
18112853Sgabeblack@google.com#undef DECL_BIN_OP_T
18212853Sgabeblack@google.com#undef DECL_BIN_OP_OTHER
18312853Sgabeblack@google.com#undef DECL_BIN_OP
18412853Sgabeblack@google.com
18512853Sgabeblack@google.com    friend const sc_fxval operator << (const sc_fxval &, int);
18612853Sgabeblack@google.com    friend const sc_fxval operator >> (const sc_fxval &, int);
18712853Sgabeblack@google.com
18812853Sgabeblack@google.com    // binary functions
18912853Sgabeblack@google.com#define DECL_BIN_FNC_T(fnc, tp) \
19012853Sgabeblack@google.com    friend void fnc (sc_fxval &, const sc_fxval &, tp); \
19112853Sgabeblack@google.com    friend void fnc (sc_fxval &, tp, const sc_fxval &);
19212853Sgabeblack@google.com
19312853Sgabeblack@google.com#define DECL_BIN_FNC_OTHER(fnc) \
19412853Sgabeblack@google.com    DECL_BIN_FNC_T(fnc, int64) \
19512853Sgabeblack@google.com    DECL_BIN_FNC_T(fnc, uint64) \
19612853Sgabeblack@google.com    DECL_BIN_FNC_T(fnc, const sc_int_base &) \
19712853Sgabeblack@google.com    DECL_BIN_FNC_T(fnc, const sc_uint_base &) \
19812853Sgabeblack@google.com    DECL_BIN_FNC_T(fnc, const sc_signed &) \
19912853Sgabeblack@google.com    DECL_BIN_FNC_T(fnc, const sc_unsigned &)
20012853Sgabeblack@google.com
20112853Sgabeblack@google.com#define DECL_BIN_FNC(fnc) \
20212853Sgabeblack@google.com    friend void fnc (sc_fxval &, const sc_fxval &, const sc_fxval &); \
20312853Sgabeblack@google.com    DECL_BIN_FNC_T(fnc, int) \
20412853Sgabeblack@google.com    DECL_BIN_FNC_T(fnc, unsigned int) \
20512853Sgabeblack@google.com    DECL_BIN_FNC_T(fnc, long) \
20612853Sgabeblack@google.com    DECL_BIN_FNC_T(fnc, unsigned long) \
20712853Sgabeblack@google.com    DECL_BIN_FNC_T(fnc, float) \
20812853Sgabeblack@google.com    DECL_BIN_FNC_T(fnc, double) \
20912853Sgabeblack@google.com    DECL_BIN_FNC_T(fnc, const char *) \
21012853Sgabeblack@google.com    DECL_BIN_FNC_T(fnc, const sc_fxval_fast &) \
21112853Sgabeblack@google.com    DECL_BIN_FNC_T(fnc, const sc_fxnum_fast &) \
21212853Sgabeblack@google.com    DECL_BIN_FNC_OTHER(fnc)
21312853Sgabeblack@google.com
21412853Sgabeblack@google.com    DECL_BIN_FNC(mult)
21512853Sgabeblack@google.com    DECL_BIN_FNC(div)
21612853Sgabeblack@google.com    DECL_BIN_FNC(add)
21712853Sgabeblack@google.com    DECL_BIN_FNC(sub)
21812853Sgabeblack@google.com
21912853Sgabeblack@google.com#undef DECL_BIN_FNC_T
22012853Sgabeblack@google.com#undef DECL_BIN_FNC_OTHER
22112853Sgabeblack@google.com#undef DECL_BIN_FNC
22212853Sgabeblack@google.com
22312853Sgabeblack@google.com    friend void lshift(sc_fxval &, const sc_fxval &, int);
22412853Sgabeblack@google.com    friend void rshift(sc_fxval &, const sc_fxval &, int);
22512853Sgabeblack@google.com
22612853Sgabeblack@google.com    // relational (including equality) operators
22712853Sgabeblack@google.com#define DECL_REL_OP_T(op, tp) \
22812853Sgabeblack@google.com    friend bool operator op (const sc_fxval &, tp); \
22912853Sgabeblack@google.com    friend bool operator op (tp, const sc_fxval &);
23012853Sgabeblack@google.com
23112853Sgabeblack@google.com#define DECL_REL_OP_OTHER(op) \
23212853Sgabeblack@google.com    DECL_REL_OP_T(op, int64) \
23312853Sgabeblack@google.com    DECL_REL_OP_T(op, uint64) \
23412853Sgabeblack@google.com    DECL_REL_OP_T(op, const sc_int_base &) \
23512853Sgabeblack@google.com    DECL_REL_OP_T(op, const sc_uint_base &) \
23612853Sgabeblack@google.com    DECL_REL_OP_T(op, const sc_signed &) \
23712853Sgabeblack@google.com    DECL_REL_OP_T(op, const sc_unsigned &)
23812853Sgabeblack@google.com
23912853Sgabeblack@google.com#define DECL_REL_OP(op) \
24012853Sgabeblack@google.com    friend bool operator op (const sc_fxval &, const sc_fxval &); \
24112853Sgabeblack@google.com    DECL_REL_OP_T(op, int) \
24212853Sgabeblack@google.com    DECL_REL_OP_T(op, unsigned int) \
24312853Sgabeblack@google.com    DECL_REL_OP_T(op, long) \
24412853Sgabeblack@google.com    DECL_REL_OP_T(op, unsigned long) \
24512853Sgabeblack@google.com    DECL_REL_OP_T(op, float) \
24612853Sgabeblack@google.com    DECL_REL_OP_T(op, double) \
24712853Sgabeblack@google.com    DECL_REL_OP_T(op, const char *) \
24812853Sgabeblack@google.com    DECL_REL_OP_T(op, const sc_fxval_fast &) \
24912853Sgabeblack@google.com    DECL_REL_OP_T(op, const sc_fxnum_fast &) \
25012853Sgabeblack@google.com    DECL_REL_OP_OTHER(op)
25112853Sgabeblack@google.com
25212853Sgabeblack@google.com    DECL_REL_OP(<)
25312853Sgabeblack@google.com    DECL_REL_OP(<=)
25412853Sgabeblack@google.com    DECL_REL_OP(>)
25512853Sgabeblack@google.com    DECL_REL_OP(>=)
25612853Sgabeblack@google.com    DECL_REL_OP(==)
25712853Sgabeblack@google.com    DECL_REL_OP(!=)
25812853Sgabeblack@google.com
25912853Sgabeblack@google.com#undef DECL_REL_OP_T
26012853Sgabeblack@google.com#undef DECL_REL_OP_OTHER
26112853Sgabeblack@google.com#undef DECL_REL_OP
26212853Sgabeblack@google.com
26312853Sgabeblack@google.com    // assignment operators
26412853Sgabeblack@google.com#define DECL_ASN_OP_T(op, tp) sc_fxval &operator op(tp);
26512853Sgabeblack@google.com
26612853Sgabeblack@google.com#define DECL_ASN_OP_OTHER(op) \
26712853Sgabeblack@google.com    DECL_ASN_OP_T(op, int64) \
26812853Sgabeblack@google.com    DECL_ASN_OP_T(op, uint64) \
26912853Sgabeblack@google.com    DECL_ASN_OP_T(op, const sc_int_base &) \
27012853Sgabeblack@google.com    DECL_ASN_OP_T(op, const sc_uint_base &) \
27112853Sgabeblack@google.com    DECL_ASN_OP_T(op, const sc_signed &) \
27212853Sgabeblack@google.com    DECL_ASN_OP_T(op, const sc_unsigned &)
27312853Sgabeblack@google.com
27412853Sgabeblack@google.com#define DECL_ASN_OP(op) \
27512853Sgabeblack@google.com    DECL_ASN_OP_T(op, int) \
27612853Sgabeblack@google.com    DECL_ASN_OP_T(op, unsigned int) \
27712853Sgabeblack@google.com    DECL_ASN_OP_T(op, long) \
27812853Sgabeblack@google.com    DECL_ASN_OP_T(op, unsigned long) \
27912853Sgabeblack@google.com    DECL_ASN_OP_T(op, float) \
28012853Sgabeblack@google.com    DECL_ASN_OP_T(op, double) \
28112853Sgabeblack@google.com    DECL_ASN_OP_T(op, const char *) \
28212853Sgabeblack@google.com    DECL_ASN_OP_T(op, const sc_fxval &) \
28312853Sgabeblack@google.com    DECL_ASN_OP_T(op, const sc_fxval_fast &) \
28412853Sgabeblack@google.com    DECL_ASN_OP_T(op, const sc_fxnum &) \
28512853Sgabeblack@google.com    DECL_ASN_OP_T(op, const sc_fxnum_fast &) \
28612853Sgabeblack@google.com    DECL_ASN_OP_OTHER(op)
28712853Sgabeblack@google.com
28812853Sgabeblack@google.com    DECL_ASN_OP(=)
28912853Sgabeblack@google.com
29012853Sgabeblack@google.com    DECL_ASN_OP(*=)
29112853Sgabeblack@google.com    DECL_ASN_OP(/=)
29212853Sgabeblack@google.com    DECL_ASN_OP(+=)
29312853Sgabeblack@google.com    DECL_ASN_OP(-=)
29412853Sgabeblack@google.com
29512853Sgabeblack@google.com    DECL_ASN_OP_T(<<=, int)
29612853Sgabeblack@google.com    DECL_ASN_OP_T(>>=, int)
29712853Sgabeblack@google.com
29812853Sgabeblack@google.com#undef DECL_ASN_OP_T
29912853Sgabeblack@google.com#undef DECL_ASN_OP_OTHER
30012853Sgabeblack@google.com#undef DECL_ASN_OP
30112853Sgabeblack@google.com
30212853Sgabeblack@google.com    // auto-increment and auto-decrement
30312853Sgabeblack@google.com    const sc_fxval operator ++ (int);
30412853Sgabeblack@google.com    const sc_fxval operator -- (int);
30512853Sgabeblack@google.com
30612853Sgabeblack@google.com    sc_fxval & operator ++ ();
30712853Sgabeblack@google.com    sc_fxval & operator -- ();
30812853Sgabeblack@google.com
30912853Sgabeblack@google.com    // implicit conversion
31012853Sgabeblack@google.com    operator double() const;            // necessary evil!
31112853Sgabeblack@google.com
31212853Sgabeblack@google.com    // explicit conversion to primitive types
31312853Sgabeblack@google.com    short to_short() const;
31412853Sgabeblack@google.com    unsigned short to_ushort() const;
31512853Sgabeblack@google.com    int to_int() const;
31612853Sgabeblack@google.com    unsigned int   to_uint() const;
31712853Sgabeblack@google.com    long to_long() const;
31812853Sgabeblack@google.com    unsigned long  to_ulong() const;
31912853Sgabeblack@google.com    int64 to_int64() const;
32012853Sgabeblack@google.com    uint64 to_uint64() const;
32112853Sgabeblack@google.com    float to_float() const;
32212853Sgabeblack@google.com    double to_double() const;
32312853Sgabeblack@google.com
32412853Sgabeblack@google.com    // explicit conversion to character string
32512853Sgabeblack@google.com    const std::string to_string() const;
32612853Sgabeblack@google.com    const std::string to_string(sc_numrep) const;
32712853Sgabeblack@google.com    const std::string to_string(sc_numrep, bool) const;
32812853Sgabeblack@google.com    const std::string to_string(sc_fmt) const;
32912853Sgabeblack@google.com    const std::string to_string(sc_numrep, sc_fmt) const;
33012853Sgabeblack@google.com    const std::string to_string(sc_numrep, bool, sc_fmt) const;
33112853Sgabeblack@google.com
33212853Sgabeblack@google.com    const std::string to_dec() const;
33312853Sgabeblack@google.com    const std::string to_bin() const;
33412853Sgabeblack@google.com    const std::string to_oct() const;
33512853Sgabeblack@google.com    const std::string to_hex() const;
33612853Sgabeblack@google.com
33712853Sgabeblack@google.com    // query value
33812853Sgabeblack@google.com    bool is_neg() const;
33912853Sgabeblack@google.com    bool is_zero() const;
34012853Sgabeblack@google.com    bool is_nan() const;
34112853Sgabeblack@google.com    bool is_inf() const;
34212853Sgabeblack@google.com    bool is_normal() const;
34312853Sgabeblack@google.com
34412853Sgabeblack@google.com    bool rounding_flag() const;
34512853Sgabeblack@google.com
34612853Sgabeblack@google.com    // print or dump content
34712853Sgabeblack@google.com    void print(::std::ostream & =::std::cout) const;
34812853Sgabeblack@google.com    void scan(::std::istream & =::std::cin);
34912853Sgabeblack@google.com    void dump(::std::ostream & =::std::cout) const;
35012853Sgabeblack@google.com
35112853Sgabeblack@google.com    // internal use only;
35212853Sgabeblack@google.com    bool get_bit(int) const;
35312853Sgabeblack@google.com
35412853Sgabeblack@google.com  protected:
35512853Sgabeblack@google.com    sc_fxval_observer *lock_observer() const;
35612853Sgabeblack@google.com    void unlock_observer(sc_fxval_observer *) const;
35712853Sgabeblack@google.com
35812853Sgabeblack@google.com    void get_type(int &, int &, sc_enc &) const;
35912853Sgabeblack@google.com
36012853Sgabeblack@google.com    const sc_fxval quantization(const scfx_params &, bool &) const;
36112853Sgabeblack@google.com    const sc_fxval overflow(const scfx_params &, bool &) const;
36212853Sgabeblack@google.com
36312853Sgabeblack@google.com  private:
36412853Sgabeblack@google.com    scfx_rep * m_rep;
36512853Sgabeblack@google.com
36612853Sgabeblack@google.com    mutable sc_fxval_observer *m_observer;
36712853Sgabeblack@google.com};
36812853Sgabeblack@google.com
36912853Sgabeblack@google.com
37012853Sgabeblack@google.com// ----------------------------------------------------------------------------
37112853Sgabeblack@google.com//  CLASS : sc_fxval_fast
37212853Sgabeblack@google.com//
37312853Sgabeblack@google.com//  Fixed-point value type; limited precision.
37412853Sgabeblack@google.com// ----------------------------------------------------------------------------
37512853Sgabeblack@google.com
37612853Sgabeblack@google.comclass sc_fxval_fast
37712853Sgabeblack@google.com{
37812853Sgabeblack@google.com    friend class sc_fxnum_fast;
37912853Sgabeblack@google.com
38012853Sgabeblack@google.com  protected:
38112853Sgabeblack@google.com    sc_fxval_fast_observer *observer() const;
38212853Sgabeblack@google.com
38312853Sgabeblack@google.com  public:
38412853Sgabeblack@google.com    explicit sc_fxval_fast(sc_fxval_fast_observer * =0);
38512853Sgabeblack@google.com    explicit sc_fxval_fast(int, sc_fxval_fast_observer * =0);
38612853Sgabeblack@google.com    explicit sc_fxval_fast(unsigned int, sc_fxval_fast_observer * =0);
38712853Sgabeblack@google.com    explicit sc_fxval_fast(long, sc_fxval_fast_observer * =0);
38812853Sgabeblack@google.com    explicit sc_fxval_fast(unsigned long, sc_fxval_fast_observer * =0);
38912853Sgabeblack@google.com    explicit sc_fxval_fast(float, sc_fxval_fast_observer * =0);
39012853Sgabeblack@google.com    explicit sc_fxval_fast(double, sc_fxval_fast_observer * =0);
39112853Sgabeblack@google.com    explicit sc_fxval_fast(const char *, sc_fxval_fast_observer * =0);
39212853Sgabeblack@google.com    sc_fxval_fast(const sc_fxval &, sc_fxval_fast_observer * =0);
39312853Sgabeblack@google.com    sc_fxval_fast(const sc_fxval_fast &, sc_fxval_fast_observer * =0);
39412853Sgabeblack@google.com    sc_fxval_fast(const sc_fxnum &, sc_fxval_fast_observer * =0);
39512853Sgabeblack@google.com    sc_fxval_fast(const sc_fxnum_fast &, sc_fxval_fast_observer * =0);
39612853Sgabeblack@google.com
39712853Sgabeblack@google.com    explicit sc_fxval_fast(int64, sc_fxval_fast_observer * =0);
39812853Sgabeblack@google.com    explicit sc_fxval_fast(uint64, sc_fxval_fast_observer * =0);
39912853Sgabeblack@google.com    explicit sc_fxval_fast(const sc_int_base &, sc_fxval_fast_observer * =0);
40012853Sgabeblack@google.com    explicit sc_fxval_fast(const sc_uint_base &, sc_fxval_fast_observer * =0);
40112853Sgabeblack@google.com    explicit sc_fxval_fast(const sc_signed &, sc_fxval_fast_observer * =0);
40212853Sgabeblack@google.com    explicit sc_fxval_fast(const sc_unsigned &, sc_fxval_fast_observer * =0);
40312853Sgabeblack@google.com
40412853Sgabeblack@google.com    ~sc_fxval_fast();
40512853Sgabeblack@google.com
40612853Sgabeblack@google.com    // internal use only;
40712853Sgabeblack@google.com    double get_val() const;
40812853Sgabeblack@google.com    void set_val(double);
40912853Sgabeblack@google.com
41012853Sgabeblack@google.com    // unary operators
41112853Sgabeblack@google.com    const sc_fxval_fast operator - () const;
41212853Sgabeblack@google.com    const sc_fxval_fast & operator + () const;
41312853Sgabeblack@google.com
41412853Sgabeblack@google.com    // unary functions
41512853Sgabeblack@google.com    friend void neg(sc_fxval_fast &, const sc_fxval_fast &);
41612853Sgabeblack@google.com
41712853Sgabeblack@google.com    // binary operators
41812853Sgabeblack@google.com#define DECL_BIN_OP_T(op, tp) \
41912853Sgabeblack@google.com    friend const sc_fxval_fast operator op (const sc_fxval_fast &, tp); \
42012853Sgabeblack@google.com    friend const sc_fxval_fast operator op (tp, const sc_fxval_fast &);
42112853Sgabeblack@google.com
42212853Sgabeblack@google.com#define DECL_BIN_OP_OTHER(op) \
42312853Sgabeblack@google.com    DECL_BIN_OP_T(op, int64) \
42412853Sgabeblack@google.com    DECL_BIN_OP_T(op, uint64) \
42512853Sgabeblack@google.com    DECL_BIN_OP_T(op, const sc_int_base &) \
42612853Sgabeblack@google.com    DECL_BIN_OP_T(op, const sc_uint_base &) \
42712853Sgabeblack@google.com    DECL_BIN_OP_T(op, const sc_signed &) \
42812853Sgabeblack@google.com    DECL_BIN_OP_T(op, const sc_unsigned &)
42912853Sgabeblack@google.com
43012853Sgabeblack@google.com#define DECL_BIN_OP(op, dummy) \
43112853Sgabeblack@google.com    friend const sc_fxval_fast operator op (const sc_fxval_fast &, \
43212853Sgabeblack@google.com                                            const sc_fxval_fast &); \
43312853Sgabeblack@google.com    DECL_BIN_OP_T(op, int) \
43412853Sgabeblack@google.com    DECL_BIN_OP_T(op, unsigned int) \
43512853Sgabeblack@google.com    DECL_BIN_OP_T(op, long) \
43612853Sgabeblack@google.com    DECL_BIN_OP_T(op, unsigned long) \
43712853Sgabeblack@google.com    DECL_BIN_OP_T(op, float) \
43812853Sgabeblack@google.com    DECL_BIN_OP_T(op, double) \
43912853Sgabeblack@google.com    DECL_BIN_OP_T(op, const char *) \
44012853Sgabeblack@google.com    DECL_BIN_OP_OTHER(op)
44112853Sgabeblack@google.com
44212853Sgabeblack@google.com    DECL_BIN_OP(*, mult)
44312853Sgabeblack@google.com    DECL_BIN_OP(+, add)
44412853Sgabeblack@google.com    DECL_BIN_OP(-, sub)
44512853Sgabeblack@google.com// don't use macro
44612853Sgabeblack@google.com//    DECL_BIN_OP(/, div)
44712853Sgabeblack@google.com    friend const sc_fxval_fast operator / (const sc_fxval_fast &,
44812853Sgabeblack@google.com                                           const sc_fxval_fast &);
44912853Sgabeblack@google.com    DECL_BIN_OP_T(/, int)
45012853Sgabeblack@google.com    DECL_BIN_OP_T(/, unsigned int)
45112853Sgabeblack@google.com    DECL_BIN_OP_T(/, long)
45212853Sgabeblack@google.com    DECL_BIN_OP_T(/, unsigned long)
45312853Sgabeblack@google.com    DECL_BIN_OP_T(/, float)
45412853Sgabeblack@google.com    DECL_BIN_OP_T(/, double)
45512853Sgabeblack@google.com    DECL_BIN_OP_T(/, const char *)
45612853Sgabeblack@google.com//    DECL_BIN_OP_OTHER(/)
45712853Sgabeblack@google.com
45812853Sgabeblack@google.com    DECL_BIN_OP_T(/, int64) \
45912853Sgabeblack@google.com    DECL_BIN_OP_T(/, uint64) \
46012853Sgabeblack@google.com    DECL_BIN_OP_T(/, const sc_int_base &) \
46112853Sgabeblack@google.com    DECL_BIN_OP_T(/, const sc_uint_base &) \
46212853Sgabeblack@google.com    DECL_BIN_OP_T(/, const sc_signed &) \
46312853Sgabeblack@google.com    DECL_BIN_OP_T(/, const sc_unsigned &)
46412853Sgabeblack@google.com
46512853Sgabeblack@google.com#undef DECL_BIN_OP_T
46612853Sgabeblack@google.com#undef DECL_BIN_OP_OTHER
46712853Sgabeblack@google.com#undef DECL_BIN_OP
46812853Sgabeblack@google.com
46912853Sgabeblack@google.com    friend const sc_fxval_fast operator << (const sc_fxval_fast &, int);
47012853Sgabeblack@google.com    friend const sc_fxval_fast operator >> (const sc_fxval_fast &, int);
47112853Sgabeblack@google.com
47212853Sgabeblack@google.com    // binary functions
47312853Sgabeblack@google.com#define DECL_BIN_FNC_T(fnc, tp) \
47412853Sgabeblack@google.com    friend void fnc (sc_fxval_fast &, const sc_fxval_fast &, tp); \
47512853Sgabeblack@google.com    friend void fnc (sc_fxval_fast &, tp, const sc_fxval_fast &);
47612853Sgabeblack@google.com
47712853Sgabeblack@google.com#define DECL_BIN_FNC_OTHER(fnc) \
47812853Sgabeblack@google.com    DECL_BIN_FNC_T(fnc, int64) \
47912853Sgabeblack@google.com    DECL_BIN_FNC_T(fnc, uint64) \
48012853Sgabeblack@google.com    DECL_BIN_FNC_T(fnc, const sc_int_base &) \
48112853Sgabeblack@google.com    DECL_BIN_FNC_T(fnc, const sc_uint_base &) \
48212853Sgabeblack@google.com    DECL_BIN_FNC_T(fnc, const sc_signed &) \
48312853Sgabeblack@google.com    DECL_BIN_FNC_T(fnc, const sc_unsigned &)
48412853Sgabeblack@google.com
48512853Sgabeblack@google.com#define DECL_BIN_FNC(fnc) \
48612853Sgabeblack@google.com    friend void fnc (sc_fxval_fast &, const sc_fxval_fast &, \
48712853Sgabeblack@google.com                     const sc_fxval_fast &); \
48812853Sgabeblack@google.com    DECL_BIN_FNC_T(fnc, int) \
48912853Sgabeblack@google.com    DECL_BIN_FNC_T(fnc, unsigned int) \
49012853Sgabeblack@google.com    DECL_BIN_FNC_T(fnc, long) \
49112853Sgabeblack@google.com    DECL_BIN_FNC_T(fnc, unsigned long) \
49212853Sgabeblack@google.com    DECL_BIN_FNC_T(fnc, float) \
49312853Sgabeblack@google.com    DECL_BIN_FNC_T(fnc, double) \
49412853Sgabeblack@google.com    DECL_BIN_FNC_T(fnc, const char *) \
49512853Sgabeblack@google.com    DECL_BIN_FNC_T(fnc, const sc_fxval &) \
49612853Sgabeblack@google.com    DECL_BIN_FNC_T(fnc, const sc_fxnum &) \
49712853Sgabeblack@google.com    DECL_BIN_FNC_OTHER(fnc)
49812853Sgabeblack@google.com
49912853Sgabeblack@google.com    DECL_BIN_FNC(mult)
50012853Sgabeblack@google.com    DECL_BIN_FNC(div)
50112853Sgabeblack@google.com    DECL_BIN_FNC(add)
50212853Sgabeblack@google.com    DECL_BIN_FNC(sub)
50312853Sgabeblack@google.com
50412853Sgabeblack@google.com#undef DECL_BIN_FNC_T
50512853Sgabeblack@google.com#undef DECL_BIN_FNC_OTHER
50612853Sgabeblack@google.com#undef DECL_BIN_FNC
50712853Sgabeblack@google.com
50812853Sgabeblack@google.com    friend void lshift(sc_fxval_fast &, const sc_fxval_fast &, int);
50912853Sgabeblack@google.com    friend void rshift(sc_fxval_fast &, const sc_fxval_fast &, int);
51012853Sgabeblack@google.com
51112853Sgabeblack@google.com    // relational (including equality) operators
51212853Sgabeblack@google.com#define DECL_REL_OP_T(op, tp) \
51312853Sgabeblack@google.com    friend bool operator op (const sc_fxval_fast &, tp); \
51412853Sgabeblack@google.com    friend bool operator op (tp, const sc_fxval_fast &);
51512853Sgabeblack@google.com
51612853Sgabeblack@google.com#define DECL_REL_OP_OTHER(op) \
51712853Sgabeblack@google.com    DECL_REL_OP_T(op, int64) \
51812853Sgabeblack@google.com    DECL_REL_OP_T(op, uint64) \
51912853Sgabeblack@google.com    DECL_REL_OP_T(op, const sc_int_base &) \
52012853Sgabeblack@google.com    DECL_REL_OP_T(op, const sc_uint_base &) \
52112853Sgabeblack@google.com    DECL_REL_OP_T(op, const sc_signed &) \
52212853Sgabeblack@google.com    DECL_REL_OP_T(op, const sc_unsigned &)
52312853Sgabeblack@google.com
52412853Sgabeblack@google.com#define DECL_REL_OP(op) \
52512853Sgabeblack@google.com    friend bool operator op (const sc_fxval_fast &, const sc_fxval_fast &); \
52612853Sgabeblack@google.com    DECL_REL_OP_T(op, int) \
52712853Sgabeblack@google.com    DECL_REL_OP_T(op, unsigned int) \
52812853Sgabeblack@google.com    DECL_REL_OP_T(op, long) \
52912853Sgabeblack@google.com    DECL_REL_OP_T(op, unsigned long) \
53012853Sgabeblack@google.com    DECL_REL_OP_T(op, float) \
53112853Sgabeblack@google.com    DECL_REL_OP_T(op, double) \
53212853Sgabeblack@google.com    DECL_REL_OP_T(op, const char *) \
53312853Sgabeblack@google.com    DECL_REL_OP_OTHER(op)
53412853Sgabeblack@google.com
53512853Sgabeblack@google.com    DECL_REL_OP(<)
53612853Sgabeblack@google.com    DECL_REL_OP(<=)
53712853Sgabeblack@google.com    DECL_REL_OP(>)
53812853Sgabeblack@google.com    DECL_REL_OP(>=)
53912853Sgabeblack@google.com    DECL_REL_OP(==)
54012853Sgabeblack@google.com    DECL_REL_OP(!=)
54112853Sgabeblack@google.com
54212853Sgabeblack@google.com#undef DECL_REL_OP_T
54312853Sgabeblack@google.com#undef DECL_REL_OP_OTHER
54412853Sgabeblack@google.com#undef DECL_REL_OP
54512853Sgabeblack@google.com
54612853Sgabeblack@google.com    // assignment operators
54712853Sgabeblack@google.com#define DECL_ASN_OP_T(op, tp) sc_fxval_fast &operator op(tp);
54812853Sgabeblack@google.com
54912853Sgabeblack@google.com#define DECL_ASN_OP_OTHER(op) \
55012853Sgabeblack@google.com    DECL_ASN_OP_T(op, int64) \
55112853Sgabeblack@google.com    DECL_ASN_OP_T(op, uint64) \
55212853Sgabeblack@google.com    DECL_ASN_OP_T(op, const sc_int_base &) \
55312853Sgabeblack@google.com    DECL_ASN_OP_T(op, const sc_uint_base &) \
55412853Sgabeblack@google.com    DECL_ASN_OP_T(op, const sc_signed &) \
55512853Sgabeblack@google.com    DECL_ASN_OP_T(op, const sc_unsigned &)
55612853Sgabeblack@google.com
55712853Sgabeblack@google.com#define DECL_ASN_OP(op) \
55812853Sgabeblack@google.com    DECL_ASN_OP_T(op, int) \
55912853Sgabeblack@google.com    DECL_ASN_OP_T(op, unsigned int) \
56012853Sgabeblack@google.com    DECL_ASN_OP_T(op, long) \
56112853Sgabeblack@google.com    DECL_ASN_OP_T(op, unsigned long) \
56212853Sgabeblack@google.com    DECL_ASN_OP_T(op, float) \
56312853Sgabeblack@google.com    DECL_ASN_OP_T(op, double) \
56412853Sgabeblack@google.com    DECL_ASN_OP_T(op, const char *) \
56512853Sgabeblack@google.com    DECL_ASN_OP_T(op, const sc_fxval &) \
56612853Sgabeblack@google.com    DECL_ASN_OP_T(op, const sc_fxval_fast &) \
56712853Sgabeblack@google.com    DECL_ASN_OP_T(op, const sc_fxnum &) \
56812853Sgabeblack@google.com    DECL_ASN_OP_T(op, const sc_fxnum_fast &) \
56912853Sgabeblack@google.com    DECL_ASN_OP_OTHER(op)
57012853Sgabeblack@google.com
57112853Sgabeblack@google.com    DECL_ASN_OP(=)
57212853Sgabeblack@google.com
57312853Sgabeblack@google.com    DECL_ASN_OP(*=)
57412853Sgabeblack@google.com    DECL_ASN_OP(/=)
57512853Sgabeblack@google.com    DECL_ASN_OP(+=)
57612853Sgabeblack@google.com    DECL_ASN_OP(-=)
57712853Sgabeblack@google.com
57812853Sgabeblack@google.com    DECL_ASN_OP_T(<<=, int)
57912853Sgabeblack@google.com    DECL_ASN_OP_T(>>=, int)
58012853Sgabeblack@google.com
58112853Sgabeblack@google.com#undef DECL_ASN_OP_T
58212853Sgabeblack@google.com#undef DECL_ASN_OP_OTHER
58312853Sgabeblack@google.com#undef DECL_ASN_OP
58412853Sgabeblack@google.com
58512853Sgabeblack@google.com    // auto-increment and auto-decrement
58612853Sgabeblack@google.com    const sc_fxval_fast operator ++ (int);
58712853Sgabeblack@google.com    const sc_fxval_fast operator -- (int);
58812853Sgabeblack@google.com
58912853Sgabeblack@google.com    sc_fxval_fast & operator ++ ();
59012853Sgabeblack@google.com    sc_fxval_fast & operator -- ();
59112853Sgabeblack@google.com
59212853Sgabeblack@google.com    // implicit conversion
59312853Sgabeblack@google.com    operator double() const;            // necessary evil!
59412853Sgabeblack@google.com
59512853Sgabeblack@google.com    // explicit conversion to primitive types
59612853Sgabeblack@google.com    short to_short() const;
59712853Sgabeblack@google.com    unsigned short to_ushort() const;
59812853Sgabeblack@google.com    int to_int() const;
59912853Sgabeblack@google.com    unsigned int to_uint() const;
60012853Sgabeblack@google.com    long to_long() const;
60112853Sgabeblack@google.com    unsigned long to_ulong() const;
60212853Sgabeblack@google.com    int64 to_int64() const;
60312853Sgabeblack@google.com    uint64 to_uint64() const;
60412853Sgabeblack@google.com    float to_float() const;
60512853Sgabeblack@google.com    double to_double() const;
60612853Sgabeblack@google.com
60712853Sgabeblack@google.com    // explicit conversion to character string
60812853Sgabeblack@google.com    const std::string to_string() const;
60912853Sgabeblack@google.com    const std::string to_string(sc_numrep) const;
61012853Sgabeblack@google.com    const std::string to_string(sc_numrep, bool) const;
61112853Sgabeblack@google.com    const std::string to_string(sc_fmt) const;
61212853Sgabeblack@google.com    const std::string to_string(sc_numrep, sc_fmt) const;
61312853Sgabeblack@google.com    const std::string to_string(sc_numrep, bool, sc_fmt) const;
61412853Sgabeblack@google.com
61512853Sgabeblack@google.com    const std::string to_dec() const;
61612853Sgabeblack@google.com    const std::string to_bin() const;
61712853Sgabeblack@google.com    const std::string to_oct() const;
61812853Sgabeblack@google.com    const std::string to_hex() const;
61912853Sgabeblack@google.com
62012853Sgabeblack@google.com    // query value
62112853Sgabeblack@google.com    bool is_neg() const;
62212853Sgabeblack@google.com    bool is_zero() const;
62312853Sgabeblack@google.com    bool is_nan() const;
62412853Sgabeblack@google.com    bool is_inf() const;
62512853Sgabeblack@google.com    bool is_normal() const;
62612853Sgabeblack@google.com
62712853Sgabeblack@google.com    bool rounding_flag() const;
62812853Sgabeblack@google.com
62912853Sgabeblack@google.com    // print or dump content
63012853Sgabeblack@google.com    void print(::std::ostream & =::std::cout) const;
63112853Sgabeblack@google.com    void scan(::std::istream & =::std::cin);
63212853Sgabeblack@google.com    void dump(::std::ostream & =::std::cout) const;
63312853Sgabeblack@google.com
63412853Sgabeblack@google.com    // internal use only;
63512853Sgabeblack@google.com    bool get_bit(int) const;
63612853Sgabeblack@google.com
63712853Sgabeblack@google.com  protected:
63812853Sgabeblack@google.com    sc_fxval_fast_observer *lock_observer() const;
63912853Sgabeblack@google.com    void unlock_observer(sc_fxval_fast_observer *) const;
64012853Sgabeblack@google.com
64112853Sgabeblack@google.com    static double from_string(const char *);
64212853Sgabeblack@google.com  private:
64312853Sgabeblack@google.com    double m_val;
64412853Sgabeblack@google.com
64512853Sgabeblack@google.com    mutable sc_fxval_fast_observer *m_observer;
64612853Sgabeblack@google.com};
64712853Sgabeblack@google.com
64812853Sgabeblack@google.com
64912853Sgabeblack@google.com// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
65012853Sgabeblack@google.com
65112853Sgabeblack@google.com// ----------------------------------------------------------------------------
65212853Sgabeblack@google.com//  CLASS : sc_fxval
65312853Sgabeblack@google.com//
65412853Sgabeblack@google.com//  Fixed-point value type; arbitrary precision.
65512853Sgabeblack@google.com// ----------------------------------------------------------------------------
65612853Sgabeblack@google.com
65712853Sgabeblack@google.com// protected method
65812853Sgabeblack@google.com
65912853Sgabeblack@google.cominline sc_fxval_observer *sc_fxval::observer() const { return m_observer; }
66012853Sgabeblack@google.com
66112853Sgabeblack@google.com// internal use only;
66212853Sgabeblack@google.cominline sc_fxval::sc_fxval(scfx_rep *a) :
66312853Sgabeblack@google.com    m_rep(a != 0 ? a : new scfx_rep), m_observer(0)
66412853Sgabeblack@google.com{}
66512853Sgabeblack@google.com
66612853Sgabeblack@google.com
66712853Sgabeblack@google.com// public constructors
66812853Sgabeblack@google.com
66912853Sgabeblack@google.cominline sc_fxval::sc_fxval(sc_fxval_observer *observer_) :
67012853Sgabeblack@google.com    m_rep(new scfx_rep), m_observer(observer_)
67112853Sgabeblack@google.com{
67212853Sgabeblack@google.com    SC_FXVAL_OBSERVER_DEFAULT_
67312853Sgabeblack@google.com    SC_FXVAL_OBSERVER_CONSTRUCT_(*this)
67412853Sgabeblack@google.com}
67512853Sgabeblack@google.com
67612853Sgabeblack@google.cominline sc_fxval::sc_fxval(const sc_fxval &a, sc_fxval_observer *observer_) :
67712853Sgabeblack@google.com    m_rep(new scfx_rep(*a.m_rep)), m_observer(observer_)
67812853Sgabeblack@google.com{
67912853Sgabeblack@google.com    SC_FXVAL_OBSERVER_DEFAULT_
68012853Sgabeblack@google.com    SC_FXVAL_OBSERVER_READ_(a)
68112853Sgabeblack@google.com    SC_FXVAL_OBSERVER_CONSTRUCT_(*this)
68212853Sgabeblack@google.com    SC_FXVAL_OBSERVER_WRITE_(*this)
68312853Sgabeblack@google.com}
68412853Sgabeblack@google.com
68512853Sgabeblack@google.com#define DEFN_CTOR_T(tp, arg) \
68612853Sgabeblack@google.cominline sc_fxval::sc_fxval(tp a, sc_fxval_observer *observer_) : \
68712853Sgabeblack@google.com    m_rep(new scfx_rep(arg)), m_observer(observer_) \
68812853Sgabeblack@google.com{ \
68912853Sgabeblack@google.com    SC_FXVAL_OBSERVER_DEFAULT_ \
69012853Sgabeblack@google.com    SC_FXVAL_OBSERVER_CONSTRUCT_(*this) \
69112853Sgabeblack@google.com    SC_FXVAL_OBSERVER_WRITE_(*this) \
69212853Sgabeblack@google.com}
69312853Sgabeblack@google.com
69412853Sgabeblack@google.com#define DEFN_CTOR_T_A(tp) DEFN_CTOR_T(tp, a)
69512853Sgabeblack@google.com#define DEFN_CTOR_T_B(tp) DEFN_CTOR_T(tp, a.to_double())
69612853Sgabeblack@google.com#define DEFN_CTOR_T_C(tp) DEFN_CTOR_T(tp, a.value())
69712853Sgabeblack@google.com
69812853Sgabeblack@google.comDEFN_CTOR_T_A(int)
69912853Sgabeblack@google.comDEFN_CTOR_T_A(unsigned int)
70012853Sgabeblack@google.comDEFN_CTOR_T_A(long)
70112853Sgabeblack@google.comDEFN_CTOR_T_A(unsigned long)
70212853Sgabeblack@google.comDEFN_CTOR_T_A(float)
70312853Sgabeblack@google.comDEFN_CTOR_T_A(double)
70412853Sgabeblack@google.comDEFN_CTOR_T_A(const char *)
70512853Sgabeblack@google.comDEFN_CTOR_T_B(const sc_fxval_fast &)
70612853Sgabeblack@google.com
70712853Sgabeblack@google.comDEFN_CTOR_T_A(int64)
70812853Sgabeblack@google.comDEFN_CTOR_T_A(uint64)
70912853Sgabeblack@google.comDEFN_CTOR_T_C(const sc_int_base &)
71012853Sgabeblack@google.comDEFN_CTOR_T_C(const sc_uint_base &)
71112853Sgabeblack@google.comDEFN_CTOR_T_A(const sc_signed &)
71212853Sgabeblack@google.comDEFN_CTOR_T_A(const sc_unsigned &)
71312853Sgabeblack@google.com
71412853Sgabeblack@google.com#undef DEFN_CTOR_T
71512853Sgabeblack@google.com#undef DEFN_CTOR_T_A
71612853Sgabeblack@google.com#undef DEFN_CTOR_T_B
71712853Sgabeblack@google.com#undef DEFN_CTOR_T_C
71812853Sgabeblack@google.com
71912853Sgabeblack@google.cominline sc_fxval::~sc_fxval()
72012853Sgabeblack@google.com{
72112853Sgabeblack@google.com    SC_FXVAL_OBSERVER_DESTRUCT_(*this)
72212853Sgabeblack@google.com    delete m_rep;
72312853Sgabeblack@google.com}
72412853Sgabeblack@google.com
72512853Sgabeblack@google.com// internal use only;
72612853Sgabeblack@google.cominline const scfx_rep *
72712853Sgabeblack@google.comsc_fxval::get_rep() const
72812853Sgabeblack@google.com{
72912853Sgabeblack@google.com    SC_FXVAL_OBSERVER_READ_(*this)
73012853Sgabeblack@google.com    return m_rep;
73112853Sgabeblack@google.com}
73212853Sgabeblack@google.com
73312853Sgabeblack@google.com// internal use only;
73412853Sgabeblack@google.cominline void
73512853Sgabeblack@google.comsc_fxval::set_rep(scfx_rep *rep_)
73612853Sgabeblack@google.com{
73712853Sgabeblack@google.com    delete m_rep;
73812853Sgabeblack@google.com    m_rep = rep_;
73912853Sgabeblack@google.com    SC_FXVAL_OBSERVER_WRITE_(*this)
74012853Sgabeblack@google.com}
74112853Sgabeblack@google.com
74212853Sgabeblack@google.com// unary operators
74312853Sgabeblack@google.cominline const sc_fxval
74412853Sgabeblack@google.comsc_fxval::operator - () const
74512853Sgabeblack@google.com{
74612853Sgabeblack@google.com    SC_FXVAL_OBSERVER_READ_(*this)
74712853Sgabeblack@google.com    return sc_fxval(sc_dt::neg_scfx_rep(*m_rep));
74812853Sgabeblack@google.com}
74912853Sgabeblack@google.com
75012853Sgabeblack@google.cominline const sc_fxval &
75112853Sgabeblack@google.comsc_fxval::operator + () const
75212853Sgabeblack@google.com{
75312853Sgabeblack@google.com    // SC_FXVAL_OBSERVER_READ_(*this)
75412853Sgabeblack@google.com    return *this;
75512853Sgabeblack@google.com}
75612853Sgabeblack@google.com
75712853Sgabeblack@google.com// unary functions
75812853Sgabeblack@google.cominline void
75912853Sgabeblack@google.comneg(sc_fxval &c, const sc_fxval &a)
76012853Sgabeblack@google.com{
76112853Sgabeblack@google.com    SC_FXVAL_OBSERVER_READ_(a)
76212853Sgabeblack@google.com    delete c.m_rep;
76312853Sgabeblack@google.com    c.m_rep = sc_dt::neg_scfx_rep(*a.m_rep);
76412853Sgabeblack@google.com    SC_FXVAL_OBSERVER_WRITE_(c)
76512853Sgabeblack@google.com}
76612853Sgabeblack@google.com
76712853Sgabeblack@google.com// binary operators
76812853Sgabeblack@google.com#define DEFN_BIN_OP_T(op, fnc, tp) \
76912853Sgabeblack@google.cominline const sc_fxval \
77012853Sgabeblack@google.comoperator op (const sc_fxval &a, tp b) \
77112853Sgabeblack@google.com{ \
77212853Sgabeblack@google.com    SC_FXVAL_OBSERVER_READ_(a) \
77312853Sgabeblack@google.com    sc_fxval tmp(b); \
77412853Sgabeblack@google.com    return sc_fxval(sc_dt::fnc ## _scfx_rep(*a.m_rep, *tmp.m_rep)); \
77512853Sgabeblack@google.com} \
77612853Sgabeblack@google.com \
77712853Sgabeblack@google.cominline \
77812853Sgabeblack@google.comconst sc_fxval \
77912853Sgabeblack@google.comoperator op (tp a, const sc_fxval &b) \
78012853Sgabeblack@google.com{ \
78112853Sgabeblack@google.com    SC_FXVAL_OBSERVER_READ_(b) \
78212853Sgabeblack@google.com    sc_fxval tmp(a); \
78312853Sgabeblack@google.com    return sc_fxval(sc_dt::fnc ## _scfx_rep(*tmp.m_rep, *b.m_rep)); \
78412853Sgabeblack@google.com}
78512853Sgabeblack@google.com
78612853Sgabeblack@google.com#define DEFN_BIN_OP_OTHER(op, fnc) \
78712853Sgabeblack@google.comDEFN_BIN_OP_T(op, fnc, int64) \
78812853Sgabeblack@google.comDEFN_BIN_OP_T(op, fnc, uint64) \
78912853Sgabeblack@google.comDEFN_BIN_OP_T(op, fnc, const sc_int_base &) \
79012853Sgabeblack@google.comDEFN_BIN_OP_T(op, fnc, const sc_uint_base &) \
79112853Sgabeblack@google.comDEFN_BIN_OP_T(op, fnc, const sc_signed &) \
79212853Sgabeblack@google.comDEFN_BIN_OP_T(op, fnc, const sc_unsigned &)
79312853Sgabeblack@google.com
79412853Sgabeblack@google.com#define DEFN_BIN_OP(op, fnc) \
79512853Sgabeblack@google.cominline const sc_fxval \
79612853Sgabeblack@google.comoperator op (const sc_fxval &a, const sc_fxval &b) \
79712853Sgabeblack@google.com{ \
79812853Sgabeblack@google.com    SC_FXVAL_OBSERVER_READ_(a) \
79912853Sgabeblack@google.com    SC_FXVAL_OBSERVER_READ_(b) \
80012853Sgabeblack@google.com    return sc_fxval(sc_dt::fnc ## _scfx_rep( *a.m_rep, *b.m_rep)); \
80112853Sgabeblack@google.com} \
80212853Sgabeblack@google.com \
80312853Sgabeblack@google.comDEFN_BIN_OP_T(op, fnc, int) \
80412853Sgabeblack@google.comDEFN_BIN_OP_T(op, fnc, unsigned int) \
80512853Sgabeblack@google.comDEFN_BIN_OP_T(op, fnc, long) \
80612853Sgabeblack@google.comDEFN_BIN_OP_T(op, fnc, unsigned long) \
80712853Sgabeblack@google.comDEFN_BIN_OP_T(op, fnc, float) \
80812853Sgabeblack@google.comDEFN_BIN_OP_T(op, fnc, double) \
80912853Sgabeblack@google.comDEFN_BIN_OP_T(op, fnc, const char *) \
81012853Sgabeblack@google.comDEFN_BIN_OP_T(op, fnc, const sc_fxval_fast &) \
81112853Sgabeblack@google.comDEFN_BIN_OP_OTHER(op, fnc)
81212853Sgabeblack@google.com
81312853Sgabeblack@google.comDEFN_BIN_OP(*, mult)
81412853Sgabeblack@google.comDEFN_BIN_OP(+, add)
81512853Sgabeblack@google.comDEFN_BIN_OP(-, sub)
81612853Sgabeblack@google.com// don't use macro
81712853Sgabeblack@google.com//DEFN_BIN_OP(/, div)
81812853Sgabeblack@google.cominline const sc_fxval
81912853Sgabeblack@google.comoperator / (const sc_fxval &a, const sc_fxval &b)
82012853Sgabeblack@google.com{
82112853Sgabeblack@google.com    SC_FXVAL_OBSERVER_READ_(a)
82212853Sgabeblack@google.com    SC_FXVAL_OBSERVER_READ_(b)
82312853Sgabeblack@google.com    return sc_fxval(sc_dt::div_scfx_rep(*a.m_rep, *b.m_rep));
82412853Sgabeblack@google.com}
82512853Sgabeblack@google.com
82612853Sgabeblack@google.comDEFN_BIN_OP_T(/, div, int)
82712853Sgabeblack@google.comDEFN_BIN_OP_T(/, div, unsigned int)
82812853Sgabeblack@google.comDEFN_BIN_OP_T(/, div, long)
82912853Sgabeblack@google.comDEFN_BIN_OP_T(/, div, unsigned long)
83012853Sgabeblack@google.comDEFN_BIN_OP_T(/, div, float)
83112853Sgabeblack@google.comDEFN_BIN_OP_T(/, div, double)
83212853Sgabeblack@google.comDEFN_BIN_OP_T(/, div, const char *)
83312853Sgabeblack@google.comDEFN_BIN_OP_T(/, div, const sc_fxval_fast &)
83412853Sgabeblack@google.com//DEFN_BIN_OP_OTHER(/, div)
83512853Sgabeblack@google.com
83612853Sgabeblack@google.comDEFN_BIN_OP_T(/, div, int64)
83712853Sgabeblack@google.comDEFN_BIN_OP_T(/, div, uint64)
83812853Sgabeblack@google.comDEFN_BIN_OP_T(/, div, const sc_int_base &)
83912853Sgabeblack@google.comDEFN_BIN_OP_T(/, div, const sc_uint_base &)
84012853Sgabeblack@google.comDEFN_BIN_OP_T(/, div, const sc_signed &)
84112853Sgabeblack@google.comDEFN_BIN_OP_T(/, div, const sc_unsigned &)
84212853Sgabeblack@google.com
84312853Sgabeblack@google.com#undef DEFN_BIN_OP_T
84412853Sgabeblack@google.com#undef DEFN_BIN_OP_OTHER
84512853Sgabeblack@google.com#undef DEFN_BIN_OP
84612853Sgabeblack@google.com
84712853Sgabeblack@google.cominline const sc_fxval
84812853Sgabeblack@google.comoperator << (const sc_fxval &a, int b)
84912853Sgabeblack@google.com{
85012853Sgabeblack@google.com    SC_FXVAL_OBSERVER_READ_(a)
85112853Sgabeblack@google.com    return sc_fxval(sc_dt::lsh_scfx_rep(*a.m_rep, b));
85212853Sgabeblack@google.com}
85312853Sgabeblack@google.com
85412853Sgabeblack@google.cominline const sc_fxval
85512853Sgabeblack@google.comoperator >> (const sc_fxval &a, int b)
85612853Sgabeblack@google.com{
85712853Sgabeblack@google.com    SC_FXVAL_OBSERVER_READ_(a)
85812853Sgabeblack@google.com    return sc_fxval(sc_dt::rsh_scfx_rep(*a.m_rep, b));
85912853Sgabeblack@google.com}
86012853Sgabeblack@google.com
86112853Sgabeblack@google.com// binary functions
86212853Sgabeblack@google.com#define DEFN_BIN_FNC_T(fnc, tp) \
86312853Sgabeblack@google.cominline void \
86412853Sgabeblack@google.comfnc (sc_fxval &c, const sc_fxval &a, tp b) \
86512853Sgabeblack@google.com{ \
86612853Sgabeblack@google.com    SC_FXVAL_OBSERVER_READ_(a) \
86712853Sgabeblack@google.com    sc_fxval tmp(b); \
86812853Sgabeblack@google.com    delete c.m_rep; \
86912853Sgabeblack@google.com    c.m_rep = sc_dt::fnc ## _scfx_rep(*a.m_rep, *tmp.m_rep); \
87012853Sgabeblack@google.com    SC_FXVAL_OBSERVER_WRITE_(c) \
87112853Sgabeblack@google.com} \
87212853Sgabeblack@google.com \
87312853Sgabeblack@google.cominline void \
87412853Sgabeblack@google.comfnc (sc_fxval &c, tp a, const sc_fxval &b) \
87512853Sgabeblack@google.com{ \
87612853Sgabeblack@google.com    SC_FXVAL_OBSERVER_READ_(b) \
87712853Sgabeblack@google.com    sc_fxval tmp(a); \
87812853Sgabeblack@google.com    delete c.m_rep; \
87912853Sgabeblack@google.com    c.m_rep = sc_dt::fnc ## _scfx_rep(*tmp.m_rep, *b.m_rep); \
88012853Sgabeblack@google.com    SC_FXVAL_OBSERVER_WRITE_(c) \
88112853Sgabeblack@google.com}
88212853Sgabeblack@google.com
88312853Sgabeblack@google.com#define DEFN_BIN_FNC_OTHER(fnc) \
88412853Sgabeblack@google.comDEFN_BIN_FNC_T(fnc, int64) \
88512853Sgabeblack@google.comDEFN_BIN_FNC_T(fnc, uint64) \
88612853Sgabeblack@google.comDEFN_BIN_FNC_T(fnc, const sc_int_base &) \
88712853Sgabeblack@google.comDEFN_BIN_FNC_T(fnc, const sc_uint_base &) \
88812853Sgabeblack@google.comDEFN_BIN_FNC_T(fnc, const sc_signed &) \
88912853Sgabeblack@google.comDEFN_BIN_FNC_T(fnc, const sc_unsigned &)
89012853Sgabeblack@google.com
89112853Sgabeblack@google.com#define DEFN_BIN_FNC(fnc) \
89212853Sgabeblack@google.cominline void \
89312853Sgabeblack@google.comfnc(sc_fxval &c, const sc_fxval &a, const sc_fxval &b) \
89412853Sgabeblack@google.com{ \
89512853Sgabeblack@google.com    SC_FXVAL_OBSERVER_READ_(a) \
89612853Sgabeblack@google.com    SC_FXVAL_OBSERVER_READ_(b) \
89712853Sgabeblack@google.com    delete c.m_rep; \
89812853Sgabeblack@google.com    c.m_rep = sc_dt::fnc ## _scfx_rep(*a.m_rep, *b.m_rep); \
89912853Sgabeblack@google.com    SC_FXVAL_OBSERVER_WRITE_(c) \
90012853Sgabeblack@google.com} \
90112853Sgabeblack@google.com \
90212853Sgabeblack@google.comDEFN_BIN_FNC_T(fnc, int) \
90312853Sgabeblack@google.comDEFN_BIN_FNC_T(fnc, unsigned int) \
90412853Sgabeblack@google.comDEFN_BIN_FNC_T(fnc, long) \
90512853Sgabeblack@google.comDEFN_BIN_FNC_T(fnc, unsigned long) \
90612853Sgabeblack@google.comDEFN_BIN_FNC_T(fnc, float) \
90712853Sgabeblack@google.comDEFN_BIN_FNC_T(fnc, double) \
90812853Sgabeblack@google.comDEFN_BIN_FNC_T(fnc, const char *) \
90912853Sgabeblack@google.comDEFN_BIN_FNC_T(fnc, const sc_fxval_fast &) \
91012853Sgabeblack@google.comDEFN_BIN_FNC_OTHER(fnc)
91112853Sgabeblack@google.com
91212853Sgabeblack@google.comDEFN_BIN_FNC(mult)
91312853Sgabeblack@google.comDEFN_BIN_FNC(div)
91412853Sgabeblack@google.comDEFN_BIN_FNC(add)
91512853Sgabeblack@google.comDEFN_BIN_FNC(sub)
91612853Sgabeblack@google.com
91712853Sgabeblack@google.com#undef DEFN_BIN_FNC_T
91812853Sgabeblack@google.com#undef DEFN_BIN_FNC_OTHER
91912853Sgabeblack@google.com#undef DEFN_BIN_FNC
92012853Sgabeblack@google.com
92112853Sgabeblack@google.cominline void
92212853Sgabeblack@google.comlshift(sc_fxval &c, const sc_fxval &a, int b)
92312853Sgabeblack@google.com{
92412853Sgabeblack@google.com    SC_FXVAL_OBSERVER_READ_(a)
92512853Sgabeblack@google.com    delete c.m_rep;
92612853Sgabeblack@google.com    c.m_rep = sc_dt::lsh_scfx_rep(*a.m_rep, b);
92712853Sgabeblack@google.com    SC_FXVAL_OBSERVER_WRITE_(c)
92812853Sgabeblack@google.com}
92912853Sgabeblack@google.com
93012853Sgabeblack@google.cominline void
93112853Sgabeblack@google.comrshift(sc_fxval &c, const sc_fxval &a, int b)
93212853Sgabeblack@google.com{
93312853Sgabeblack@google.com    SC_FXVAL_OBSERVER_READ_(a)
93412853Sgabeblack@google.com    delete c.m_rep;
93512853Sgabeblack@google.com    c.m_rep = sc_dt::rsh_scfx_rep(*a.m_rep, b);
93612853Sgabeblack@google.com    SC_FXVAL_OBSERVER_WRITE_(c)
93712853Sgabeblack@google.com}
93812853Sgabeblack@google.com
93912853Sgabeblack@google.com// relational (including equality) operators
94012853Sgabeblack@google.com#define DEFN_REL_OP_T(op, ret, tp) \
94112853Sgabeblack@google.cominline bool \
94212853Sgabeblack@google.comoperator op (const sc_fxval &a, tp b) \
94312853Sgabeblack@google.com{ \
94412853Sgabeblack@google.com    SC_FXVAL_OBSERVER_READ_(a) \
94512853Sgabeblack@google.com    sc_fxval tmp(b); \
94612853Sgabeblack@google.com    int result = sc_dt::cmp_scfx_rep(*a.m_rep, *tmp.m_rep); \
94712853Sgabeblack@google.com    return (ret); \
94812853Sgabeblack@google.com} \
94912853Sgabeblack@google.com \
95012853Sgabeblack@google.cominline bool \
95112853Sgabeblack@google.comoperator op (tp a, const sc_fxval &b) \
95212853Sgabeblack@google.com{ \
95312853Sgabeblack@google.com    SC_FXVAL_OBSERVER_READ_(b) \
95412853Sgabeblack@google.com    sc_fxval tmp(a); \
95512853Sgabeblack@google.com    int result = sc_dt::cmp_scfx_rep(*tmp.m_rep, *b.m_rep); \
95612853Sgabeblack@google.com    return (ret); \
95712853Sgabeblack@google.com}
95812853Sgabeblack@google.com
95912853Sgabeblack@google.com#define DEFN_REL_OP_OTHER(op, ret) \
96012853Sgabeblack@google.comDEFN_REL_OP_T(op, ret, int64) \
96112853Sgabeblack@google.comDEFN_REL_OP_T(op, ret, uint64) \
96212853Sgabeblack@google.comDEFN_REL_OP_T(op, ret, const sc_int_base &) \
96312853Sgabeblack@google.comDEFN_REL_OP_T(op, ret, const sc_uint_base &) \
96412853Sgabeblack@google.comDEFN_REL_OP_T(op, ret, const sc_signed &) \
96512853Sgabeblack@google.comDEFN_REL_OP_T(op, ret, const sc_unsigned &)
96612853Sgabeblack@google.com
96712853Sgabeblack@google.com#define DEFN_REL_OP(op, ret) \
96812853Sgabeblack@google.cominline bool \
96912853Sgabeblack@google.comoperator op (const sc_fxval &a, const sc_fxval &b) \
97012853Sgabeblack@google.com{ \
97112853Sgabeblack@google.com    SC_FXVAL_OBSERVER_READ_(a) \
97212853Sgabeblack@google.com    SC_FXVAL_OBSERVER_READ_(b) \
97312853Sgabeblack@google.com    int result = sc_dt::cmp_scfx_rep(*a.m_rep, *b.m_rep); \
97412853Sgabeblack@google.com    return (ret); \
97512853Sgabeblack@google.com} \
97612853Sgabeblack@google.com \
97712853Sgabeblack@google.comDEFN_REL_OP_T(op, ret, int) \
97812853Sgabeblack@google.comDEFN_REL_OP_T(op, ret, unsigned int) \
97912853Sgabeblack@google.comDEFN_REL_OP_T(op, ret, long) \
98012853Sgabeblack@google.comDEFN_REL_OP_T(op, ret, unsigned long) \
98112853Sgabeblack@google.comDEFN_REL_OP_T(op, ret, float) \
98212853Sgabeblack@google.comDEFN_REL_OP_T(op, ret, double) \
98312853Sgabeblack@google.comDEFN_REL_OP_T(op, ret, const char *) \
98412853Sgabeblack@google.comDEFN_REL_OP_T(op, ret, const sc_fxval_fast &) \
98512853Sgabeblack@google.comDEFN_REL_OP_OTHER(op, ret)
98612853Sgabeblack@google.com
98712853Sgabeblack@google.comDEFN_REL_OP(<, result < 0)
98812853Sgabeblack@google.comDEFN_REL_OP(<=, result <= 0)
98912853Sgabeblack@google.comDEFN_REL_OP(>, result > 0 && result != 2)
99012853Sgabeblack@google.comDEFN_REL_OP(>=, result >= 0 && result != 2)
99112853Sgabeblack@google.comDEFN_REL_OP(==, result == 0)
99212853Sgabeblack@google.comDEFN_REL_OP(!=, result != 0)
99312853Sgabeblack@google.com
99412853Sgabeblack@google.com#undef DEFN_REL_OP_T
99512853Sgabeblack@google.com#undef DEFN_REL_OP_OTHER
99612853Sgabeblack@google.com#undef DEFN_REL_OP
99712853Sgabeblack@google.com
99812853Sgabeblack@google.com// assignment operators
99912853Sgabeblack@google.cominline sc_fxval &
100012853Sgabeblack@google.comsc_fxval::operator = (const sc_fxval &a)
100112853Sgabeblack@google.com{
100212853Sgabeblack@google.com    if (&a != this) {
100312853Sgabeblack@google.com        SC_FXVAL_OBSERVER_READ_(a)
100412853Sgabeblack@google.com        *m_rep = *a.m_rep;
100512853Sgabeblack@google.com        SC_FXVAL_OBSERVER_WRITE_(*this)
100612853Sgabeblack@google.com    }
100712853Sgabeblack@google.com    return *this;
100812853Sgabeblack@google.com}
100912853Sgabeblack@google.com
101012853Sgabeblack@google.com#define DEFN_ASN_OP_T(tp) \
101112853Sgabeblack@google.cominline sc_fxval & \
101212853Sgabeblack@google.comsc_fxval::operator = (tp b) \
101312853Sgabeblack@google.com{ \
101412853Sgabeblack@google.com    sc_fxval tmp(b); \
101512853Sgabeblack@google.com    *m_rep = *tmp.m_rep; \
101612853Sgabeblack@google.com    SC_FXVAL_OBSERVER_WRITE_(*this) \
101712853Sgabeblack@google.com    return *this; \
101812853Sgabeblack@google.com}
101912853Sgabeblack@google.com
102012853Sgabeblack@google.comDEFN_ASN_OP_T(int)
102112853Sgabeblack@google.comDEFN_ASN_OP_T(unsigned int)
102212853Sgabeblack@google.comDEFN_ASN_OP_T(long)
102312853Sgabeblack@google.comDEFN_ASN_OP_T(unsigned long)
102412853Sgabeblack@google.comDEFN_ASN_OP_T(float)
102512853Sgabeblack@google.comDEFN_ASN_OP_T(double)
102612853Sgabeblack@google.comDEFN_ASN_OP_T(const char *)
102712853Sgabeblack@google.comDEFN_ASN_OP_T(const sc_fxval_fast &)
102812853Sgabeblack@google.com
102912853Sgabeblack@google.comDEFN_ASN_OP_T(int64)
103012853Sgabeblack@google.comDEFN_ASN_OP_T(uint64)
103112853Sgabeblack@google.comDEFN_ASN_OP_T(const sc_int_base &)
103212853Sgabeblack@google.comDEFN_ASN_OP_T(const sc_uint_base &)
103312853Sgabeblack@google.comDEFN_ASN_OP_T(const sc_signed &)
103412853Sgabeblack@google.comDEFN_ASN_OP_T(const sc_unsigned &)
103512853Sgabeblack@google.com
103612853Sgabeblack@google.com#undef DEFN_ASN_OP_T
103712853Sgabeblack@google.com
103812853Sgabeblack@google.com#define DEFN_ASN_OP_T(op, fnc, tp) \
103912853Sgabeblack@google.cominline sc_fxval & \
104012853Sgabeblack@google.comsc_fxval::operator op (tp b) \
104112853Sgabeblack@google.com{ \
104212853Sgabeblack@google.com    SC_FXVAL_OBSERVER_READ_(*this) \
104312853Sgabeblack@google.com    sc_fxval tmp(b); \
104412853Sgabeblack@google.com    scfx_rep *new_rep = sc_dt::fnc ## _scfx_rep(*m_rep, *tmp.m_rep); \
104512853Sgabeblack@google.com    delete m_rep; \
104612853Sgabeblack@google.com    m_rep = new_rep; \
104712853Sgabeblack@google.com    SC_FXVAL_OBSERVER_WRITE_(*this) \
104812853Sgabeblack@google.com    return *this; \
104912853Sgabeblack@google.com}
105012853Sgabeblack@google.com
105112853Sgabeblack@google.com#define DEFN_ASN_OP_OTHER(op, fnc) \
105212853Sgabeblack@google.comDEFN_ASN_OP_T(op, fnc, int64) \
105312853Sgabeblack@google.comDEFN_ASN_OP_T(op, fnc, uint64) \
105412853Sgabeblack@google.comDEFN_ASN_OP_T(op, fnc, const sc_int_base &) \
105512853Sgabeblack@google.comDEFN_ASN_OP_T(op, fnc, const sc_uint_base &) \
105612853Sgabeblack@google.comDEFN_ASN_OP_T(op, fnc, const sc_signed &) \
105712853Sgabeblack@google.comDEFN_ASN_OP_T(op, fnc, const sc_unsigned &)
105812853Sgabeblack@google.com
105912853Sgabeblack@google.com#define DEFN_ASN_OP(op, fnc) \
106012853Sgabeblack@google.cominline sc_fxval & \
106112853Sgabeblack@google.comsc_fxval::operator op (const sc_fxval &b) \
106212853Sgabeblack@google.com{ \
106312853Sgabeblack@google.com    SC_FXVAL_OBSERVER_READ_(*this) \
106412853Sgabeblack@google.com    SC_FXVAL_OBSERVER_READ_(b) \
106512853Sgabeblack@google.com    scfx_rep *new_rep = sc_dt::fnc ## _scfx_rep(*m_rep, *b.m_rep); \
106612853Sgabeblack@google.com    delete m_rep; \
106712853Sgabeblack@google.com    m_rep = new_rep; \
106812853Sgabeblack@google.com    SC_FXVAL_OBSERVER_WRITE_(*this) \
106912853Sgabeblack@google.com    return *this; \
107012853Sgabeblack@google.com} \
107112853Sgabeblack@google.com \
107212853Sgabeblack@google.comDEFN_ASN_OP_T(op, fnc, int) \
107312853Sgabeblack@google.comDEFN_ASN_OP_T(op, fnc, unsigned int) \
107412853Sgabeblack@google.comDEFN_ASN_OP_T(op, fnc, long) \
107512853Sgabeblack@google.comDEFN_ASN_OP_T(op, fnc, unsigned long) \
107612853Sgabeblack@google.comDEFN_ASN_OP_T(op, fnc, float) \
107712853Sgabeblack@google.comDEFN_ASN_OP_T(op, fnc, double) \
107812853Sgabeblack@google.comDEFN_ASN_OP_T(op, fnc, const char *) \
107912853Sgabeblack@google.comDEFN_ASN_OP_T(op, fnc, const sc_fxval_fast &) \
108012853Sgabeblack@google.comDEFN_ASN_OP_OTHER(op, fnc)
108112853Sgabeblack@google.com
108212853Sgabeblack@google.comDEFN_ASN_OP(*=, mult)
108312853Sgabeblack@google.comDEFN_ASN_OP(/=, div)
108412853Sgabeblack@google.comDEFN_ASN_OP(+=, add)
108512853Sgabeblack@google.comDEFN_ASN_OP(-=, sub)
108612853Sgabeblack@google.com
108712853Sgabeblack@google.com#undef DEFN_ASN_OP_T
108812853Sgabeblack@google.com#undef DEFN_ASN_OP_OTHER
108912853Sgabeblack@google.com#undef DEFN_ASN_OP
109012853Sgabeblack@google.com
109112853Sgabeblack@google.cominline sc_fxval &
109212853Sgabeblack@google.comsc_fxval::operator <<= (int b)
109312853Sgabeblack@google.com{
109412853Sgabeblack@google.com    SC_FXVAL_OBSERVER_READ_(*this)
109512853Sgabeblack@google.com    m_rep->lshift(b);
109612853Sgabeblack@google.com    SC_FXVAL_OBSERVER_WRITE_(*this)
109712853Sgabeblack@google.com    return *this;
109812853Sgabeblack@google.com}
109912853Sgabeblack@google.com
110012853Sgabeblack@google.cominline sc_fxval &
110112853Sgabeblack@google.comsc_fxval::operator >>= (int b)
110212853Sgabeblack@google.com{
110312853Sgabeblack@google.com    SC_FXVAL_OBSERVER_READ_(*this)
110412853Sgabeblack@google.com    m_rep->rshift(b);
110512853Sgabeblack@google.com    SC_FXVAL_OBSERVER_WRITE_(*this)
110612853Sgabeblack@google.com    return *this;
110712853Sgabeblack@google.com}
110812853Sgabeblack@google.com
110912853Sgabeblack@google.com// auto-increment and auto-decrement
111012853Sgabeblack@google.cominline const sc_fxval
111112853Sgabeblack@google.comsc_fxval::operator ++ (int)
111212853Sgabeblack@google.com{
111312853Sgabeblack@google.com    sc_fxval c = *this;
111412853Sgabeblack@google.com    (*this) += 1;
111512853Sgabeblack@google.com    return c;
111612853Sgabeblack@google.com}
111712853Sgabeblack@google.com
111812853Sgabeblack@google.cominline const sc_fxval
111912853Sgabeblack@google.comsc_fxval::operator -- (int)
112012853Sgabeblack@google.com{
112112853Sgabeblack@google.com    sc_fxval c = *this;
112212853Sgabeblack@google.com    (*this) -= 1;
112312853Sgabeblack@google.com    return c;
112412853Sgabeblack@google.com}
112512853Sgabeblack@google.com
112612853Sgabeblack@google.cominline sc_fxval &
112712853Sgabeblack@google.comsc_fxval::operator ++ ()
112812853Sgabeblack@google.com{
112912853Sgabeblack@google.com    (*this) += 1;
113012853Sgabeblack@google.com    return *this;
113112853Sgabeblack@google.com}
113212853Sgabeblack@google.com
113312853Sgabeblack@google.cominline sc_fxval &
113412853Sgabeblack@google.comsc_fxval::operator -- ()
113512853Sgabeblack@google.com{
113612853Sgabeblack@google.com    (*this) -= 1;
113712853Sgabeblack@google.com    return *this;
113812853Sgabeblack@google.com}
113912853Sgabeblack@google.com
114012853Sgabeblack@google.com// implicit conversion
114112853Sgabeblack@google.cominline sc_fxval::operator double() const
114212853Sgabeblack@google.com{
114312853Sgabeblack@google.com    SC_FXVAL_OBSERVER_READ_(*this)
114412853Sgabeblack@google.com    return m_rep->to_double();
114512853Sgabeblack@google.com}
114612853Sgabeblack@google.com
114712853Sgabeblack@google.com// explicit conversion to primitive types
114812853Sgabeblack@google.cominline short
114912853Sgabeblack@google.comsc_fxval::to_short() const
115012853Sgabeblack@google.com{
115112853Sgabeblack@google.com    SC_FXVAL_OBSERVER_READ_(*this)
115212853Sgabeblack@google.com    return static_cast<short>(m_rep->to_uint64());
115312853Sgabeblack@google.com}
115412853Sgabeblack@google.com
115512853Sgabeblack@google.cominline unsigned short
115612853Sgabeblack@google.comsc_fxval::to_ushort() const
115712853Sgabeblack@google.com{
115812853Sgabeblack@google.com    SC_FXVAL_OBSERVER_READ_(*this)
115912853Sgabeblack@google.com    return static_cast<unsigned short>(m_rep->to_uint64());
116012853Sgabeblack@google.com}
116112853Sgabeblack@google.com
116212853Sgabeblack@google.cominline int
116312853Sgabeblack@google.comsc_fxval::to_int() const
116412853Sgabeblack@google.com{
116512853Sgabeblack@google.com    SC_FXVAL_OBSERVER_READ_(*this)
116612853Sgabeblack@google.com    return static_cast<int>(m_rep->to_uint64());
116712853Sgabeblack@google.com}
116812853Sgabeblack@google.com
116912853Sgabeblack@google.cominline int64
117012853Sgabeblack@google.comsc_fxval::to_int64() const
117112853Sgabeblack@google.com{
117212853Sgabeblack@google.com    SC_FXVAL_OBSERVER_READ_(*this)
117312853Sgabeblack@google.com    return static_cast<int64>(m_rep->to_uint64());
117412853Sgabeblack@google.com}
117512853Sgabeblack@google.com
117612853Sgabeblack@google.cominline unsigned int
117712853Sgabeblack@google.comsc_fxval::to_uint() const
117812853Sgabeblack@google.com{
117912853Sgabeblack@google.com    SC_FXVAL_OBSERVER_READ_(*this)
118012853Sgabeblack@google.com    return static_cast<unsigned int>(m_rep->to_uint64());
118112853Sgabeblack@google.com}
118212853Sgabeblack@google.com
118312853Sgabeblack@google.cominline uint64
118412853Sgabeblack@google.comsc_fxval::to_uint64() const
118512853Sgabeblack@google.com{
118612853Sgabeblack@google.com    SC_FXVAL_OBSERVER_READ_(*this)
118712853Sgabeblack@google.com    return m_rep->to_uint64();
118812853Sgabeblack@google.com}
118912853Sgabeblack@google.com
119012853Sgabeblack@google.cominline long
119112853Sgabeblack@google.comsc_fxval::to_long() const
119212853Sgabeblack@google.com{
119312853Sgabeblack@google.com    SC_FXVAL_OBSERVER_READ_(*this)
119412853Sgabeblack@google.com    return static_cast<long>(m_rep->to_uint64());
119512853Sgabeblack@google.com}
119612853Sgabeblack@google.com
119712853Sgabeblack@google.cominline unsigned long
119812853Sgabeblack@google.comsc_fxval::to_ulong() const
119912853Sgabeblack@google.com{
120012853Sgabeblack@google.com    SC_FXVAL_OBSERVER_READ_(*this)
120112853Sgabeblack@google.com    return static_cast<unsigned long>(m_rep->to_uint64());
120212853Sgabeblack@google.com}
120312853Sgabeblack@google.com
120412853Sgabeblack@google.cominline float
120512853Sgabeblack@google.comsc_fxval::to_float() const
120612853Sgabeblack@google.com{
120712853Sgabeblack@google.com    SC_FXVAL_OBSERVER_READ_(*this)
120812853Sgabeblack@google.com    return static_cast<float>(m_rep->to_double());
120912853Sgabeblack@google.com}
121012853Sgabeblack@google.com
121112853Sgabeblack@google.cominline double
121212853Sgabeblack@google.comsc_fxval::to_double() const
121312853Sgabeblack@google.com{
121412853Sgabeblack@google.com    SC_FXVAL_OBSERVER_READ_(*this)
121512853Sgabeblack@google.com    return m_rep->to_double();
121612853Sgabeblack@google.com}
121712853Sgabeblack@google.com
121812853Sgabeblack@google.com// query value
121912853Sgabeblack@google.cominline bool
122012853Sgabeblack@google.comsc_fxval::is_neg() const
122112853Sgabeblack@google.com{
122212853Sgabeblack@google.com    SC_FXVAL_OBSERVER_READ_(*this)
122312853Sgabeblack@google.com    return m_rep->is_neg();
122412853Sgabeblack@google.com}
122512853Sgabeblack@google.com
122612853Sgabeblack@google.cominline bool
122712853Sgabeblack@google.comsc_fxval::is_zero() const
122812853Sgabeblack@google.com{
122912853Sgabeblack@google.com    SC_FXVAL_OBSERVER_READ_(*this)
123012853Sgabeblack@google.com    return m_rep->is_zero();
123112853Sgabeblack@google.com}
123212853Sgabeblack@google.com
123312853Sgabeblack@google.cominline bool
123412853Sgabeblack@google.comsc_fxval::is_nan() const
123512853Sgabeblack@google.com{
123612853Sgabeblack@google.com    SC_FXVAL_OBSERVER_READ_(*this)
123712853Sgabeblack@google.com    return m_rep->is_nan();
123812853Sgabeblack@google.com}
123912853Sgabeblack@google.com
124012853Sgabeblack@google.cominline bool
124112853Sgabeblack@google.comsc_fxval::is_inf() const
124212853Sgabeblack@google.com{
124312853Sgabeblack@google.com    SC_FXVAL_OBSERVER_READ_(*this)
124412853Sgabeblack@google.com    return m_rep->is_inf();
124512853Sgabeblack@google.com}
124612853Sgabeblack@google.com
124712853Sgabeblack@google.cominline bool
124812853Sgabeblack@google.comsc_fxval::is_normal() const
124912853Sgabeblack@google.com{
125012853Sgabeblack@google.com    SC_FXVAL_OBSERVER_READ_(*this)
125112853Sgabeblack@google.com    return m_rep->is_normal();
125212853Sgabeblack@google.com}
125312853Sgabeblack@google.com
125412853Sgabeblack@google.cominline bool
125512853Sgabeblack@google.comsc_fxval::rounding_flag() const
125612853Sgabeblack@google.com{
125712853Sgabeblack@google.com    return m_rep->rounding_flag();
125812853Sgabeblack@google.com}
125912853Sgabeblack@google.com
126012853Sgabeblack@google.com// internal use only;
126112853Sgabeblack@google.cominline bool
126212853Sgabeblack@google.comsc_fxval::get_bit(int i) const
126312853Sgabeblack@google.com{
126412853Sgabeblack@google.com    return m_rep->get_bit(i);
126512853Sgabeblack@google.com}
126612853Sgabeblack@google.com
126712853Sgabeblack@google.com// protected methods and friend functions
126812853Sgabeblack@google.cominline void
126912853Sgabeblack@google.comsc_fxval::get_type(int &wl, int &iwl, sc_enc &enc) const
127012853Sgabeblack@google.com{
127112853Sgabeblack@google.com    m_rep->get_type(wl, iwl, enc);
127212853Sgabeblack@google.com}
127312853Sgabeblack@google.com
127412853Sgabeblack@google.cominline const sc_fxval
127512853Sgabeblack@google.comsc_fxval::quantization(const scfx_params &params, bool &q_flag) const
127612853Sgabeblack@google.com{
127712853Sgabeblack@google.com    return sc_fxval(sc_dt::quantization_scfx_rep(*m_rep, params, q_flag));
127812853Sgabeblack@google.com}
127912853Sgabeblack@google.com
128012853Sgabeblack@google.cominline const sc_fxval
128112853Sgabeblack@google.comsc_fxval::overflow(const scfx_params &params, bool &o_flag) const
128212853Sgabeblack@google.com{
128312853Sgabeblack@google.com    return sc_fxval(sc_dt::overflow_scfx_rep(*m_rep, params, o_flag));
128412853Sgabeblack@google.com}
128512853Sgabeblack@google.com
128612853Sgabeblack@google.cominline ::std::ostream &
128712853Sgabeblack@google.comoperator << (::std::ostream &os, const sc_fxval &a)
128812853Sgabeblack@google.com{
128912853Sgabeblack@google.com    a.print(os);
129012853Sgabeblack@google.com    return os;
129112853Sgabeblack@google.com}
129212853Sgabeblack@google.com
129312853Sgabeblack@google.cominline ::std::istream &
129412853Sgabeblack@google.comoperator >> (::std::istream &is, sc_fxval &a)
129512853Sgabeblack@google.com{
129612853Sgabeblack@google.com    a.scan(is);
129712853Sgabeblack@google.com    return is;
129812853Sgabeblack@google.com}
129912853Sgabeblack@google.com
130012853Sgabeblack@google.com
130112853Sgabeblack@google.com// ----------------------------------------------------------------------------
130212853Sgabeblack@google.com//  CLASS : sc_fxval_fast
130312853Sgabeblack@google.com//
130412853Sgabeblack@google.com//  Fixed-point value type; limited precision.
130512853Sgabeblack@google.com// ----------------------------------------------------------------------------
130612853Sgabeblack@google.com
130712853Sgabeblack@google.com// protected method
130812853Sgabeblack@google.cominline sc_fxval_fast_observer *
130912853Sgabeblack@google.comsc_fxval_fast::observer() const
131012853Sgabeblack@google.com{
131112853Sgabeblack@google.com    return m_observer;
131212853Sgabeblack@google.com}
131312853Sgabeblack@google.com
131412853Sgabeblack@google.com
131512853Sgabeblack@google.com// public constructors
131612853Sgabeblack@google.cominline sc_fxval_fast::sc_fxval_fast(sc_fxval_fast_observer *observer_) :
131712853Sgabeblack@google.com    m_val(0.0), m_observer(observer_)
131812853Sgabeblack@google.com{
131912853Sgabeblack@google.com    SC_FXVAL_FAST_OBSERVER_DEFAULT_
132012853Sgabeblack@google.com    SC_FXVAL_FAST_OBSERVER_CONSTRUCT_(*this)
132112853Sgabeblack@google.com}
132212853Sgabeblack@google.com
132312853Sgabeblack@google.cominline sc_fxval_fast::sc_fxval_fast(const sc_fxval_fast &a,
132412853Sgabeblack@google.com                                    sc_fxval_fast_observer *observer_) :
132512853Sgabeblack@google.com    m_val(a.m_val), m_observer(observer_)
132612853Sgabeblack@google.com{
132712853Sgabeblack@google.com    SC_FXVAL_FAST_OBSERVER_DEFAULT_
132812853Sgabeblack@google.com    SC_FXVAL_FAST_OBSERVER_READ_(a)
132912853Sgabeblack@google.com    SC_FXVAL_FAST_OBSERVER_CONSTRUCT_(*this)
133012853Sgabeblack@google.com    SC_FXVAL_FAST_OBSERVER_WRITE_(*this)
133112853Sgabeblack@google.com}
133212853Sgabeblack@google.com
133312853Sgabeblack@google.com#define DEFN_CTOR_T(tp, arg) \
133412853Sgabeblack@google.cominline sc_fxval_fast::sc_fxval_fast( \
133512853Sgabeblack@google.com        tp a, sc_fxval_fast_observer * observer_) : \
133612853Sgabeblack@google.com    m_val(arg), m_observer(observer_) \
133712853Sgabeblack@google.com{ \
133812853Sgabeblack@google.com    SC_FXVAL_FAST_OBSERVER_DEFAULT_ \
133912853Sgabeblack@google.com    SC_FXVAL_FAST_OBSERVER_CONSTRUCT_(*this) \
134012853Sgabeblack@google.com    SC_FXVAL_FAST_OBSERVER_WRITE_(*this) \
134112853Sgabeblack@google.com}
134212853Sgabeblack@google.com
134312853Sgabeblack@google.com#define DEFN_CTOR_T_A(tp) DEFN_CTOR_T(tp, static_cast<double>(a))
134412853Sgabeblack@google.com#define DEFN_CTOR_T_B(tp) DEFN_CTOR_T(tp, from_string(a))
134512853Sgabeblack@google.com#define DEFN_CTOR_T_C(tp) DEFN_CTOR_T(tp, a.to_double())
134612853Sgabeblack@google.com
134712853Sgabeblack@google.comDEFN_CTOR_T_A(int)
134812853Sgabeblack@google.comDEFN_CTOR_T_A(unsigned int)
134912853Sgabeblack@google.comDEFN_CTOR_T_A(long)
135012853Sgabeblack@google.comDEFN_CTOR_T_A(unsigned long)
135112853Sgabeblack@google.comDEFN_CTOR_T_A(float)
135212853Sgabeblack@google.comDEFN_CTOR_T_A(double)
135312853Sgabeblack@google.comDEFN_CTOR_T_B(const char *)
135412853Sgabeblack@google.comDEFN_CTOR_T_C(const sc_fxval &)
135512853Sgabeblack@google.com
135612853Sgabeblack@google.comDEFN_CTOR_T_A(int64)
135712853Sgabeblack@google.comDEFN_CTOR_T_A(uint64)
135812853Sgabeblack@google.comDEFN_CTOR_T_C(const sc_int_base &)
135912853Sgabeblack@google.comDEFN_CTOR_T_C(const sc_uint_base &)
136012853Sgabeblack@google.comDEFN_CTOR_T_C(const sc_signed &)
136112853Sgabeblack@google.comDEFN_CTOR_T_C(const sc_unsigned &)
136212853Sgabeblack@google.com
136312853Sgabeblack@google.com#undef DEFN_CTOR_T
136412853Sgabeblack@google.com#undef DEFN_CTOR_T_A
136512853Sgabeblack@google.com#undef DEFN_CTOR_T_B
136612853Sgabeblack@google.com#undef DEFN_CTOR_T_C
136712853Sgabeblack@google.com#undef DEFN_CTOR_T_D
136812853Sgabeblack@google.com#undef DEFN_CTOR_T_E
136912853Sgabeblack@google.com
137012853Sgabeblack@google.cominline sc_fxval_fast::~sc_fxval_fast()
137112853Sgabeblack@google.com{
137212853Sgabeblack@google.com    SC_FXVAL_FAST_OBSERVER_DESTRUCT_(*this)
137312853Sgabeblack@google.com}
137412853Sgabeblack@google.com
137512853Sgabeblack@google.com// internal use only;
137612853Sgabeblack@google.cominline double
137712853Sgabeblack@google.comsc_fxval_fast::get_val() const
137812853Sgabeblack@google.com{
137912853Sgabeblack@google.com    SC_FXVAL_FAST_OBSERVER_READ_(*this)
138012853Sgabeblack@google.com    return m_val;
138112853Sgabeblack@google.com}
138212853Sgabeblack@google.com
138312853Sgabeblack@google.com// internal use only;
138412853Sgabeblack@google.cominline void
138512853Sgabeblack@google.comsc_fxval_fast::set_val(double val_)
138612853Sgabeblack@google.com{
138712853Sgabeblack@google.com    m_val = val_;
138812853Sgabeblack@google.com    SC_FXVAL_FAST_OBSERVER_WRITE_(*this)
138912853Sgabeblack@google.com}
139012853Sgabeblack@google.com
139112853Sgabeblack@google.com// unary operators
139212853Sgabeblack@google.cominline const sc_fxval_fast
139312853Sgabeblack@google.comsc_fxval_fast::operator - () const
139412853Sgabeblack@google.com{
139512853Sgabeblack@google.com    SC_FXVAL_FAST_OBSERVER_READ_(*this)
139612853Sgabeblack@google.com    return sc_fxval_fast(-m_val);
139712853Sgabeblack@google.com}
139812853Sgabeblack@google.com
139912853Sgabeblack@google.cominline const sc_fxval_fast &
140012853Sgabeblack@google.comsc_fxval_fast::operator + () const
140112853Sgabeblack@google.com{
140212853Sgabeblack@google.com    // SC_FXVAL_FAST_OBSERVER_READ_(*this)
140312853Sgabeblack@google.com    return *this;
140412853Sgabeblack@google.com}
140512853Sgabeblack@google.com
140612853Sgabeblack@google.com// unary functions
140712853Sgabeblack@google.cominline void
140812853Sgabeblack@google.comneg(sc_fxval_fast &c, const sc_fxval_fast &a)
140912853Sgabeblack@google.com{
141012853Sgabeblack@google.com    SC_FXVAL_FAST_OBSERVER_READ_(a)
141112853Sgabeblack@google.com    c.m_val = - a.m_val;
141212853Sgabeblack@google.com    SC_FXVAL_FAST_OBSERVER_WRITE_(c)
141312853Sgabeblack@google.com}
141412853Sgabeblack@google.com
141512853Sgabeblack@google.com// binary operators
141612853Sgabeblack@google.com#define DEFN_BIN_OP_T(op, tp) \
141712853Sgabeblack@google.cominline const sc_fxval_fast \
141812853Sgabeblack@google.comoperator op (const sc_fxval_fast &a, tp b) \
141912853Sgabeblack@google.com{ \
142012853Sgabeblack@google.com    SC_FXVAL_FAST_OBSERVER_READ_(a) \
142112853Sgabeblack@google.com    sc_fxval_fast tmp(b); \
142212853Sgabeblack@google.com    return sc_fxval_fast(a.m_val op tmp.m_val); \
142312853Sgabeblack@google.com} \
142412853Sgabeblack@google.com \
142512853Sgabeblack@google.cominline const sc_fxval_fast \
142612853Sgabeblack@google.comoperator op (tp a, const sc_fxval_fast &b) \
142712853Sgabeblack@google.com{ \
142812853Sgabeblack@google.com    SC_FXVAL_FAST_OBSERVER_READ_(b) \
142912853Sgabeblack@google.com    sc_fxval_fast tmp(a); \
143012853Sgabeblack@google.com    return sc_fxval_fast(tmp.m_val op b.m_val); \
143112853Sgabeblack@google.com}
143212853Sgabeblack@google.com
143312853Sgabeblack@google.com#define DEFN_BIN_OP_OTHER(op) \
143412853Sgabeblack@google.comDEFN_BIN_OP_T(op, int64) \
143512853Sgabeblack@google.comDEFN_BIN_OP_T(op, uint64) \
143612853Sgabeblack@google.comDEFN_BIN_OP_T(op, const sc_int_base &) \
143712853Sgabeblack@google.comDEFN_BIN_OP_T(op, const sc_uint_base &) \
143812853Sgabeblack@google.comDEFN_BIN_OP_T(op, const sc_signed &) \
143912853Sgabeblack@google.comDEFN_BIN_OP_T(op, const sc_unsigned &)
144012853Sgabeblack@google.com
144112853Sgabeblack@google.com#define DEFN_BIN_OP(op, dummy) \
144212853Sgabeblack@google.cominline const sc_fxval_fast \
144312853Sgabeblack@google.comoperator op (const sc_fxval_fast &a, const sc_fxval_fast &b) \
144412853Sgabeblack@google.com{ \
144512853Sgabeblack@google.com    SC_FXVAL_FAST_OBSERVER_READ_(a) \
144612853Sgabeblack@google.com    SC_FXVAL_FAST_OBSERVER_READ_(b) \
144712853Sgabeblack@google.com    return sc_fxval_fast(a.m_val op b.m_val); \
144812853Sgabeblack@google.com} \
144912853Sgabeblack@google.com \
145012853Sgabeblack@google.comDEFN_BIN_OP_T(op, int) \
145112853Sgabeblack@google.comDEFN_BIN_OP_T(op, unsigned int) \
145212853Sgabeblack@google.comDEFN_BIN_OP_T(op, long) \
145312853Sgabeblack@google.comDEFN_BIN_OP_T(op, unsigned long) \
145412853Sgabeblack@google.comDEFN_BIN_OP_T(op, float) \
145512853Sgabeblack@google.comDEFN_BIN_OP_T(op, double) \
145612853Sgabeblack@google.comDEFN_BIN_OP_T(op, const char *) \
145712853Sgabeblack@google.comDEFN_BIN_OP_OTHER(op)
145812853Sgabeblack@google.com
145912853Sgabeblack@google.comDEFN_BIN_OP(*, mult)
146012853Sgabeblack@google.comDEFN_BIN_OP(+, add)
146112853Sgabeblack@google.comDEFN_BIN_OP(-, sub)
146212853Sgabeblack@google.com//DEFN_BIN_OP(/, div)
146312853Sgabeblack@google.cominline const sc_fxval_fast
146412853Sgabeblack@google.comoperator / (const sc_fxval_fast &a, const sc_fxval_fast &b)
146512853Sgabeblack@google.com{
146612853Sgabeblack@google.com    SC_FXVAL_FAST_OBSERVER_READ_(a)
146712853Sgabeblack@google.com    SC_FXVAL_FAST_OBSERVER_READ_(b)
146812853Sgabeblack@google.com    return sc_fxval_fast(a.m_val / b.m_val);
146912853Sgabeblack@google.com}
147012853Sgabeblack@google.com
147112853Sgabeblack@google.comDEFN_BIN_OP_T(/, int)
147212853Sgabeblack@google.comDEFN_BIN_OP_T(/, unsigned int)
147312853Sgabeblack@google.comDEFN_BIN_OP_T(/, long)
147412853Sgabeblack@google.comDEFN_BIN_OP_T(/, unsigned long)
147512853Sgabeblack@google.comDEFN_BIN_OP_T(/, float)
147612853Sgabeblack@google.comDEFN_BIN_OP_T(/, double)
147712853Sgabeblack@google.comDEFN_BIN_OP_T(/, const char *)
147812853Sgabeblack@google.com//DEFN_BIN_OP_OTHER(/)
147912853Sgabeblack@google.com
148012853Sgabeblack@google.comDEFN_BIN_OP_T(/, int64)
148112853Sgabeblack@google.comDEFN_BIN_OP_T(/, uint64)
148212853Sgabeblack@google.comDEFN_BIN_OP_T(/, const sc_int_base &)
148312853Sgabeblack@google.comDEFN_BIN_OP_T(/, const sc_uint_base &)
148412853Sgabeblack@google.comDEFN_BIN_OP_T(/, const sc_signed &)
148512853Sgabeblack@google.comDEFN_BIN_OP_T(/, const sc_unsigned &)
148612853Sgabeblack@google.com
148712853Sgabeblack@google.com
148812853Sgabeblack@google.com#undef DEFN_BIN_OP_T
148912853Sgabeblack@google.com#undef DEFN_BIN_OP_OTHER
149012853Sgabeblack@google.com#undef DEFN_BIN_OP
149112853Sgabeblack@google.com
149212853Sgabeblack@google.com
149312853Sgabeblack@google.cominline const sc_fxval_fast
149412853Sgabeblack@google.comoperator << (const sc_fxval_fast &a, int b)
149512853Sgabeblack@google.com{
149612853Sgabeblack@google.com    SC_FXVAL_FAST_OBSERVER_READ_(a)
149712853Sgabeblack@google.com    return sc_fxval_fast(a.m_val * scfx_pow2(b));
149812853Sgabeblack@google.com}
149912853Sgabeblack@google.com
150012853Sgabeblack@google.cominline const sc_fxval_fast
150112853Sgabeblack@google.comoperator >> (const sc_fxval_fast &a, int b)
150212853Sgabeblack@google.com{
150312853Sgabeblack@google.com    SC_FXVAL_FAST_OBSERVER_READ_(a)
150412853Sgabeblack@google.com    return sc_fxval_fast(a.m_val * scfx_pow2(-b));
150512853Sgabeblack@google.com}
150612853Sgabeblack@google.com
150712853Sgabeblack@google.com// binary functions
150812853Sgabeblack@google.com#define DEFN_BIN_FNC_T(fnc, op, tp) \
150912853Sgabeblack@google.cominline void \
151012853Sgabeblack@google.comfnc (sc_fxval_fast &c, const sc_fxval_fast &a, tp b) \
151112853Sgabeblack@google.com{ \
151212853Sgabeblack@google.com    SC_FXVAL_FAST_OBSERVER_READ_(a) \
151312853Sgabeblack@google.com    sc_fxval_fast tmp(b); \
151412853Sgabeblack@google.com    c.m_val = a.m_val op tmp.m_val; \
151512853Sgabeblack@google.com    SC_FXVAL_FAST_OBSERVER_WRITE_(c) \
151612853Sgabeblack@google.com} \
151712853Sgabeblack@google.com \
151812853Sgabeblack@google.cominline void \
151912853Sgabeblack@google.comfnc (sc_fxval_fast &c, tp a, const sc_fxval_fast &b) \
152012853Sgabeblack@google.com{ \
152112853Sgabeblack@google.com    SC_FXVAL_FAST_OBSERVER_READ_(b) \
152212853Sgabeblack@google.com    sc_fxval_fast tmp(a); \
152312853Sgabeblack@google.com    c.m_val = tmp.m_val op b.m_val; \
152412853Sgabeblack@google.com    SC_FXVAL_FAST_OBSERVER_WRITE_(c) \
152512853Sgabeblack@google.com}
152612853Sgabeblack@google.com
152712853Sgabeblack@google.com#define DEFN_BIN_FNC_OTHER(fnc, op) \
152812853Sgabeblack@google.comDEFN_BIN_FNC_T(fnc, op, int64) \
152912853Sgabeblack@google.comDEFN_BIN_FNC_T(fnc, op, uint64) \
153012853Sgabeblack@google.comDEFN_BIN_FNC_T(fnc, op, const sc_int_base &) \
153112853Sgabeblack@google.comDEFN_BIN_FNC_T(fnc, op, const sc_uint_base &) \
153212853Sgabeblack@google.comDEFN_BIN_FNC_T(fnc, op, const sc_signed &) \
153312853Sgabeblack@google.comDEFN_BIN_FNC_T(fnc, op, const sc_unsigned &)
153412853Sgabeblack@google.com
153512853Sgabeblack@google.com#define DEFN_BIN_FNC(fnc, op) \
153612853Sgabeblack@google.cominline void \
153712853Sgabeblack@google.comfnc (sc_fxval_fast &c, const sc_fxval_fast &a, const sc_fxval_fast &b) \
153812853Sgabeblack@google.com{ \
153912853Sgabeblack@google.com    SC_FXVAL_FAST_OBSERVER_READ_(a) \
154012853Sgabeblack@google.com    SC_FXVAL_FAST_OBSERVER_READ_(b) \
154112853Sgabeblack@google.com    c.m_val = a.m_val op b.m_val; \
154212853Sgabeblack@google.com    SC_FXVAL_FAST_OBSERVER_WRITE_(c) \
154312853Sgabeblack@google.com} \
154412853Sgabeblack@google.com \
154512853Sgabeblack@google.comDEFN_BIN_FNC_T(fnc, op, int) \
154612853Sgabeblack@google.comDEFN_BIN_FNC_T(fnc, op, unsigned int) \
154712853Sgabeblack@google.comDEFN_BIN_FNC_T(fnc, op, long) \
154812853Sgabeblack@google.comDEFN_BIN_FNC_T(fnc, op, unsigned long) \
154912853Sgabeblack@google.comDEFN_BIN_FNC_T(fnc, op, float) \
155012853Sgabeblack@google.comDEFN_BIN_FNC_T(fnc, op, double) \
155112853Sgabeblack@google.comDEFN_BIN_FNC_T(fnc, op, const char *) \
155212853Sgabeblack@google.comDEFN_BIN_FNC_OTHER(fnc, op)
155312853Sgabeblack@google.com
155412853Sgabeblack@google.comDEFN_BIN_FNC(mult, *)
155512853Sgabeblack@google.comDEFN_BIN_FNC(div, /)
155612853Sgabeblack@google.comDEFN_BIN_FNC(add, +)
155712853Sgabeblack@google.comDEFN_BIN_FNC(sub, -)
155812853Sgabeblack@google.com
155912853Sgabeblack@google.com#undef DEFN_BIN_FNC_T
156012853Sgabeblack@google.com#undef DEFN_BIN_FNC_OTHER
156112853Sgabeblack@google.com#undef DEFN_BIN_FNC
156212853Sgabeblack@google.com
156312853Sgabeblack@google.cominline void
156412853Sgabeblack@google.comlshift(sc_fxval_fast &c, const sc_fxval_fast &a, int b)
156512853Sgabeblack@google.com{
156612853Sgabeblack@google.com    SC_FXVAL_FAST_OBSERVER_READ_(a)
156712853Sgabeblack@google.com    c.m_val = a.m_val * scfx_pow2(b);
156812853Sgabeblack@google.com    SC_FXVAL_FAST_OBSERVER_WRITE_(c)
156912853Sgabeblack@google.com}
157012853Sgabeblack@google.com
157112853Sgabeblack@google.cominline void
157212853Sgabeblack@google.comrshift(sc_fxval_fast &c, const sc_fxval_fast &a, int b)
157312853Sgabeblack@google.com{
157412853Sgabeblack@google.com    SC_FXVAL_FAST_OBSERVER_READ_(a)
157512853Sgabeblack@google.com    c.m_val = a.m_val * scfx_pow2(-b);
157612853Sgabeblack@google.com    SC_FXVAL_FAST_OBSERVER_WRITE_(c)
157712853Sgabeblack@google.com}
157812853Sgabeblack@google.com
157912853Sgabeblack@google.com// relational (including equality) operators
158012853Sgabeblack@google.com#define DEFN_REL_OP_T(op, tp) \
158112853Sgabeblack@google.cominline bool \
158212853Sgabeblack@google.comoperator op (const sc_fxval_fast &a, tp b) \
158312853Sgabeblack@google.com{ \
158412853Sgabeblack@google.com    SC_FXVAL_FAST_OBSERVER_READ_(a) \
158512853Sgabeblack@google.com    sc_fxval_fast tmp(b); \
158612853Sgabeblack@google.com    return (a.m_val op tmp.m_val); \
158712853Sgabeblack@google.com} \
158812853Sgabeblack@google.com \
158912853Sgabeblack@google.cominline bool \
159012853Sgabeblack@google.comoperator op (tp a, const sc_fxval_fast &b) \
159112853Sgabeblack@google.com{ \
159212853Sgabeblack@google.com    SC_FXVAL_FAST_OBSERVER_READ_(b) \
159312853Sgabeblack@google.com    sc_fxval_fast tmp(a); \
159412853Sgabeblack@google.com    return (tmp.m_val op b.m_val); \
159512853Sgabeblack@google.com}
159612853Sgabeblack@google.com
159712853Sgabeblack@google.com#define DEFN_REL_OP_OTHER(op) \
159812853Sgabeblack@google.comDEFN_REL_OP_T(op, int64) \
159912853Sgabeblack@google.comDEFN_REL_OP_T(op, uint64) \
160012853Sgabeblack@google.comDEFN_REL_OP_T(op, const sc_int_base &) \
160112853Sgabeblack@google.comDEFN_REL_OP_T(op, const sc_uint_base &) \
160212853Sgabeblack@google.comDEFN_REL_OP_T(op, const sc_signed &) \
160312853Sgabeblack@google.comDEFN_REL_OP_T(op, const sc_unsigned &)
160412853Sgabeblack@google.com
160512853Sgabeblack@google.com#define DEFN_REL_OP(op) \
160612853Sgabeblack@google.cominline bool \
160712853Sgabeblack@google.comoperator op (const sc_fxval_fast &a, const sc_fxval_fast &b) \
160812853Sgabeblack@google.com{ \
160912853Sgabeblack@google.com    SC_FXVAL_FAST_OBSERVER_READ_(a) \
161012853Sgabeblack@google.com    SC_FXVAL_FAST_OBSERVER_READ_(b) \
161112853Sgabeblack@google.com    return (a.m_val op b.m_val); \
161212853Sgabeblack@google.com} \
161312853Sgabeblack@google.com \
161412853Sgabeblack@google.comDEFN_REL_OP_T(op, int) \
161512853Sgabeblack@google.comDEFN_REL_OP_T(op, unsigned int) \
161612853Sgabeblack@google.comDEFN_REL_OP_T(op, long) \
161712853Sgabeblack@google.comDEFN_REL_OP_T(op, unsigned long) \
161812853Sgabeblack@google.comDEFN_REL_OP_T(op, float) \
161912853Sgabeblack@google.comDEFN_REL_OP_T(op, double) \
162012853Sgabeblack@google.comDEFN_REL_OP_T(op, const char *) \
162112853Sgabeblack@google.comDEFN_REL_OP_OTHER(op)
162212853Sgabeblack@google.com
162312853Sgabeblack@google.comDEFN_REL_OP(<)
162412853Sgabeblack@google.comDEFN_REL_OP(<=)
162512853Sgabeblack@google.comDEFN_REL_OP(>)
162612853Sgabeblack@google.comDEFN_REL_OP(>=)
162712853Sgabeblack@google.comDEFN_REL_OP(==)
162812853Sgabeblack@google.comDEFN_REL_OP(!=)
162912853Sgabeblack@google.com
163012853Sgabeblack@google.com#undef DEFN_REL_OP_T
163112853Sgabeblack@google.com#undef DEFN_REL_OP_OTHER
163212853Sgabeblack@google.com#undef DEFN_REL_OP
163312853Sgabeblack@google.com
163412853Sgabeblack@google.com// assignment operators
163512853Sgabeblack@google.cominline sc_fxval_fast &
163612853Sgabeblack@google.comsc_fxval_fast::operator = (const sc_fxval_fast &a)
163712853Sgabeblack@google.com{
163812853Sgabeblack@google.com    if (&a != this) {
163912853Sgabeblack@google.com        SC_FXVAL_FAST_OBSERVER_READ_(a)
164012853Sgabeblack@google.com        m_val = a.m_val;
164112853Sgabeblack@google.com        SC_FXVAL_FAST_OBSERVER_WRITE_(*this)
164212853Sgabeblack@google.com    }
164312853Sgabeblack@google.com    return *this;
164412853Sgabeblack@google.com}
164512853Sgabeblack@google.com
164612853Sgabeblack@google.com#define DEFN_ASN_OP_T(tp) \
164712853Sgabeblack@google.cominline sc_fxval_fast & \
164812853Sgabeblack@google.comsc_fxval_fast::operator = (tp a) \
164912853Sgabeblack@google.com{ \
165012853Sgabeblack@google.com    sc_fxval_fast tmp(a); \
165112853Sgabeblack@google.com    m_val = tmp.m_val; \
165212853Sgabeblack@google.com    SC_FXVAL_FAST_OBSERVER_WRITE_(*this) \
165312853Sgabeblack@google.com    return *this; \
165412853Sgabeblack@google.com}
165512853Sgabeblack@google.com
165612853Sgabeblack@google.comDEFN_ASN_OP_T(int)
165712853Sgabeblack@google.comDEFN_ASN_OP_T(unsigned int)
165812853Sgabeblack@google.comDEFN_ASN_OP_T(long)
165912853Sgabeblack@google.comDEFN_ASN_OP_T(unsigned long)
166012853Sgabeblack@google.comDEFN_ASN_OP_T(float)
166112853Sgabeblack@google.comDEFN_ASN_OP_T(double)
166212853Sgabeblack@google.comDEFN_ASN_OP_T(const char *)
166312853Sgabeblack@google.comDEFN_ASN_OP_T(const sc_fxval &)
166412853Sgabeblack@google.com
166512853Sgabeblack@google.comDEFN_ASN_OP_T(int64)
166612853Sgabeblack@google.comDEFN_ASN_OP_T(uint64)
166712853Sgabeblack@google.comDEFN_ASN_OP_T(const sc_int_base &)
166812853Sgabeblack@google.comDEFN_ASN_OP_T(const sc_uint_base &)
166912853Sgabeblack@google.comDEFN_ASN_OP_T(const sc_signed &)
167012853Sgabeblack@google.comDEFN_ASN_OP_T(const sc_unsigned &)
167112853Sgabeblack@google.com
167212853Sgabeblack@google.com#undef DEFN_ASN_OP_T
167312853Sgabeblack@google.com
167412853Sgabeblack@google.com#define DEFN_ASN_OP_T(op, tp) \
167512853Sgabeblack@google.cominline sc_fxval_fast & \
167612853Sgabeblack@google.comsc_fxval_fast::operator op (tp b) \
167712853Sgabeblack@google.com{ \
167812853Sgabeblack@google.com    SC_FXVAL_FAST_OBSERVER_READ_(*this) \
167912853Sgabeblack@google.com    sc_fxval_fast tmp(b); \
168012853Sgabeblack@google.com    m_val op tmp.m_val; \
168112853Sgabeblack@google.com    SC_FXVAL_FAST_OBSERVER_WRITE_(*this) \
168212853Sgabeblack@google.com    return *this; \
168312853Sgabeblack@google.com}
168412853Sgabeblack@google.com
168512853Sgabeblack@google.com#define DEFN_ASN_OP_OTHER(op) \
168612853Sgabeblack@google.comDEFN_ASN_OP_T(op, int64) \
168712853Sgabeblack@google.comDEFN_ASN_OP_T(op, uint64) \
168812853Sgabeblack@google.comDEFN_ASN_OP_T(op, const sc_int_base &) \
168912853Sgabeblack@google.comDEFN_ASN_OP_T(op, const sc_uint_base &) \
169012853Sgabeblack@google.comDEFN_ASN_OP_T(op, const sc_signed &) \
169112853Sgabeblack@google.comDEFN_ASN_OP_T(op, const sc_unsigned &)
169212853Sgabeblack@google.com
169312853Sgabeblack@google.com#define DEFN_ASN_OP(op) \
169412853Sgabeblack@google.cominline sc_fxval_fast & \
169512853Sgabeblack@google.comsc_fxval_fast::operator op (const sc_fxval_fast &b) \
169612853Sgabeblack@google.com{ \
169712853Sgabeblack@google.com    SC_FXVAL_FAST_OBSERVER_READ_(*this) \
169812853Sgabeblack@google.com    SC_FXVAL_FAST_OBSERVER_READ_(b) \
169912853Sgabeblack@google.com    m_val op b.m_val; \
170012853Sgabeblack@google.com    SC_FXVAL_FAST_OBSERVER_WRITE_(*this) \
170112853Sgabeblack@google.com    return *this; \
170212853Sgabeblack@google.com} \
170312853Sgabeblack@google.com \
170412853Sgabeblack@google.comDEFN_ASN_OP_T(op, int) \
170512853Sgabeblack@google.comDEFN_ASN_OP_T(op, unsigned int) \
170612853Sgabeblack@google.comDEFN_ASN_OP_T(op, long) \
170712853Sgabeblack@google.comDEFN_ASN_OP_T(op, unsigned long) \
170812853Sgabeblack@google.comDEFN_ASN_OP_T(op, float) \
170912853Sgabeblack@google.comDEFN_ASN_OP_T(op, double) \
171012853Sgabeblack@google.comDEFN_ASN_OP_T(op, const char *) \
171112853Sgabeblack@google.comDEFN_ASN_OP_T(op, const sc_fxval &) \
171212853Sgabeblack@google.comDEFN_ASN_OP_OTHER(op)
171312853Sgabeblack@google.com
171412853Sgabeblack@google.comDEFN_ASN_OP(*=)
171512853Sgabeblack@google.comDEFN_ASN_OP(/=)
171612853Sgabeblack@google.comDEFN_ASN_OP(+=)
171712853Sgabeblack@google.comDEFN_ASN_OP(-=)
171812853Sgabeblack@google.com
171912853Sgabeblack@google.com#undef DEFN_ASN_OP_T
172012853Sgabeblack@google.com#undef DEFN_ASN_OP_OTHER
172112853Sgabeblack@google.com#undef DEFN_ASN_OP
172212853Sgabeblack@google.com
172312853Sgabeblack@google.cominline sc_fxval_fast &
172412853Sgabeblack@google.comsc_fxval_fast::operator <<= (int b)
172512853Sgabeblack@google.com{
172612853Sgabeblack@google.com    SC_FXVAL_FAST_OBSERVER_READ_(*this)
172712853Sgabeblack@google.com    m_val *= scfx_pow2(b);
172812853Sgabeblack@google.com    SC_FXVAL_FAST_OBSERVER_WRITE_(*this)
172912853Sgabeblack@google.com    return *this;
173012853Sgabeblack@google.com}
173112853Sgabeblack@google.com
173212853Sgabeblack@google.cominline sc_fxval_fast &
173312853Sgabeblack@google.comsc_fxval_fast::operator >>= (int b)
173412853Sgabeblack@google.com{
173512853Sgabeblack@google.com    SC_FXVAL_FAST_OBSERVER_READ_(*this)
173612853Sgabeblack@google.com    m_val *= scfx_pow2(-b);
173712853Sgabeblack@google.com    SC_FXVAL_FAST_OBSERVER_WRITE_(*this)
173812853Sgabeblack@google.com    return *this;
173912853Sgabeblack@google.com}
174012853Sgabeblack@google.com
174112853Sgabeblack@google.com// auto-increment and auto-decrement
174212853Sgabeblack@google.cominline const sc_fxval_fast
174312853Sgabeblack@google.comsc_fxval_fast::operator ++ (int)
174412853Sgabeblack@google.com{
174512853Sgabeblack@google.com    SC_FXVAL_FAST_OBSERVER_READ_(*this)
174612853Sgabeblack@google.com    SC_FXVAL_FAST_OBSERVER_READ_(*this)
174712853Sgabeblack@google.com    double c = m_val;
174812853Sgabeblack@google.com    m_val = m_val + 1;
174912853Sgabeblack@google.com    SC_FXVAL_FAST_OBSERVER_WRITE_(*this)
175012853Sgabeblack@google.com    return sc_fxval_fast(c);
175112853Sgabeblack@google.com}
175212853Sgabeblack@google.com
175312853Sgabeblack@google.cominline const sc_fxval_fast
175412853Sgabeblack@google.comsc_fxval_fast::operator -- (int)
175512853Sgabeblack@google.com{
175612853Sgabeblack@google.com    SC_FXVAL_FAST_OBSERVER_READ_(*this)
175712853Sgabeblack@google.com    SC_FXVAL_FAST_OBSERVER_READ_(*this)
175812853Sgabeblack@google.com    double c = m_val;
175912853Sgabeblack@google.com    m_val = m_val - 1;
176012853Sgabeblack@google.com    SC_FXVAL_FAST_OBSERVER_WRITE_(*this)
176112853Sgabeblack@google.com    return sc_fxval_fast(c);
176212853Sgabeblack@google.com}
176312853Sgabeblack@google.com
176412853Sgabeblack@google.cominline sc_fxval_fast &
176512853Sgabeblack@google.comsc_fxval_fast::operator ++ ()
176612853Sgabeblack@google.com{
176712853Sgabeblack@google.com    SC_FXVAL_FAST_OBSERVER_READ_(*this)
176812853Sgabeblack@google.com    m_val = m_val + 1;
176912853Sgabeblack@google.com    SC_FXVAL_FAST_OBSERVER_WRITE_(*this)
177012853Sgabeblack@google.com    return *this;
177112853Sgabeblack@google.com}
177212853Sgabeblack@google.com
177312853Sgabeblack@google.cominline sc_fxval_fast &
177412853Sgabeblack@google.comsc_fxval_fast::operator -- ()
177512853Sgabeblack@google.com{
177612853Sgabeblack@google.com    SC_FXVAL_FAST_OBSERVER_READ_(*this)
177712853Sgabeblack@google.com    m_val = m_val - 1;
177812853Sgabeblack@google.com    SC_FXVAL_FAST_OBSERVER_WRITE_(*this)
177912853Sgabeblack@google.com    return *this;
178012853Sgabeblack@google.com}
178112853Sgabeblack@google.com
178212853Sgabeblack@google.com// implicit conversion
178312853Sgabeblack@google.cominline sc_fxval_fast::operator double() const
178412853Sgabeblack@google.com{
178512853Sgabeblack@google.com    SC_FXVAL_FAST_OBSERVER_READ_(*this)
178612853Sgabeblack@google.com    return m_val;
178712853Sgabeblack@google.com}
178812853Sgabeblack@google.com
178912853Sgabeblack@google.com// explicit conversion to primitive types
179012853Sgabeblack@google.cominline short
179112853Sgabeblack@google.comsc_fxval_fast::to_short() const
179212853Sgabeblack@google.com{
179312853Sgabeblack@google.com    // SC_FXVAL_FAST_OBSERVER_READ_ in to_uint64
179412853Sgabeblack@google.com    return static_cast<short>(to_uint64());
179512853Sgabeblack@google.com}
179612853Sgabeblack@google.com
179712853Sgabeblack@google.cominline unsigned short
179812853Sgabeblack@google.comsc_fxval_fast::to_ushort() const
179912853Sgabeblack@google.com{
180012853Sgabeblack@google.com    // SC_FXVAL_FAST_OBSERVER_READ_ in to_uint64
180112853Sgabeblack@google.com    return static_cast<unsigned short>(to_uint64());
180212853Sgabeblack@google.com}
180312853Sgabeblack@google.com
180412853Sgabeblack@google.cominline int64
180512853Sgabeblack@google.comsc_fxval_fast::to_int64() const
180612853Sgabeblack@google.com{
180712853Sgabeblack@google.com    // SC_FXVAL_FAST_OBSERVER_READ_ in to_uint64
180812853Sgabeblack@google.com    return static_cast<int64>(to_uint64());
180912853Sgabeblack@google.com}
181012853Sgabeblack@google.com
181112853Sgabeblack@google.cominline int
181212853Sgabeblack@google.comsc_fxval_fast::to_int() const
181312853Sgabeblack@google.com{
181412853Sgabeblack@google.com    // SC_FXVAL_FAST_OBSERVER_READ_ in to_uint64
181512853Sgabeblack@google.com    return static_cast<int>(to_uint64());
181612853Sgabeblack@google.com}
181712853Sgabeblack@google.com
181812853Sgabeblack@google.cominline unsigned int
181912853Sgabeblack@google.comsc_fxval_fast::to_uint() const
182012853Sgabeblack@google.com{
182112853Sgabeblack@google.com    // SC_FXVAL_FAST_OBSERVER_READ_ in to_uint64
182212853Sgabeblack@google.com    return static_cast<unsigned int>(to_uint64());
182312853Sgabeblack@google.com}
182412853Sgabeblack@google.com
182512853Sgabeblack@google.cominline uint64
182612853Sgabeblack@google.comsc_fxval_fast::to_uint64() const
182712853Sgabeblack@google.com{
182812853Sgabeblack@google.com    // SC_FXVAL_FAST_OBSERVER_READ_ in is_normal
182912853Sgabeblack@google.com    if (!is_normal()) {
183012853Sgabeblack@google.com        return 0;
183112853Sgabeblack@google.com    }
183212853Sgabeblack@google.com
183312853Sgabeblack@google.com    int exponent;
183412853Sgabeblack@google.com    double mantissa_dbl = frexp(m_val, &exponent);
183512853Sgabeblack@google.com
183612853Sgabeblack@google.com    uint64 mantissa = static_cast<uint64>(
183712853Sgabeblack@google.com        fabs(mantissa_dbl) * (UINT64_ONE << 53));
183812853Sgabeblack@google.com    exponent -= 53;
183912853Sgabeblack@google.com
184012853Sgabeblack@google.com    if (!(-64 < exponent && exponent < 64)) {
184112853Sgabeblack@google.com        return 0;
184212853Sgabeblack@google.com    }
184312853Sgabeblack@google.com
184412853Sgabeblack@google.com    mantissa = exponent >= 0 ? mantissa << exponent : mantissa >> -exponent;
184512853Sgabeblack@google.com    return mantissa_dbl >= 0 ? mantissa : -mantissa;
184612853Sgabeblack@google.com}
184712853Sgabeblack@google.com
184812853Sgabeblack@google.cominline long
184912853Sgabeblack@google.comsc_fxval_fast::to_long() const
185012853Sgabeblack@google.com{
185112853Sgabeblack@google.com    // SC_FXVAL_FAST_OBSERVER_READ_ in to_uint64
185212853Sgabeblack@google.com    return static_cast<long>(to_uint64());
185312853Sgabeblack@google.com}
185412853Sgabeblack@google.com
185512853Sgabeblack@google.cominline unsigned long
185612853Sgabeblack@google.comsc_fxval_fast::to_ulong() const
185712853Sgabeblack@google.com{
185812853Sgabeblack@google.com    // SC_FXVAL_FAST_OBSERVER_READ_ in to_uint64
185912853Sgabeblack@google.com    return static_cast<unsigned long>(to_uint64());
186012853Sgabeblack@google.com}
186112853Sgabeblack@google.com
186212853Sgabeblack@google.cominline float
186312853Sgabeblack@google.comsc_fxval_fast::to_float() const
186412853Sgabeblack@google.com{
186512853Sgabeblack@google.com    SC_FXVAL_FAST_OBSERVER_READ_(*this)
186612853Sgabeblack@google.com    return static_cast<float>(m_val);
186712853Sgabeblack@google.com}
186812853Sgabeblack@google.com
186912853Sgabeblack@google.cominline double
187012853Sgabeblack@google.comsc_fxval_fast::to_double() const
187112853Sgabeblack@google.com{
187212853Sgabeblack@google.com    SC_FXVAL_FAST_OBSERVER_READ_(*this)
187312853Sgabeblack@google.com    return m_val;
187412853Sgabeblack@google.com}
187512853Sgabeblack@google.com
187612853Sgabeblack@google.com// query value
187712853Sgabeblack@google.cominline bool
187812853Sgabeblack@google.comsc_fxval_fast::is_neg() const
187912853Sgabeblack@google.com{
188012853Sgabeblack@google.com    SC_FXVAL_FAST_OBSERVER_READ_(*this)
188112853Sgabeblack@google.com    scfx_ieee_double id(m_val);
188212853Sgabeblack@google.com    return (id.negative() != 0);
188312853Sgabeblack@google.com}
188412853Sgabeblack@google.com
188512853Sgabeblack@google.cominline bool
188612853Sgabeblack@google.comsc_fxval_fast::is_zero() const
188712853Sgabeblack@google.com{
188812853Sgabeblack@google.com    SC_FXVAL_FAST_OBSERVER_READ_(*this)
188912853Sgabeblack@google.com    scfx_ieee_double id(m_val);
189012853Sgabeblack@google.com    return id.is_zero();
189112853Sgabeblack@google.com}
189212853Sgabeblack@google.com
189312853Sgabeblack@google.cominline bool
189412853Sgabeblack@google.comsc_fxval_fast::is_nan() const
189512853Sgabeblack@google.com{
189612853Sgabeblack@google.com    SC_FXVAL_FAST_OBSERVER_READ_(*this)
189712853Sgabeblack@google.com    scfx_ieee_double id(m_val);
189812853Sgabeblack@google.com    return id.is_nan();
189912853Sgabeblack@google.com}
190012853Sgabeblack@google.com
190112853Sgabeblack@google.cominline bool
190212853Sgabeblack@google.comsc_fxval_fast::is_inf() const
190312853Sgabeblack@google.com{
190412853Sgabeblack@google.com    SC_FXVAL_FAST_OBSERVER_READ_(*this)
190512853Sgabeblack@google.com    scfx_ieee_double id(m_val);
190612853Sgabeblack@google.com    return id.is_inf();
190712853Sgabeblack@google.com}
190812853Sgabeblack@google.com
190912853Sgabeblack@google.cominline bool
191012853Sgabeblack@google.comsc_fxval_fast::is_normal() const
191112853Sgabeblack@google.com{
191212853Sgabeblack@google.com    SC_FXVAL_FAST_OBSERVER_READ_(*this)
191312853Sgabeblack@google.com    scfx_ieee_double id(m_val);
191412853Sgabeblack@google.com    return (id.is_normal() || id.is_subnormal() || id.is_zero());
191512853Sgabeblack@google.com}
191612853Sgabeblack@google.com
191712853Sgabeblack@google.cominline bool
191812853Sgabeblack@google.comsc_fxval_fast::rounding_flag() const
191912853Sgabeblack@google.com{
192012853Sgabeblack@google.com    // does not apply to sc_fxval_fast; included for API compatibility
192112853Sgabeblack@google.com    return false;
192212853Sgabeblack@google.com}
192312853Sgabeblack@google.com
192412853Sgabeblack@google.cominline ::std::ostream &
192512853Sgabeblack@google.comoperator << (::std::ostream &os, const sc_fxval_fast &a)
192612853Sgabeblack@google.com{
192712853Sgabeblack@google.com    a.print(os);
192812853Sgabeblack@google.com    return os;
192912853Sgabeblack@google.com}
193012853Sgabeblack@google.com
193112853Sgabeblack@google.cominline ::std::istream &
193212853Sgabeblack@google.comoperator >> (::std::istream &is, sc_fxval_fast &a)
193312853Sgabeblack@google.com{
193412853Sgabeblack@google.com    a.scan(is);
193512853Sgabeblack@google.com    return is;
193612853Sgabeblack@google.com}
193712853Sgabeblack@google.com
193812853Sgabeblack@google.com} // namespace sc_dt
193912853Sgabeblack@google.com
194012853Sgabeblack@google.com#undef SCFX_EXPLICIT_
194112853Sgabeblack@google.com#undef SCFX_EXPLICIT_OTHER_
194212853Sgabeblack@google.com
194312853Sgabeblack@google.com#endif // __SYSTEMC_EXT_DT_FX_SC_FXVAL_HH__
1944