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