sc_fxnum.cc revision 12854
112854Sgabeblack@google.com/*****************************************************************************
212854Sgabeblack@google.com
312854Sgabeblack@google.com  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
412854Sgabeblack@google.com  more contributor license agreements.  See the NOTICE file distributed
512854Sgabeblack@google.com  with this work for additional information regarding copyright ownership.
612854Sgabeblack@google.com  Accellera licenses this file to you under the Apache License, Version 2.0
712854Sgabeblack@google.com  (the "License"); you may not use this file except in compliance with the
812854Sgabeblack@google.com  License.  You may obtain a copy of the License at
912854Sgabeblack@google.com
1012854Sgabeblack@google.com    http://www.apache.org/licenses/LICENSE-2.0
1112854Sgabeblack@google.com
1212854Sgabeblack@google.com  Unless required by applicable law or agreed to in writing, software
1312854Sgabeblack@google.com  distributed under the License is distributed on an "AS IS" BASIS,
1412854Sgabeblack@google.com  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
1512854Sgabeblack@google.com  implied.  See the License for the specific language governing
1612854Sgabeblack@google.com  permissions and limitations under the License.
1712854Sgabeblack@google.com
1812854Sgabeblack@google.com *****************************************************************************/
1912854Sgabeblack@google.com
2012854Sgabeblack@google.com/*****************************************************************************
2112854Sgabeblack@google.com
2212854Sgabeblack@google.com  sc_fxnum.cpp -
2312854Sgabeblack@google.com
2412854Sgabeblack@google.com  Original Author: Martin Janssen, Synopsys, Inc.
2512854Sgabeblack@google.com
2612854Sgabeblack@google.com *****************************************************************************/
2712854Sgabeblack@google.com
2812854Sgabeblack@google.com/*****************************************************************************
2912854Sgabeblack@google.com
3012854Sgabeblack@google.com  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
3112854Sgabeblack@google.com  changes you are making here.
3212854Sgabeblack@google.com
3312854Sgabeblack@google.com      Name, Affiliation, Date:
3412854Sgabeblack@google.com  Description of Modification:
3512854Sgabeblack@google.com
3612854Sgabeblack@google.com *****************************************************************************/
3712854Sgabeblack@google.com
3812854Sgabeblack@google.com
3912854Sgabeblack@google.com// $Log: sc_fxnum.cpp,v $
4012854Sgabeblack@google.com// Revision 1.3  2011/01/19 18:57:40  acg
4112854Sgabeblack@google.com//  Andy Goodrich: changes for IEEE_1666_2011.
4212854Sgabeblack@google.com//
4312854Sgabeblack@google.com// Revision 1.2  2010/12/07 20:09:08  acg
4412854Sgabeblack@google.com// Andy Goodrich: Philipp Hartmann's constructor disambiguation fix
4512854Sgabeblack@google.com//
4612854Sgabeblack@google.com// Revision 1.1.1.1  2006/12/15 20:20:04  acg
4712854Sgabeblack@google.com// SystemC 2.3
4812854Sgabeblack@google.com//
4912854Sgabeblack@google.com// Revision 1.3  2006/01/13 18:53:57  acg
5012854Sgabeblack@google.com// Andy Goodrich: added $Log command so that CVS comments are reproduced in
5112854Sgabeblack@google.com// the source.
5212854Sgabeblack@google.com//
5312854Sgabeblack@google.com
5412854Sgabeblack@google.com#include <cmath>
5512854Sgabeblack@google.com
5612854Sgabeblack@google.com#include "systemc/ext/dt/fx/sc_fxnum.hh"
5712854Sgabeblack@google.com
5812854Sgabeblack@google.comnamespace sc_dt
5912854Sgabeblack@google.com{
6012854Sgabeblack@google.com
6112854Sgabeblack@google.com// ----------------------------------------------------------------------------
6212854Sgabeblack@google.com//  CLASS : sc_fxnum_bitref
6312854Sgabeblack@google.com//
6412854Sgabeblack@google.com//  Proxy class for bit-selection in class sc_fxnum, behaves like sc_bit.
6512854Sgabeblack@google.com// ----------------------------------------------------------------------------
6612854Sgabeblack@google.com
6712854Sgabeblack@google.combool sc_fxnum_bitref::get() const { return m_num.get_bit(m_idx); }
6812854Sgabeblack@google.comvoid sc_fxnum_bitref::set(bool high) { m_num.set_bit(m_idx, high); }
6912854Sgabeblack@google.com
7012854Sgabeblack@google.com// print or dump content
7112854Sgabeblack@google.comvoid sc_fxnum_bitref::print(::std::ostream &os) const { os << get(); }
7212854Sgabeblack@google.com
7312854Sgabeblack@google.comvoid
7412854Sgabeblack@google.comsc_fxnum_bitref::scan(::std::istream &is)
7512854Sgabeblack@google.com{
7612854Sgabeblack@google.com    bool b;
7712854Sgabeblack@google.com    is >> b;
7812854Sgabeblack@google.com    *this = b;
7912854Sgabeblack@google.com}
8012854Sgabeblack@google.com
8112854Sgabeblack@google.comvoid
8212854Sgabeblack@google.comsc_fxnum_bitref::dump(::std::ostream &os) const
8312854Sgabeblack@google.com{
8412854Sgabeblack@google.com    os << "sc_fxnum_bitref" << ::std::endl;
8512854Sgabeblack@google.com    os << "(" << ::std::endl;
8612854Sgabeblack@google.com    os << "num = ";
8712854Sgabeblack@google.com    m_num.dump(os);
8812854Sgabeblack@google.com    os << "idx = " << m_idx << ::std::endl;
8912854Sgabeblack@google.com    os << ")" << ::std::endl;
9012854Sgabeblack@google.com}
9112854Sgabeblack@google.com
9212854Sgabeblack@google.com
9312854Sgabeblack@google.com// ----------------------------------------------------------------------------
9412854Sgabeblack@google.com//  CLASS : sc_fxnum_fast_bitref
9512854Sgabeblack@google.com//
9612854Sgabeblack@google.com//  Proxy class for bit-selection in class sc_fxnum_fast, behaves like sc_bit.
9712854Sgabeblack@google.com// ----------------------------------------------------------------------------
9812854Sgabeblack@google.com
9912854Sgabeblack@google.combool sc_fxnum_fast_bitref::get() const { return m_num.get_bit(m_idx); }
10012854Sgabeblack@google.comvoid sc_fxnum_fast_bitref::set(bool high) { m_num.set_bit(m_idx, high); }
10112854Sgabeblack@google.com
10212854Sgabeblack@google.com// print or dump content
10312854Sgabeblack@google.comvoid sc_fxnum_fast_bitref::print(::std::ostream &os) const { os << get(); }
10412854Sgabeblack@google.com
10512854Sgabeblack@google.comvoid
10612854Sgabeblack@google.comsc_fxnum_fast_bitref::scan(::std::istream &is)
10712854Sgabeblack@google.com{
10812854Sgabeblack@google.com    bool b;
10912854Sgabeblack@google.com    is >> b;
11012854Sgabeblack@google.com    *this = b;
11112854Sgabeblack@google.com}
11212854Sgabeblack@google.com
11312854Sgabeblack@google.comvoid
11412854Sgabeblack@google.comsc_fxnum_fast_bitref::dump(::std::ostream &os) const
11512854Sgabeblack@google.com{
11612854Sgabeblack@google.com    os << "sc_fxnum_fast_bitref" << ::std::endl;
11712854Sgabeblack@google.com    os << "(" << ::std::endl;
11812854Sgabeblack@google.com    os << "num = ";
11912854Sgabeblack@google.com    m_num.dump(os);
12012854Sgabeblack@google.com    os << "idx = " << m_idx << ::std::endl;
12112854Sgabeblack@google.com    os << ")" << ::std::endl;
12212854Sgabeblack@google.com}
12312854Sgabeblack@google.com
12412854Sgabeblack@google.com// ----------------------------------------------------------------------------
12512854Sgabeblack@google.com//  CLASS : sc_fxnum_subref
12612854Sgabeblack@google.com//
12712854Sgabeblack@google.com//  Proxy class for part-selection in class sc_fxnum,
12812854Sgabeblack@google.com//  behaves like sc_bv_base.
12912854Sgabeblack@google.com// ----------------------------------------------------------------------------
13012854Sgabeblack@google.com
13112854Sgabeblack@google.combool
13212854Sgabeblack@google.comsc_fxnum_subref::get() const
13312854Sgabeblack@google.com{
13412854Sgabeblack@google.com    return m_num.get_slice(m_from, m_to, m_bv);
13512854Sgabeblack@google.com}
13612854Sgabeblack@google.com
13712854Sgabeblack@google.combool
13812854Sgabeblack@google.comsc_fxnum_subref::set()
13912854Sgabeblack@google.com{
14012854Sgabeblack@google.com    return m_num.set_slice(m_from, m_to, m_bv);
14112854Sgabeblack@google.com}
14212854Sgabeblack@google.com
14312854Sgabeblack@google.com// print or dump content
14412854Sgabeblack@google.comvoid
14512854Sgabeblack@google.comsc_fxnum_subref::print(::std::ostream &os) const
14612854Sgabeblack@google.com{
14712854Sgabeblack@google.com    get();
14812854Sgabeblack@google.com    m_bv.print(os);
14912854Sgabeblack@google.com}
15012854Sgabeblack@google.com
15112854Sgabeblack@google.comvoid
15212854Sgabeblack@google.comsc_fxnum_subref::scan(::std::istream &is)
15312854Sgabeblack@google.com{
15412854Sgabeblack@google.com    m_bv.scan(is);
15512854Sgabeblack@google.com    set();
15612854Sgabeblack@google.com}
15712854Sgabeblack@google.com
15812854Sgabeblack@google.comvoid
15912854Sgabeblack@google.comsc_fxnum_subref::dump(::std::ostream &os) const
16012854Sgabeblack@google.com{
16112854Sgabeblack@google.com    os << "sc_fxnum_subref" << ::std::endl;
16212854Sgabeblack@google.com    os << "(" << ::std::endl;
16312854Sgabeblack@google.com    os << "num  = ";
16412854Sgabeblack@google.com    m_num.dump(os);
16512854Sgabeblack@google.com    os << "from = " << m_from << ::std::endl;
16612854Sgabeblack@google.com    os << "to   = " << m_to << ::std::endl;
16712854Sgabeblack@google.com    os << ")" << ::std::endl;
16812854Sgabeblack@google.com}
16912854Sgabeblack@google.com
17012854Sgabeblack@google.com
17112854Sgabeblack@google.com// ----------------------------------------------------------------------------
17212854Sgabeblack@google.com//  CLASS : sc_fxnum_fast_subref
17312854Sgabeblack@google.com//
17412854Sgabeblack@google.com//  Proxy class for part-selection in class sc_fxnum_fast,
17512854Sgabeblack@google.com//  behaves like sc_bv_base.
17612854Sgabeblack@google.com// ----------------------------------------------------------------------------
17712854Sgabeblack@google.com
17812854Sgabeblack@google.combool
17912854Sgabeblack@google.comsc_fxnum_fast_subref::get() const
18012854Sgabeblack@google.com{
18112854Sgabeblack@google.com    return m_num.get_slice(m_from, m_to, m_bv);
18212854Sgabeblack@google.com}
18312854Sgabeblack@google.com
18412854Sgabeblack@google.combool
18512854Sgabeblack@google.comsc_fxnum_fast_subref::set()
18612854Sgabeblack@google.com{
18712854Sgabeblack@google.com    return m_num.set_slice(m_from, m_to, m_bv);
18812854Sgabeblack@google.com}
18912854Sgabeblack@google.com
19012854Sgabeblack@google.com// print or dump content
19112854Sgabeblack@google.comvoid
19212854Sgabeblack@google.comsc_fxnum_fast_subref::print(::std::ostream &os) const
19312854Sgabeblack@google.com{
19412854Sgabeblack@google.com    get();
19512854Sgabeblack@google.com    m_bv.print(os);
19612854Sgabeblack@google.com}
19712854Sgabeblack@google.com
19812854Sgabeblack@google.comvoid
19912854Sgabeblack@google.comsc_fxnum_fast_subref::scan(::std::istream &is)
20012854Sgabeblack@google.com{
20112854Sgabeblack@google.com    m_bv.scan(is);
20212854Sgabeblack@google.com    set();
20312854Sgabeblack@google.com}
20412854Sgabeblack@google.com
20512854Sgabeblack@google.comvoid
20612854Sgabeblack@google.comsc_fxnum_fast_subref::dump(::std::ostream &os) const
20712854Sgabeblack@google.com{
20812854Sgabeblack@google.com    os << "sc_fxnum_fast_subref" << ::std::endl;
20912854Sgabeblack@google.com    os << "(" << ::std::endl;
21012854Sgabeblack@google.com    os << "num  = ";
21112854Sgabeblack@google.com    m_num.dump(os);
21212854Sgabeblack@google.com    os << "from = " << m_from << ::std::endl;
21312854Sgabeblack@google.com    os << "to   = " << m_to << ::std::endl;
21412854Sgabeblack@google.com    os << ")" << ::std::endl;
21512854Sgabeblack@google.com}
21612854Sgabeblack@google.com
21712854Sgabeblack@google.com
21812854Sgabeblack@google.com// ----------------------------------------------------------------------------
21912854Sgabeblack@google.com//  CLASS : sc_fxnum
22012854Sgabeblack@google.com//
22112854Sgabeblack@google.com//  Base class for the fixed-point types; arbitrary precision.
22212854Sgabeblack@google.com// ----------------------------------------------------------------------------
22312854Sgabeblack@google.com
22412854Sgabeblack@google.com// explicit conversion to character string
22512854Sgabeblack@google.com
22612854Sgabeblack@google.comconst std::string
22712854Sgabeblack@google.comsc_fxnum::to_string() const
22812854Sgabeblack@google.com{
22912854Sgabeblack@google.com    return std::string(m_rep->to_string(SC_DEC, -1, SC_F, &m_params));
23012854Sgabeblack@google.com}
23112854Sgabeblack@google.com
23212854Sgabeblack@google.comconst std::string
23312854Sgabeblack@google.comsc_fxnum::to_string(sc_numrep numrep) const
23412854Sgabeblack@google.com{
23512854Sgabeblack@google.com    return std::string(m_rep->to_string(numrep, -1, SC_F, &m_params));
23612854Sgabeblack@google.com}
23712854Sgabeblack@google.com
23812854Sgabeblack@google.comconst std::string
23912854Sgabeblack@google.comsc_fxnum::to_string(sc_numrep numrep, bool w_prefix) const
24012854Sgabeblack@google.com{
24112854Sgabeblack@google.com    return std::string(m_rep->to_string(numrep, (w_prefix ? 1 : 0),
24212854Sgabeblack@google.com                                        SC_F, &m_params));
24312854Sgabeblack@google.com}
24412854Sgabeblack@google.com
24512854Sgabeblack@google.comconst std::string
24612854Sgabeblack@google.comsc_fxnum::to_string(sc_fmt fmt) const
24712854Sgabeblack@google.com{
24812854Sgabeblack@google.com    return std::string(m_rep->to_string(SC_DEC, -1, fmt, &m_params));
24912854Sgabeblack@google.com}
25012854Sgabeblack@google.com
25112854Sgabeblack@google.comconst std::string
25212854Sgabeblack@google.comsc_fxnum::to_string(sc_numrep numrep, sc_fmt fmt) const
25312854Sgabeblack@google.com{
25412854Sgabeblack@google.com    return std::string(m_rep->to_string(numrep, -1, fmt, &m_params));
25512854Sgabeblack@google.com}
25612854Sgabeblack@google.com
25712854Sgabeblack@google.comconst std::string
25812854Sgabeblack@google.comsc_fxnum::to_string(sc_numrep numrep, bool w_prefix, sc_fmt fmt) const
25912854Sgabeblack@google.com{
26012854Sgabeblack@google.com    return std::string(m_rep->to_string(numrep, (w_prefix ? 1 : 0),
26112854Sgabeblack@google.com                                        fmt, &m_params));
26212854Sgabeblack@google.com}
26312854Sgabeblack@google.com
26412854Sgabeblack@google.com
26512854Sgabeblack@google.comconst std::string
26612854Sgabeblack@google.comsc_fxnum::to_dec() const
26712854Sgabeblack@google.com{
26812854Sgabeblack@google.com    return std::string(m_rep->to_string(SC_DEC, -1, SC_F, &m_params));
26912854Sgabeblack@google.com}
27012854Sgabeblack@google.com
27112854Sgabeblack@google.comconst std::string
27212854Sgabeblack@google.comsc_fxnum::to_bin() const
27312854Sgabeblack@google.com{
27412854Sgabeblack@google.com    return std::string(m_rep->to_string(SC_BIN, -1, SC_F, &m_params));
27512854Sgabeblack@google.com}
27612854Sgabeblack@google.com
27712854Sgabeblack@google.comconst std::string
27812854Sgabeblack@google.comsc_fxnum::to_oct() const
27912854Sgabeblack@google.com{
28012854Sgabeblack@google.com    return std::string(m_rep->to_string(SC_OCT, -1, SC_F, &m_params));
28112854Sgabeblack@google.com}
28212854Sgabeblack@google.com
28312854Sgabeblack@google.comconst std::string
28412854Sgabeblack@google.comsc_fxnum::to_hex() const
28512854Sgabeblack@google.com{
28612854Sgabeblack@google.com    return std::string(m_rep->to_string(SC_HEX, -1, SC_F, &m_params));
28712854Sgabeblack@google.com}
28812854Sgabeblack@google.com
28912854Sgabeblack@google.com
29012854Sgabeblack@google.com// print or dump content
29112854Sgabeblack@google.comvoid
29212854Sgabeblack@google.comsc_fxnum::print(::std::ostream &os) const
29312854Sgabeblack@google.com{
29412854Sgabeblack@google.com    os << m_rep->to_string(SC_DEC, -1, SC_F, &m_params);
29512854Sgabeblack@google.com}
29612854Sgabeblack@google.com
29712854Sgabeblack@google.comvoid
29812854Sgabeblack@google.comsc_fxnum::scan(::std::istream &is)
29912854Sgabeblack@google.com{
30012854Sgabeblack@google.com    std::string s;
30112854Sgabeblack@google.com    is >> s;
30212854Sgabeblack@google.com    *this = s.c_str();
30312854Sgabeblack@google.com}
30412854Sgabeblack@google.com
30512854Sgabeblack@google.comvoid
30612854Sgabeblack@google.comsc_fxnum::dump(::std::ostream &os) const
30712854Sgabeblack@google.com{
30812854Sgabeblack@google.com    os << "sc_fxnum" << ::std::endl;
30912854Sgabeblack@google.com    os << "(" << ::std::endl;
31012854Sgabeblack@google.com    os << "rep      = ";
31112854Sgabeblack@google.com    m_rep->dump(os);
31212854Sgabeblack@google.com    os << "params   = ";
31312854Sgabeblack@google.com    m_params.dump(os);
31412854Sgabeblack@google.com    os << "q_flag   = " << m_q_flag << ::std::endl;
31512854Sgabeblack@google.com    os << "o_flag   = " << m_o_flag << ::std::endl;
31612854Sgabeblack@google.com    // TO BE COMPLETED
31712854Sgabeblack@google.com    // os << "observer = ";
31812854Sgabeblack@google.com    // if (m_observer != 0)
31912854Sgabeblack@google.com    //     m_observer->dump(os);
32012854Sgabeblack@google.com    // else
32112854Sgabeblack@google.com    //     os << "0" << ::std::endl;
32212854Sgabeblack@google.com    os << ")" << ::std::endl;
32312854Sgabeblack@google.com}
32412854Sgabeblack@google.com
32512854Sgabeblack@google.com
32612854Sgabeblack@google.comsc_fxnum_observer *
32712854Sgabeblack@google.comsc_fxnum::lock_observer() const
32812854Sgabeblack@google.com{
32912854Sgabeblack@google.com    SC_ASSERT_(m_observer != 0, "lock observer failed");
33012854Sgabeblack@google.com    sc_fxnum_observer * tmp = m_observer;
33112854Sgabeblack@google.com    m_observer = 0;
33212854Sgabeblack@google.com    return tmp;
33312854Sgabeblack@google.com}
33412854Sgabeblack@google.com
33512854Sgabeblack@google.comvoid
33612854Sgabeblack@google.comsc_fxnum::unlock_observer(sc_fxnum_observer *observer_) const
33712854Sgabeblack@google.com{
33812854Sgabeblack@google.com    SC_ASSERT_(observer_ != 0, "unlock observer failed");
33912854Sgabeblack@google.com    m_observer = observer_;
34012854Sgabeblack@google.com}
34112854Sgabeblack@google.com
34212854Sgabeblack@google.com
34312854Sgabeblack@google.com// ----------------------------------------------------------------------------
34412854Sgabeblack@google.com//  CLASS : sc_fxnum_fast
34512854Sgabeblack@google.com//
34612854Sgabeblack@google.com//  Base class for the fixed-point types; limited precision.
34712854Sgabeblack@google.com// ----------------------------------------------------------------------------
34812854Sgabeblack@google.com
34912854Sgabeblack@google.comstatic void
35012854Sgabeblack@google.comquantization(double &c, const scfx_params &params, bool &q_flag)
35112854Sgabeblack@google.com{
35212854Sgabeblack@google.com    int fwl = params.wl() - params.iwl();
35312854Sgabeblack@google.com    double scale = scfx_pow2(fwl);
35412854Sgabeblack@google.com    double val = scale * c;
35512854Sgabeblack@google.com    double int_part;
35612854Sgabeblack@google.com    double frac_part = modf(val, &int_part);
35712854Sgabeblack@google.com
35812854Sgabeblack@google.com    q_flag = (frac_part != 0.0);
35912854Sgabeblack@google.com
36012854Sgabeblack@google.com    if (q_flag) {
36112854Sgabeblack@google.com        val = int_part;
36212854Sgabeblack@google.com
36312854Sgabeblack@google.com        switch (params.q_mode()) {
36412854Sgabeblack@google.com          case SC_TRN: // truncation
36512854Sgabeblack@google.com            {
36612854Sgabeblack@google.com                if (c < 0.0)
36712854Sgabeblack@google.com                    val -= 1.0;
36812854Sgabeblack@google.com                break;
36912854Sgabeblack@google.com            }
37012854Sgabeblack@google.com          case SC_RND: // rounding to plus infinity
37112854Sgabeblack@google.com            {
37212854Sgabeblack@google.com                if (frac_part >= 0.5)
37312854Sgabeblack@google.com                    val += 1.0;
37412854Sgabeblack@google.com                else if (frac_part < -0.5)
37512854Sgabeblack@google.com                    val -= 1.0;
37612854Sgabeblack@google.com                break;
37712854Sgabeblack@google.com            }
37812854Sgabeblack@google.com          case SC_TRN_ZERO: // truncation to zero
37912854Sgabeblack@google.com            {
38012854Sgabeblack@google.com                break;
38112854Sgabeblack@google.com            }
38212854Sgabeblack@google.com          case SC_RND_INF: // rounding to infinity
38312854Sgabeblack@google.com            {
38412854Sgabeblack@google.com                if (frac_part >= 0.5)
38512854Sgabeblack@google.com                    val += 1.0;
38612854Sgabeblack@google.com                else if (frac_part <= -0.5)
38712854Sgabeblack@google.com                    val -= 1.0;
38812854Sgabeblack@google.com                break;
38912854Sgabeblack@google.com            }
39012854Sgabeblack@google.com          case SC_RND_CONV: // convergent rounding
39112854Sgabeblack@google.com            {
39212854Sgabeblack@google.com                if (frac_part > 0.5 ||
39312854Sgabeblack@google.com                    (frac_part == 0.5 && fmod(int_part, 2.0) != 0.0)) {
39412854Sgabeblack@google.com                    val += 1.0;
39512854Sgabeblack@google.com                } else if (frac_part < -0.5 ||
39612854Sgabeblack@google.com                           (frac_part == -0.5 && fmod(int_part, 2.0) != 0.0)) {
39712854Sgabeblack@google.com                    val -= 1.0;
39812854Sgabeblack@google.com                }
39912854Sgabeblack@google.com                break;
40012854Sgabeblack@google.com            }
40112854Sgabeblack@google.com          case SC_RND_ZERO: // rounding to zero
40212854Sgabeblack@google.com            {
40312854Sgabeblack@google.com                if (frac_part > 0.5)
40412854Sgabeblack@google.com                    val += 1.0;
40512854Sgabeblack@google.com                else if (frac_part < -0.5)
40612854Sgabeblack@google.com                    val -= 1.0;
40712854Sgabeblack@google.com                break;
40812854Sgabeblack@google.com            }
40912854Sgabeblack@google.com          case SC_RND_MIN_INF: // rounding to minus infinity
41012854Sgabeblack@google.com            {
41112854Sgabeblack@google.com                if (frac_part > 0.5)
41212854Sgabeblack@google.com                    val += 1.0;
41312854Sgabeblack@google.com                else if (frac_part <= -0.5)
41412854Sgabeblack@google.com                    val -= 1.0;
41512854Sgabeblack@google.com                break;
41612854Sgabeblack@google.com            }
41712854Sgabeblack@google.com          default:
41812854Sgabeblack@google.com            ;
41912854Sgabeblack@google.com        }
42012854Sgabeblack@google.com    }
42112854Sgabeblack@google.com
42212854Sgabeblack@google.com    val /= scale;
42312854Sgabeblack@google.com    c = val;
42412854Sgabeblack@google.com}
42512854Sgabeblack@google.com
42612854Sgabeblack@google.comstatic void
42712854Sgabeblack@google.comoverflow(double &c, const scfx_params &params, bool &o_flag)
42812854Sgabeblack@google.com{
42912854Sgabeblack@google.com    int iwl = params.iwl();
43012854Sgabeblack@google.com    int fwl = params.wl() - iwl;
43112854Sgabeblack@google.com    double full_circle = scfx_pow2(iwl);
43212854Sgabeblack@google.com    double resolution = scfx_pow2(-fwl);
43312854Sgabeblack@google.com    double low, high;
43412854Sgabeblack@google.com    if (params.enc() == SC_TC_) {
43512854Sgabeblack@google.com        high = full_circle / 2.0 - resolution;
43612854Sgabeblack@google.com        if (params.o_mode() == SC_SAT_SYM)
43712854Sgabeblack@google.com            low = - high;
43812854Sgabeblack@google.com        else
43912854Sgabeblack@google.com            low = - full_circle / 2.0;
44012854Sgabeblack@google.com    } else {
44112854Sgabeblack@google.com        low = 0.0;
44212854Sgabeblack@google.com        high = full_circle - resolution;
44312854Sgabeblack@google.com    }
44412854Sgabeblack@google.com    double val = c;
44512854Sgabeblack@google.com    sc_fxval_fast c2(c);
44612854Sgabeblack@google.com
44712854Sgabeblack@google.com    bool under = (val < low);
44812854Sgabeblack@google.com    bool over = (val > high);
44912854Sgabeblack@google.com
45012854Sgabeblack@google.com    o_flag = (under || over);
45112854Sgabeblack@google.com
45212854Sgabeblack@google.com    if (o_flag) {
45312854Sgabeblack@google.com        switch (params.o_mode()) {
45412854Sgabeblack@google.com          case SC_WRAP: // wrap-around
45512854Sgabeblack@google.com            {
45612854Sgabeblack@google.com                int n_bits = params.n_bits();
45712854Sgabeblack@google.com
45812854Sgabeblack@google.com                if (n_bits == 0) {
45912854Sgabeblack@google.com                    // wrap-around all 'wl' bits
46012854Sgabeblack@google.com                    val -= floor(val / full_circle) * full_circle;
46112854Sgabeblack@google.com                    if (val > high)
46212854Sgabeblack@google.com                        val -= full_circle;
46312854Sgabeblack@google.com                } else if (n_bits < params.wl()) {
46412854Sgabeblack@google.com                    double X = scfx_pow2(iwl - n_bits);
46512854Sgabeblack@google.com
46612854Sgabeblack@google.com                    // wrap-around least significant 'wl - n_bits' bits
46712854Sgabeblack@google.com                    val -= floor(val / X) * X;
46812854Sgabeblack@google.com                    if (val > (X - resolution))
46912854Sgabeblack@google.com                        val -= X;
47012854Sgabeblack@google.com
47112854Sgabeblack@google.com                    // saturate most significant 'n_bits' bits
47212854Sgabeblack@google.com                    if (under) {
47312854Sgabeblack@google.com                        val += low;
47412854Sgabeblack@google.com                    } else {
47512854Sgabeblack@google.com                        if (params.enc() == SC_TC_)
47612854Sgabeblack@google.com                            val += full_circle / 2.0 - X;
47712854Sgabeblack@google.com                        else
47812854Sgabeblack@google.com                            val += full_circle - X;
47912854Sgabeblack@google.com                    }
48012854Sgabeblack@google.com                } else {
48112854Sgabeblack@google.com                    // saturate all 'wl' bits
48212854Sgabeblack@google.com                    if (under)
48312854Sgabeblack@google.com                        val = low;
48412854Sgabeblack@google.com                    else
48512854Sgabeblack@google.com                        val = high;
48612854Sgabeblack@google.com                }
48712854Sgabeblack@google.com                break;
48812854Sgabeblack@google.com            }
48912854Sgabeblack@google.com          case SC_SAT: // saturation
49012854Sgabeblack@google.com          case SC_SAT_SYM: // symmetrical saturation
49112854Sgabeblack@google.com            {
49212854Sgabeblack@google.com                if (under)
49312854Sgabeblack@google.com                    val = low;
49412854Sgabeblack@google.com                else
49512854Sgabeblack@google.com                    val = high;
49612854Sgabeblack@google.com                break;
49712854Sgabeblack@google.com            }
49812854Sgabeblack@google.com          case SC_SAT_ZERO: // saturation to zero
49912854Sgabeblack@google.com            {
50012854Sgabeblack@google.com                val = 0.0;
50112854Sgabeblack@google.com                break;
50212854Sgabeblack@google.com            }
50312854Sgabeblack@google.com          case SC_WRAP_SM: // sign magnitude wrap-around
50412854Sgabeblack@google.com            {
50512854Sgabeblack@google.com                SC_ERROR_IF_(params.enc() == SC_US_,
50612854Sgabeblack@google.com                             "SC_WRAP_SM not defined for unsigned numbers");
50712854Sgabeblack@google.com
50812854Sgabeblack@google.com                int n_bits = params.n_bits();
50912854Sgabeblack@google.com
51012854Sgabeblack@google.com                if (n_bits == 0) {
51112854Sgabeblack@google.com                    // invert conditionally
51212854Sgabeblack@google.com                    if (c2.get_bit(iwl) != c2.get_bit(iwl - 1))
51312854Sgabeblack@google.com                        val = -val - resolution;
51412854Sgabeblack@google.com
51512854Sgabeblack@google.com                    // wrap-around all 'wl' bits
51612854Sgabeblack@google.com                    val -= floor(val / full_circle) * full_circle;
51712854Sgabeblack@google.com                    if (val > high)
51812854Sgabeblack@google.com                        val -= full_circle;
51912854Sgabeblack@google.com                } else if (n_bits == 1) {
52012854Sgabeblack@google.com                    // invert conditionally
52112854Sgabeblack@google.com                    if (c2.is_neg() != c2.get_bit(iwl - 1))
52212854Sgabeblack@google.com                        val = -val - resolution;
52312854Sgabeblack@google.com
52412854Sgabeblack@google.com                    // wrap-around all 'wl' bits
52512854Sgabeblack@google.com                    val -= floor(val / full_circle) * full_circle;
52612854Sgabeblack@google.com                    if (val > high)
52712854Sgabeblack@google.com                        val -= full_circle;
52812854Sgabeblack@google.com                } else if (n_bits < params.wl()) {
52912854Sgabeblack@google.com                    // invert conditionally
53012854Sgabeblack@google.com                    if (c2.is_neg() == c2.get_bit(iwl - n_bits))
53112854Sgabeblack@google.com                        val = -val - resolution;
53212854Sgabeblack@google.com
53312854Sgabeblack@google.com                    double X = scfx_pow2(iwl - n_bits);
53412854Sgabeblack@google.com
53512854Sgabeblack@google.com                    // wrap-around least significant 'wl - n_bits' bits
53612854Sgabeblack@google.com                    val -= floor(val / X) * X;
53712854Sgabeblack@google.com                    if (val > (X - resolution))
53812854Sgabeblack@google.com                        val -= X;
53912854Sgabeblack@google.com
54012854Sgabeblack@google.com                    // saturate most significant 'n_bits' bits
54112854Sgabeblack@google.com                    if (under)
54212854Sgabeblack@google.com                        val += low;
54312854Sgabeblack@google.com                    else
54412854Sgabeblack@google.com                        val += full_circle / 2.0 - X;
54512854Sgabeblack@google.com                } else {
54612854Sgabeblack@google.com                    // saturate all 'wl' bits
54712854Sgabeblack@google.com                    if (under)
54812854Sgabeblack@google.com                        val = low;
54912854Sgabeblack@google.com                    else
55012854Sgabeblack@google.com                        val = high;
55112854Sgabeblack@google.com                }
55212854Sgabeblack@google.com                break;
55312854Sgabeblack@google.com            }
55412854Sgabeblack@google.com            default:
55512854Sgabeblack@google.com                ;
55612854Sgabeblack@google.com        }
55712854Sgabeblack@google.com
55812854Sgabeblack@google.com        c = val;
55912854Sgabeblack@google.com    }
56012854Sgabeblack@google.com}
56112854Sgabeblack@google.com
56212854Sgabeblack@google.com
56312854Sgabeblack@google.comvoid
56412854Sgabeblack@google.comsc_fxnum_fast::cast()
56512854Sgabeblack@google.com{
56612854Sgabeblack@google.com    scfx_ieee_double id(m_val);
56712854Sgabeblack@google.com    SC_ERROR_IF_(id.is_nan() || id.is_inf(), "invalid fixed-point value");
56812854Sgabeblack@google.com
56912854Sgabeblack@google.com    if (m_params.cast_switch() == SC_ON) {
57012854Sgabeblack@google.com        m_q_flag = false;
57112854Sgabeblack@google.com        m_o_flag = false;
57212854Sgabeblack@google.com
57312854Sgabeblack@google.com        // check for special cases
57412854Sgabeblack@google.com
57512854Sgabeblack@google.com        if (id.is_zero()) {
57612854Sgabeblack@google.com            if (id.negative() != 0)
57712854Sgabeblack@google.com                m_val = -m_val;
57812854Sgabeblack@google.com            return;
57912854Sgabeblack@google.com        }
58012854Sgabeblack@google.com
58112854Sgabeblack@google.com        // perform casting
58212854Sgabeblack@google.com        sc_dt::quantization(m_val, m_params, m_q_flag);
58312854Sgabeblack@google.com        sc_dt::overflow(m_val, m_params, m_o_flag);
58412854Sgabeblack@google.com
58512854Sgabeblack@google.com        // check for special case: -0
58612854Sgabeblack@google.com        id = m_val;
58712854Sgabeblack@google.com        if (id.is_zero() && id.negative() != 0) {
58812854Sgabeblack@google.com            m_val = -m_val;
58912854Sgabeblack@google.com        }
59012854Sgabeblack@google.com
59112854Sgabeblack@google.com        // check for special case: NaN of Inf
59212854Sgabeblack@google.com        if (id.is_nan() || id.is_inf()) {
59312854Sgabeblack@google.com            m_val = 0.0;
59412854Sgabeblack@google.com        }
59512854Sgabeblack@google.com    }
59612854Sgabeblack@google.com}
59712854Sgabeblack@google.com
59812854Sgabeblack@google.com
59912854Sgabeblack@google.com// defined in sc_fxval.cpp;
60012854Sgabeblack@google.comextern const char* to_string(const scfx_ieee_double &, sc_numrep, int, sc_fmt,
60112854Sgabeblack@google.com                             const scfx_params * =0);
60212854Sgabeblack@google.com
60312854Sgabeblack@google.com
60412854Sgabeblack@google.com// explicit conversion to character string
60512854Sgabeblack@google.com
60612854Sgabeblack@google.comconst std::string
60712854Sgabeblack@google.comsc_fxnum_fast::to_string() const
60812854Sgabeblack@google.com{
60912854Sgabeblack@google.com    return std::string(sc_dt::to_string(m_val, SC_DEC, -1, SC_F, &m_params));
61012854Sgabeblack@google.com}
61112854Sgabeblack@google.com
61212854Sgabeblack@google.comconst std::string
61312854Sgabeblack@google.comsc_fxnum_fast::to_string(sc_numrep numrep) const
61412854Sgabeblack@google.com{
61512854Sgabeblack@google.com    return std::string(sc_dt::to_string(m_val, numrep, -1, SC_F, &m_params));
61612854Sgabeblack@google.com}
61712854Sgabeblack@google.com
61812854Sgabeblack@google.comconst std::string
61912854Sgabeblack@google.comsc_fxnum_fast::to_string(sc_numrep numrep, bool w_prefix) const
62012854Sgabeblack@google.com{
62112854Sgabeblack@google.com    return std::string(sc_dt::to_string(m_val, numrep, (w_prefix ? 1 : 0),
62212854Sgabeblack@google.com                                        SC_F, &m_params));
62312854Sgabeblack@google.com}
62412854Sgabeblack@google.com
62512854Sgabeblack@google.comconst std::string
62612854Sgabeblack@google.comsc_fxnum_fast::to_string(sc_fmt fmt) const
62712854Sgabeblack@google.com{
62812854Sgabeblack@google.com    return std::string(sc_dt::to_string(m_val, SC_DEC, -1, fmt, &m_params));
62912854Sgabeblack@google.com}
63012854Sgabeblack@google.com
63112854Sgabeblack@google.comconst std::string
63212854Sgabeblack@google.comsc_fxnum_fast::to_string(sc_numrep numrep, sc_fmt fmt) const
63312854Sgabeblack@google.com{
63412854Sgabeblack@google.com    return std::string(sc_dt::to_string(m_val, numrep, -1, fmt, &m_params));
63512854Sgabeblack@google.com}
63612854Sgabeblack@google.com
63712854Sgabeblack@google.comconst std::string
63812854Sgabeblack@google.comsc_fxnum_fast::to_string(sc_numrep numrep, bool w_prefix, sc_fmt fmt) const
63912854Sgabeblack@google.com{
64012854Sgabeblack@google.com    return std::string(sc_dt::to_string(m_val, numrep, (w_prefix ? 1 : 0),
64112854Sgabeblack@google.com                                        fmt, &m_params));
64212854Sgabeblack@google.com}
64312854Sgabeblack@google.com
64412854Sgabeblack@google.com
64512854Sgabeblack@google.comconst std::string
64612854Sgabeblack@google.comsc_fxnum_fast::to_dec() const
64712854Sgabeblack@google.com{
64812854Sgabeblack@google.com    return std::string(sc_dt::to_string(m_val, SC_DEC, -1, SC_F, &m_params));
64912854Sgabeblack@google.com}
65012854Sgabeblack@google.com
65112854Sgabeblack@google.comconst std::string
65212854Sgabeblack@google.comsc_fxnum_fast::to_bin() const
65312854Sgabeblack@google.com{
65412854Sgabeblack@google.com    return std::string(sc_dt::to_string(m_val, SC_BIN, -1, SC_F, &m_params));
65512854Sgabeblack@google.com}
65612854Sgabeblack@google.com
65712854Sgabeblack@google.comconst std::string
65812854Sgabeblack@google.comsc_fxnum_fast::to_oct() const
65912854Sgabeblack@google.com{
66012854Sgabeblack@google.com    return std::string(sc_dt::to_string(m_val, SC_OCT, -1, SC_F, &m_params));
66112854Sgabeblack@google.com}
66212854Sgabeblack@google.com
66312854Sgabeblack@google.comconst std::string
66412854Sgabeblack@google.comsc_fxnum_fast::to_hex() const
66512854Sgabeblack@google.com{
66612854Sgabeblack@google.com    return std::string(sc_dt::to_string(m_val, SC_HEX, -1, SC_F, &m_params));
66712854Sgabeblack@google.com}
66812854Sgabeblack@google.com
66912854Sgabeblack@google.com// print or dump content
67012854Sgabeblack@google.comvoid
67112854Sgabeblack@google.comsc_fxnum_fast::print(::std::ostream &os) const
67212854Sgabeblack@google.com{
67312854Sgabeblack@google.com    os << sc_dt::to_string(m_val, SC_DEC, -1, SC_F, &m_params);
67412854Sgabeblack@google.com}
67512854Sgabeblack@google.com
67612854Sgabeblack@google.comvoid
67712854Sgabeblack@google.comsc_fxnum_fast::scan(::std::istream &is)
67812854Sgabeblack@google.com{
67912854Sgabeblack@google.com    std::string s;
68012854Sgabeblack@google.com    is >> s;
68112854Sgabeblack@google.com    *this = s.c_str();
68212854Sgabeblack@google.com}
68312854Sgabeblack@google.com
68412854Sgabeblack@google.comvoid
68512854Sgabeblack@google.comsc_fxnum_fast::dump(::std::ostream &os) const
68612854Sgabeblack@google.com{
68712854Sgabeblack@google.com    os << "sc_fxnum_fast" << ::std::endl;
68812854Sgabeblack@google.com    os << "(" << ::std::endl;
68912854Sgabeblack@google.com    os << "val      = " << m_val << ::std::endl;
69012854Sgabeblack@google.com    os << "params   = ";
69112854Sgabeblack@google.com    m_params.dump(os);
69212854Sgabeblack@google.com    os << "q_flag   = " << m_q_flag << ::std::endl;
69312854Sgabeblack@google.com    os << "o_flag   = " << m_o_flag << ::std::endl;
69412854Sgabeblack@google.com    // TO BE COMPLETED
69512854Sgabeblack@google.com    // os << "observer = ";
69612854Sgabeblack@google.com    // if (m_observer != 0)
69712854Sgabeblack@google.com    //     m_observer->dump(os);
69812854Sgabeblack@google.com    // else
69912854Sgabeblack@google.com    //     os << "0" << ::std::endl;
70012854Sgabeblack@google.com    os << ")" << ::std::endl;
70112854Sgabeblack@google.com}
70212854Sgabeblack@google.com
70312854Sgabeblack@google.com// internal use only;
70412854Sgabeblack@google.combool
70512854Sgabeblack@google.comsc_fxnum_fast::get_bit(int i) const
70612854Sgabeblack@google.com{
70712854Sgabeblack@google.com    scfx_ieee_double id(m_val);
70812854Sgabeblack@google.com    if (id.is_zero() || id.is_nan() || id.is_inf())
70912854Sgabeblack@google.com        return false;
71012854Sgabeblack@google.com
71112854Sgabeblack@google.com    // convert to two's complement
71212854Sgabeblack@google.com    unsigned int m0 = id.mantissa0();
71312854Sgabeblack@google.com    unsigned int m1 = id.mantissa1();
71412854Sgabeblack@google.com
71512854Sgabeblack@google.com    if (id.is_normal())
71612854Sgabeblack@google.com        m0 += 1U << 20;
71712854Sgabeblack@google.com
71812854Sgabeblack@google.com    if (id.negative() != 0) {
71912854Sgabeblack@google.com        m0 = ~ m0;
72012854Sgabeblack@google.com        m1 = ~ m1;
72112854Sgabeblack@google.com        unsigned int tmp = m1;
72212854Sgabeblack@google.com        m1 += 1U;
72312854Sgabeblack@google.com        if (m1 <= tmp)
72412854Sgabeblack@google.com            m0 += 1U;
72512854Sgabeblack@google.com    }
72612854Sgabeblack@google.com
72712854Sgabeblack@google.com    // get the right bit
72812854Sgabeblack@google.com    int j = i - id.exponent();
72912854Sgabeblack@google.com    if ((j += 20) >= 32)
73012854Sgabeblack@google.com        return ((m0 & 1U << 31) != 0);
73112854Sgabeblack@google.com    else if (j >= 0)
73212854Sgabeblack@google.com        return ((m0 & 1U << j) != 0);
73312854Sgabeblack@google.com    else if ((j += 32) >= 0)
73412854Sgabeblack@google.com        return ((m1 & 1U << j) != 0);
73512854Sgabeblack@google.com    else
73612854Sgabeblack@google.com        return false;
73712854Sgabeblack@google.com}
73812854Sgabeblack@google.com
73912854Sgabeblack@google.com
74012854Sgabeblack@google.combool
74112854Sgabeblack@google.comsc_fxnum_fast::set_bit(int i, bool high)
74212854Sgabeblack@google.com{
74312854Sgabeblack@google.com    scfx_ieee_double id(m_val);
74412854Sgabeblack@google.com    if (id.is_nan() || id.is_inf())
74512854Sgabeblack@google.com        return false;
74612854Sgabeblack@google.com
74712854Sgabeblack@google.com    if (high) {
74812854Sgabeblack@google.com        if (get_bit(i))
74912854Sgabeblack@google.com            return true;
75012854Sgabeblack@google.com
75112854Sgabeblack@google.com        if (m_params.enc() == SC_TC_ && i == m_params.iwl() - 1)
75212854Sgabeblack@google.com            m_val -= scfx_pow2(i);
75312854Sgabeblack@google.com        else
75412854Sgabeblack@google.com            m_val += scfx_pow2(i);
75512854Sgabeblack@google.com    } else {
75612854Sgabeblack@google.com        if (!get_bit(i))
75712854Sgabeblack@google.com            return true;
75812854Sgabeblack@google.com
75912854Sgabeblack@google.com        if (m_params.enc() == SC_TC_ && i == m_params.iwl() - 1)
76012854Sgabeblack@google.com            m_val += scfx_pow2(i);
76112854Sgabeblack@google.com        else
76212854Sgabeblack@google.com            m_val -= scfx_pow2(i);
76312854Sgabeblack@google.com    }
76412854Sgabeblack@google.com
76512854Sgabeblack@google.com    return true;
76612854Sgabeblack@google.com}
76712854Sgabeblack@google.com
76812854Sgabeblack@google.com
76912854Sgabeblack@google.combool
77012854Sgabeblack@google.comsc_fxnum_fast::get_slice(int i, int j, sc_bv_base &bv) const
77112854Sgabeblack@google.com{
77212854Sgabeblack@google.com    scfx_ieee_double id(m_val);
77312854Sgabeblack@google.com    if (id.is_nan() || id.is_inf())
77412854Sgabeblack@google.com        return false;
77512854Sgabeblack@google.com
77612854Sgabeblack@google.com    // convert to two's complement
77712854Sgabeblack@google.com    unsigned int m0 = id.mantissa0();
77812854Sgabeblack@google.com    unsigned int m1 = id.mantissa1();
77912854Sgabeblack@google.com
78012854Sgabeblack@google.com    if (id.is_normal())
78112854Sgabeblack@google.com        m0 += 1U << 20;
78212854Sgabeblack@google.com
78312854Sgabeblack@google.com    if (id.negative() != 0) {
78412854Sgabeblack@google.com        m0 = ~ m0;
78512854Sgabeblack@google.com        m1 = ~ m1;
78612854Sgabeblack@google.com        unsigned int tmp = m1;
78712854Sgabeblack@google.com        m1 += 1U;
78812854Sgabeblack@google.com        if (m1 <= tmp)
78912854Sgabeblack@google.com            m0 += 1U;
79012854Sgabeblack@google.com    }
79112854Sgabeblack@google.com
79212854Sgabeblack@google.com    // get the bits
79312854Sgabeblack@google.com    int l = j;
79412854Sgabeblack@google.com    for (int k = 0; k < bv.length(); ++ k) {
79512854Sgabeblack@google.com        bool b = false;
79612854Sgabeblack@google.com
79712854Sgabeblack@google.com        int n = l - id.exponent();
79812854Sgabeblack@google.com        if ((n += 20) >= 32)
79912854Sgabeblack@google.com            b = ((m0 & 1U << 31) != 0);
80012854Sgabeblack@google.com        else if (n >= 0)
80112854Sgabeblack@google.com            b = ((m0 & 1U << n) != 0);
80212854Sgabeblack@google.com        else if ((n += 32) >= 0)
80312854Sgabeblack@google.com            b = ((m1 & 1U << n) != 0);
80412854Sgabeblack@google.com
80512854Sgabeblack@google.com        bv[k] = b;
80612854Sgabeblack@google.com
80712854Sgabeblack@google.com        if (i >= j)
80812854Sgabeblack@google.com            ++l;
80912854Sgabeblack@google.com        else
81012854Sgabeblack@google.com            --l;
81112854Sgabeblack@google.com    }
81212854Sgabeblack@google.com
81312854Sgabeblack@google.com    return true;
81412854Sgabeblack@google.com}
81512854Sgabeblack@google.com
81612854Sgabeblack@google.combool
81712854Sgabeblack@google.comsc_fxnum_fast::set_slice(int i, int j, const sc_bv_base &bv)
81812854Sgabeblack@google.com{
81912854Sgabeblack@google.com    scfx_ieee_double id(m_val);
82012854Sgabeblack@google.com    if (id.is_nan() || id.is_inf())
82112854Sgabeblack@google.com        return false;
82212854Sgabeblack@google.com
82312854Sgabeblack@google.com    // set the bits
82412854Sgabeblack@google.com    int l = j;
82512854Sgabeblack@google.com    for (int k = 0; k < bv.length(); ++k) {
82612854Sgabeblack@google.com        if (bv[k].to_bool()) {
82712854Sgabeblack@google.com            if (!get_bit(l)) {
82812854Sgabeblack@google.com                if (m_params.enc() == SC_TC_ && l == m_params.iwl() - 1)
82912854Sgabeblack@google.com                    m_val -= scfx_pow2(l);
83012854Sgabeblack@google.com                else
83112854Sgabeblack@google.com                    m_val += scfx_pow2(l);
83212854Sgabeblack@google.com            }
83312854Sgabeblack@google.com        } else {
83412854Sgabeblack@google.com            if (get_bit(l)) {
83512854Sgabeblack@google.com                if (m_params.enc() == SC_TC_ && l == m_params.iwl() - 1)
83612854Sgabeblack@google.com                    m_val += scfx_pow2(l);
83712854Sgabeblack@google.com                else
83812854Sgabeblack@google.com                    m_val -= scfx_pow2(l);
83912854Sgabeblack@google.com            }
84012854Sgabeblack@google.com        }
84112854Sgabeblack@google.com
84212854Sgabeblack@google.com        if (i >= j)
84312854Sgabeblack@google.com            ++l;
84412854Sgabeblack@google.com        else
84512854Sgabeblack@google.com            --l;
84612854Sgabeblack@google.com    }
84712854Sgabeblack@google.com
84812854Sgabeblack@google.com    return true;
84912854Sgabeblack@google.com}
85012854Sgabeblack@google.com
85112854Sgabeblack@google.comsc_fxnum_fast_observer *
85212854Sgabeblack@google.comsc_fxnum_fast::lock_observer() const
85312854Sgabeblack@google.com{
85412854Sgabeblack@google.com    SC_ASSERT_(m_observer != 0, "lock observer failed");
85512854Sgabeblack@google.com    sc_fxnum_fast_observer *tmp = m_observer;
85612854Sgabeblack@google.com    m_observer = 0;
85712854Sgabeblack@google.com    return tmp;
85812854Sgabeblack@google.com}
85912854Sgabeblack@google.com
86012854Sgabeblack@google.comvoid
86112854Sgabeblack@google.comsc_fxnum_fast::unlock_observer(sc_fxnum_fast_observer *observer_) const
86212854Sgabeblack@google.com{
86312854Sgabeblack@google.com    SC_ASSERT_(observer_ != 0, "unlock observer failed");
86412854Sgabeblack@google.com    m_observer = observer_;
86512854Sgabeblack@google.com}
86612854Sgabeblack@google.com
86712854Sgabeblack@google.com} // namespace sc_dt
868