/*****************************************************************************

  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
  more contributor license agreements.  See the NOTICE file distributed
  with this work for additional information regarding copyright ownership.
  Accellera licenses this file to you under the Apache License, Version 2.0
  (the "License"); you may not use this file except in compliance with the
  License.  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
  implied.  See the License for the specific language governing
  permissions and limitations under the License.

 *****************************************************************************/

/*****************************************************************************

  scfx_rep.cpp -

  Original Author: Robert Graulich, Synopsys, Inc.
                   Martin Janssen,  Synopsys, Inc.

 *****************************************************************************/

/*****************************************************************************

  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
  changes you are making here.

      Name, Affiliation, Date:
  Description of Modification:

 *****************************************************************************/


// $Log: scfx_rep.cpp,v $
// Revision 1.4  2011/08/24 22:05:43  acg
//  Torsten Maehne: initialization changes to remove warnings.
//
// Revision 1.3  2011/08/15 16:43:24  acg
//  Torsten Maehne: changes to remove unused argument warnings.
//
// Revision 1.2  2009/02/28 00:26:20  acg
//  Andy Goodrich: bug fixes.
//
// Revision 1.2  2008/11/06 17:22:47  acg
//  Andy Goodrich: bug fixes for 2.2.1.
//
// Revision 1.1.1.1  2006/12/15 20:31:36  acg
// SystemC 2.2
//
// Revision 1.3  2006/01/13 18:53:58  acg
// Andy Goodrich: added $Log command so that CVS comments are reproduced in
// the source.
//

#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>

#include "base/compiler.hh"
#include "systemc/ext/dt/bit/sc_bv_base.hh"
#include "systemc/ext/dt/bit/sc_lv_base.hh"
#include "systemc/ext/dt/fx/scfx_ieee.hh"
#include "systemc/ext/dt/fx/scfx_pow10.hh"
#include "systemc/ext/dt/fx/scfx_rep.hh"
#include "systemc/ext/dt/fx/scfx_utils.hh"
#include "systemc/ext/utils/endian.hh"
#include "systemc/ext/utils/messages.hh"

namespace sc_dt
{

// ----------------------------------------------------------------------------
//  some utilities
// ----------------------------------------------------------------------------

static scfx_pow10 pow10_fx;

static const int mantissa0_size = SCFX_IEEE_DOUBLE_M_SIZE - bits_in_int;

static inline int
n_word(int x)
{
    return (x + bits_in_word - 1) / bits_in_word;
}


// ----------------------------------------------------------------------------
//  CONSTRUCTORS
// ----------------------------------------------------------------------------

scfx_rep::scfx_rep() :
    m_mant(min_mant), m_wp(), m_sign(), m_state(), m_msw(), m_lsw(),
    m_r_flag(false)
{
    set_zero();
}

scfx_rep::scfx_rep(int a) : m_mant(min_mant), m_wp(), m_sign(), m_state(),
    m_msw(), m_lsw(), m_r_flag(false)
{
    if (a != 0) {
        m_mant.clear();
        m_wp = m_msw = m_lsw = 2;
        m_state = normal;
        if (a > 0) {
            m_mant[2] = a;
            m_sign = 1;
        } else {
            m_mant[2] = -a;
            m_sign = -1;
        }
    } else {
        set_zero();
    }
}

scfx_rep::scfx_rep(unsigned int a) : m_mant(min_mant), m_wp(), m_sign(),
    m_state(), m_msw(), m_lsw(), m_r_flag(false)
{
    if (a != 0) {
        m_mant.clear();
        m_wp = m_msw = m_lsw = 2;
        m_state = normal;
        m_mant[2] = a;
        m_sign = 1;
    } else {
        set_zero();
    }
}

scfx_rep::scfx_rep(long a) :
    m_mant(min_mant), m_wp(), m_sign(), m_state(), m_msw(), m_lsw(),
    m_r_flag(false)
{
    if (a != 0) {
        m_mant.clear();
        m_state = normal;
        if (a > 0) {
            m_sign = 1;
        } else {
            a = -a;
            m_sign = -1;
        }
#       if SC_LONG_64
            m_wp = 1;
            m_mant[1] = static_cast<word>(a);
            m_mant[2] = static_cast<word>(a >> bits_in_word);
            find_sw();
#       else
            m_wp = 2;
            m_msw = 2;
            m_lsw = 2;
            m_mant[2] = a;
#       endif
    } else {
        set_zero();
    }
}

scfx_rep::scfx_rep(unsigned long a) :
    m_mant(min_mant), m_wp(), m_sign(), m_state(), m_msw(), m_lsw(),
    m_r_flag(false)
{
    if (a != 0) {
        m_mant.clear();
        m_wp = m_msw = m_lsw = 2;
        m_state = normal;
#       if SC_LONG_64
            m_wp = 1;
            m_mant[1] = static_cast<word>(a);
            m_mant[2] = static_cast<word>(a >> bits_in_word);
            find_sw();
#       else
            m_wp = 2;
            m_msw = 2;
            m_lsw = 2;
            m_mant[2] = a;
#       endif
        m_sign = 1;
    }
    else
        set_zero();
}

scfx_rep::scfx_rep(double a) :
    m_mant(min_mant), m_wp(0), m_sign(), m_state(normal), m_msw(0),
    m_lsw(0), m_r_flag(false)
{
    m_mant.clear();

    scfx_ieee_double id(a);

    m_sign = id.negative() ? -1 : 1;

    if (id.is_nan()) {
        m_state = not_a_number;
    } else if (id.is_inf()) {
        m_state = infinity;
    } else if (id.is_subnormal()) {
        m_mant[0] = id.mantissa1();
        m_mant[1] = id.mantissa0();
        normalize(id.exponent() + 1 - SCFX_IEEE_DOUBLE_M_SIZE);
    } else if (id.is_normal()) {
        m_mant[0] = id.mantissa1();
        m_mant[1] = id.mantissa0() | (1 << mantissa0_size);
        normalize(id.exponent() - SCFX_IEEE_DOUBLE_M_SIZE);
    }
}

scfx_rep::scfx_rep(int64 a) :
    m_mant(min_mant), m_wp(), m_sign(), m_state(), m_msw(), m_lsw(),
    m_r_flag(false)
{
    if (a != 0) {
        m_mant.clear();
        m_wp = 1;
        m_state = normal;
        if (a > 0) {
            m_mant[1] = static_cast<word>(a);
            m_mant[2] = static_cast<word>(a >> bits_in_word);
            m_sign = 1;
        } else {
            m_mant[1] = static_cast<word>(-a);
            m_mant[2] = static_cast<word>((-a) >> bits_in_word);
            m_sign = -1;
        }
        find_sw();
    } else {
        set_zero();
    }
}

scfx_rep::scfx_rep(uint64 a) :
    m_mant(min_mant), m_wp(), m_sign(), m_state(), m_msw(), m_lsw(),
    m_r_flag(false)
{
    if (a != 0) {
        m_mant.clear();
        m_wp = 1;
        m_state = normal;
        m_mant[1] = static_cast<word>(a);
        m_mant[2] = static_cast<word>(a >> bits_in_word);
        m_sign = 1;
        find_sw();
    } else {
        set_zero();
    }
}

scfx_rep::scfx_rep(const sc_signed &a) :
    m_mant(min_mant), m_wp(), m_sign(), m_state(), m_msw(), m_lsw(),
    m_r_flag(false)
{
    if (a.iszero()) {
        set_zero();
    } else {
        int words = n_word(a.length());
        if (words > size())
            resize_to(words);
        m_mant.clear();
        m_wp = 0;
        m_state = normal;
        if (a.sign()) {
            sc_signed a2 = -a;
            for (int i = 0; i < a2.length(); ++i) {
                if (a2[i]) {
                    scfx_index x = calc_indices(i);
                    m_mant[x.wi()] |= 1 << x.bi();
                }
            }
            m_sign = -1;
        } else {
            for (int i = 0; i < a.length(); ++i) {
                if (a[i]) {
                    scfx_index x = calc_indices(i);
                    m_mant[x.wi()] |= 1 << x.bi();
                }
            }
            m_sign = 1;
        }
        find_sw();
    }
}

scfx_rep::scfx_rep(const sc_unsigned &a) :
    m_mant(min_mant), m_wp(), m_sign(), m_state(), m_msw(), m_lsw(),
    m_r_flag(false)
{
    if (a.iszero()) {
        set_zero();
    } else {
        int words = n_word(a.length());
        if (words > size())
            resize_to(words);
        m_mant.clear();
        m_wp = 0;
        m_state = normal;
        for (int i = 0; i < a.length(); ++i) {
            if (a[i]) {
                scfx_index x = calc_indices(i);
                m_mant[x.wi()] |= 1 << x.bi();
            }
        }
        m_sign = 1;
        find_sw();
    }
}

// copy constructor
scfx_rep::scfx_rep(const scfx_rep &a) :
    m_mant(a.m_mant), m_wp(a.m_wp), m_sign(a.m_sign), m_state(a.m_state),
    m_msw(a.m_msw), m_lsw(a.m_lsw), m_r_flag(false)
{}


// ----------------------------------------------------------------------------
//  OPERATORS : new, delete
//
//  Memory management for class scfx_rep.
// ----------------------------------------------------------------------------

union scfx_rep_node
{
    char data[sizeof(scfx_rep)];
    scfx_rep_node *next;
};

static scfx_rep_node *list = 0;

void *
scfx_rep::operator new(std::size_t size)
{
    const int ALLOC_SIZE = 1024;

    if (size != sizeof(scfx_rep))
        return ::operator new(size);

    if (!list) {
        list = new scfx_rep_node[ALLOC_SIZE];
        for (int i = 0; i < ALLOC_SIZE - 1; i++)
            list[i].next = list + i + 1;
        list[ALLOC_SIZE - 1].next = 0;
    }

    scfx_rep *ptr = reinterpret_cast<scfx_rep *>(list->data);
    list = list->next;

    return ptr;
}

void
scfx_rep::operator delete(void *ptr, std::size_t size)
{
    if (size != sizeof(scfx_rep)) {
        ::operator delete(ptr);
        return;
    }

    scfx_rep_node *node = static_cast<scfx_rep_node *>(ptr);
    node->next = list;
    list = node;
}


// ----------------------------------------------------------------------------
//  METHOD : from_string
//
//  Convert from character string to sc_fxrep.
// ----------------------------------------------------------------------------

#define SCFX_FAIL_IF_(cnd) \
{ \
    if ((cnd)) { \
        m_state = not_a_number; \
        m_mant.clear(); /* to avoid Purify UMRs during assignment */ \
        return; \
    } \
}

void
scfx_rep::from_string(const char *s, int cte_wl)
{
    SCFX_FAIL_IF_(s == 0 || *s == 0);

    scfx_string s2;
    s2 += s;
    s2 += '\0';

    bool sign_char;
    m_sign = scfx_parse_sign(s, sign_char);

    sc_numrep numrep = scfx_parse_prefix(s);

    int base = 0;

    switch (numrep) {
      case SC_DEC:
        {
            base = 10;
            if (scfx_is_nan(s)) {   // special case: NaN
                m_state = not_a_number;
                m_mant.clear(); /* to avoid Purify UMRs during assignment */
                return;
            }
            if (scfx_is_inf(s)) {   // special case: Infinity
                m_state = infinity;
                m_mant.clear(); /* to avoid Purify UMRs during assignment */
                return;
            }
            break;
        }
      case SC_BIN:
      case SC_BIN_US:
        {
            SCFX_FAIL_IF_(sign_char);
            base = 2;
            break;
        }

      case SC_BIN_SM:
        {
            base = 2;
            break;
        }
      case SC_OCT:
      case SC_OCT_US:
        {
            SCFX_FAIL_IF_(sign_char);
            base = 8;
            break;
        }
      case SC_OCT_SM:
        {
            base = 8;
            break;
        }
      case SC_HEX:
      case SC_HEX_US:
        {
            SCFX_FAIL_IF_(sign_char);
            base = 16;
            break;
        }
      case SC_HEX_SM:
        {
            base = 16;
            break;
        }
      case SC_CSD:
        {
            SCFX_FAIL_IF_(sign_char);
            base = 2;
            scfx_csd2tc(s2);
            s = (const char *)s2 + 4;
            numrep = SC_BIN;
            break;
        }
      default:
        ;
    }

    //
    // find end of mantissa and count the digits and points
    //

    const char *end = s;
    bool based_point = false;
    int int_digits = 0;
    int frac_digits = 0;

    while (*end) {
        if (scfx_exp_start(end))
            break;

        if (*end == '.') {
            SCFX_FAIL_IF_(based_point);
            based_point = true;
        } else {
            SCFX_FAIL_IF_(!scfx_is_digit(*end, numrep));
            if (based_point)
                frac_digits++;
            else
                int_digits++;
        }

        ++end;
    }

    SCFX_FAIL_IF_(int_digits == 0 && frac_digits == 0);

    // [ exponent ]
    int exponent = 0;

    if (*end) {
        for (const char *e = end + 2; *e; ++e)
            SCFX_FAIL_IF_(!scfx_is_digit(*e, SC_DEC));
        exponent = std::atoi(end + 1);
    }

    //
    // check if the mantissa is negative
    //
    bool mant_is_neg = false;
    switch (numrep) {
      case SC_BIN:
      case SC_OCT:
      case SC_HEX:
        {
            const char *p = s;
            if (*p == '.')
                ++p;

            mant_is_neg = (scfx_to_digit(* p, numrep) >= (base >> 1));
            break;
        }
      default:
            ;
    }

    //
    // convert the mantissa
    //

    switch (base) {
      case 2:
        {
            int bit_offset = exponent % bits_in_word;
            int word_offset = exponent / bits_in_word;

            int_digits += bit_offset;
            frac_digits -= bit_offset;

            int words = n_word(int_digits) + n_word(frac_digits);
            if (words > size())
                resize_to(words);
            m_mant.clear();

            int j = n_word(frac_digits) * bits_in_word + int_digits - 1;

            for (; s < end; s++) {
                switch (*s) {
                  case '1':
                    set_bin(j);
                    M5_FALLTHROUGH;
                  case '0':
                    j--;
                    M5_FALLTHROUGH;
                  case '.':
                    break;
                  default:
                    SCFX_FAIL_IF_(true); // should not happen
                }
            }

            m_wp = n_word(frac_digits) - word_offset;
            break;
        }
      case 8:
        {
            exponent *= 3;
            int_digits *= 3;
            frac_digits *= 3;

            int bit_offset = exponent % bits_in_word;
            int word_offset = exponent / bits_in_word;

            int_digits += bit_offset;
            frac_digits -= bit_offset;

            int words = n_word(int_digits) + n_word(frac_digits);
            if (words > size())
                resize_to(words);
            m_mant.clear();

            int j = n_word(frac_digits) * bits_in_word + int_digits - 3;

            for (; s < end; s++) {
                switch (*s) {
                  case '7': case '6': case '5': case '4':
                  case '3': case '2': case '1':
                    set_oct(j, *s - '0');
                    M5_FALLTHROUGH;
                  case '0':
                    j -= 3;
                    M5_FALLTHROUGH;
                  case '.':
                    break;
                  default:
                    SCFX_FAIL_IF_(true); // should not happen
                }
            }

            m_wp = n_word(frac_digits) - word_offset;
            break;
        }
      case 10:
        {
            word carry, temp;
            int length = int_digits + frac_digits;
            resize_to(sc_max(min_mant, n_word(4 * length)));

            m_mant.clear();
            m_msw = m_lsw = 0;

            for (; s < end; s++) {
                switch (*s) {
                  case '9': case '8': case '7': case '6': case '5':
                  case '4': case '3': case '2': case '1': case '0':
                    multiply_by_ten();
                    carry = *s - '0';
                    for (int i = 0; carry && i < m_mant.size(); i++) {
                        temp = m_mant[i];
                        temp += carry;
                        carry = temp < m_mant[i];
                        m_mant[i] = temp;
                    }
                  case '.':
                    break;
                  default:
                    SCFX_FAIL_IF_(true); // should not happen
                }
            }

            m_wp = 0;
            find_sw();

            int denominator = frac_digits - exponent;

            if (denominator) {
                scfx_rep frac_num = pow10_fx(denominator);
                scfx_rep *temp_num =
                    div_scfx_rep(const_cast<const scfx_rep &>(*this),
                                   frac_num, cte_wl);
                *this = *temp_num;
                delete temp_num;
            }

            break;
        }
      case 16:
        {
            exponent *= 4;
            int_digits *= 4;
            frac_digits *= 4;

            int bit_offset = exponent % bits_in_word;
            int word_offset = exponent / bits_in_word;

            int_digits += bit_offset;
            frac_digits -= bit_offset;

            int words = n_word(int_digits) + n_word(frac_digits);
            if (words > size())
                resize_to(words);
            m_mant.clear();

            int j = n_word(frac_digits) * bits_in_word + int_digits - 4;

            for (; s < end; s ++) {
                switch (*s) {
                  case 'f': case 'e': case 'd': case 'c': case 'b': case 'a':
                    set_hex(j, *s - 'a' + 10);
                    j -= 4;
                    break;
                  case 'F': case 'E': case 'D': case 'C': case 'B': case 'A':
                    set_hex(j, *s - 'A' + 10);
                    j -= 4;
                    break;
                  case '9': case '8': case '7': case '6': case '5':
                  case '4': case '3': case '2': case '1':
                    set_hex(j, *s - '0');
                    M5_FALLTHROUGH;
                  case '0':
                    j -= 4;
                    M5_FALLTHROUGH;
                  case '.':
                    break;
                  default:
                    SCFX_FAIL_IF_(true); // should not happen
                }
            }

            m_wp = n_word(frac_digits) - word_offset;
            break;
        }
    }

    m_state = normal;
    find_sw();

    //
    // two's complement of mantissa if it is negative
    //
    if (mant_is_neg) {
        m_mant[m_msw] |=  ~0U << scfx_find_msb(m_mant[m_msw]);
        for (int i = m_msw + 1; i < m_mant.size(); ++i)
            m_mant[i] = static_cast<word>(-1);
        complement(m_mant, m_mant, m_mant.size());
        inc(m_mant);
        m_sign *= -1;
        find_sw();
    }
}

#undef SCFX_FAIL_IF_

// ----------------------------------------------------------------------------
//  METHOD : to_double
//
//  Convert from scfx_rep to double.
// ----------------------------------------------------------------------------

double
scfx_rep::to_double() const
{
    scfx_ieee_double id;

    // handle special cases
    if (is_nan()) {
        id.set_nan();
        return id;
    }

    if (is_inf()) {
        id.set_inf();
        id.negative(m_sign < 0);
        return id;
    }

    if (is_zero()) {
        id = 0.;
        id.negative(m_sign < 0);
        return id;
    }

    int msb = scfx_find_msb(m_mant[m_msw]);

    int exp = (m_msw - m_wp) * bits_in_word + msb;

    if (exp > SCFX_IEEE_DOUBLE_E_MAX) {
        id.set_inf();
        id.negative(m_sign < 0);
        return id;
    }

    if (exp < SCFX_IEEE_DOUBLE_E_MIN -
        static_cast<int>(SCFX_IEEE_DOUBLE_M_SIZE))
    {
        id = 0.;
        return id;
    }

    int shift = mantissa0_size - msb;

    unsigned int m0;
    unsigned int m1 = 0;
    unsigned int guard = 0;

    if (shift == 0) {
        m0 = m_mant[m_msw] & ~(1 << mantissa0_size);
        if (m_msw > m_lsw) {
            m1 = m_mant[m_msw - 1];
            if (m_msw - 1 > m_lsw)
                guard = m_mant[m_msw - 2] >> (bits_in_word - 1);
        }
    } else if (shift < 0) {
        m0 = (m_mant[m_msw] >> -shift) & ~(1 << mantissa0_size);
        m1 = m_mant[m_msw] << (bits_in_word + shift);
        if (m_msw > m_lsw) {
            m1 |= m_mant[m_msw - 1] >> -shift;
            guard = (m_mant[m_msw - 1] >> (-shift - 1)) & 1;
        }
    } else {
        m0 = (m_mant[m_msw] << shift) & ~(1 << mantissa0_size);
        if (m_msw > m_lsw) {
            m0 |= m_mant[m_msw - 1] >> (bits_in_word - shift);
            m1 = m_mant[m_msw - 1] << shift;
            if (m_msw - 1 > m_lsw) {
                m1 |= m_mant[m_msw - 2] >> (bits_in_word - shift);
                guard = (m_mant[m_msw - 2] >> (bits_in_word - shift - 1)) & 1;
            }
        }
    }

    if (exp < SCFX_IEEE_DOUBLE_E_MIN) {
        m0 |= (1 << mantissa0_size);

        int subnormal_shift = SCFX_IEEE_DOUBLE_E_MIN - exp;

        if (subnormal_shift < bits_in_word) {
            m1 = m1 >> subnormal_shift |
                m0 << (bits_in_word - subnormal_shift);
            m0 = m0 >> subnormal_shift;
        } else {
            m1 = m0 >> (subnormal_shift - bits_in_word);
            m0 = 0;
        }

        guard = 0;

        exp = SCFX_IEEE_DOUBLE_E_MIN - 1;
    }

    id.mantissa0(m0);
    id.mantissa1(m1);
    id.exponent(exp);
    id.negative(m_sign < 0);

    double result = id;

    if (guard != 0)
        result += m_sign * scfx_pow2(exp - SCFX_IEEE_DOUBLE_M_SIZE);

    return result;
}


// ----------------------------------------------------------------------------
//  METHOD : to_uint64
//
//  Convert from scfx_rep to uint64.
//  Truncates towards 0 _then_ wraps; infinities and NaN go to zero.
// ----------------------------------------------------------------------------

uint64
scfx_rep::to_uint64() const
{
    if (!is_normal() || is_zero()) {
        return 0;
    }

    uint64 result = 0;
    int shift = 0;
    int idx = m_wp;

    // Ignore bits off the top; they modulo out.
    // Ignore bits off the bottom; we're truncating.
    while (shift < 64 && m_msw >= idx && idx >= m_lsw) {
        result += static_cast<uint64>(m_mant[idx]) << shift;
        shift += bits_in_word;
        idx += 1;
    }

    return m_sign > 0 ? result : -result;
}


// ----------------------------------------------------------------------------
//  METHOD : to_string
//
//  Convert from scfx_rep to character string.
// ----------------------------------------------------------------------------

void
print_dec(scfx_string &s, const scfx_rep &num, int w_prefix, sc_fmt fmt)
{
    if (num.is_neg())
        s += '-';

    if (w_prefix == 1) {
        scfx_print_prefix(s, SC_DEC);
    }

    if (num.is_zero()) {
        s += '0';
        return;
    }

    // split 'num' into its integer and fractional part
    scfx_rep int_part = num;
    scfx_rep frac_part = num;

    int i;

    for (i = int_part.m_lsw; i <= int_part.m_msw && i < int_part.m_wp; i++)
        int_part.m_mant[i] = 0;
    int_part.find_sw();
    if (int_part.m_wp < int_part.m_lsw)
        int_part.resize_to(int_part.size() - int_part.m_wp, -1);

    for (i = frac_part.m_msw;
            i >= frac_part.m_lsw && i >= frac_part.m_wp; i--)
        frac_part.m_mant[i] = 0;
    frac_part.find_sw();
    if (frac_part.m_msw == frac_part.size() - 1)
        frac_part.resize_to(frac_part.size() + 1, 1);

    // print integer part
    int int_digits = 0;
    int int_zeros  = 0;

    if (!int_part.is_zero()) {
        double int_wl = (int_part.m_msw - int_part.m_wp) * bits_in_word +
                         scfx_find_msb(int_part.m_mant[int_part.m_msw]) + 1;
        int_digits = (int)std::ceil(int_wl * std::log10(2.));

        int len = s.length();
        s.append(int_digits);

        bool zero_digits = (frac_part.is_zero() && fmt != SC_F);

        for (i = int_digits + len - 1; i >= len; i--) {
            unsigned int remainder = int_part.divide_by_ten();
            s[i] = static_cast<char>('0' + remainder);

            if (zero_digits) {
                if (remainder == 0)
                    int_zeros++;
                else
                    zero_digits = false;
            }
        }

        // discard trailing zeros from int_part
        s.discard(int_zeros);

        if (s[len] == '0') {
            // int_digits was overestimated by one
            s.remove(len);
            --int_digits;
        }
    }

    // print fractional part
    int frac_digits = 0;
    int frac_zeros  = 0;

    if (!frac_part.is_zero()) {
        s += '.';

        bool zero_digits = (int_digits == 0 && fmt != SC_F);

        double frac_wl = (frac_part.m_wp - frac_part.m_msw) * bits_in_word -
                          scfx_find_msb(frac_part.m_mant[frac_part.m_msw]) - 1;
        frac_zeros = (int)std::floor(frac_wl * std::log10(2.));

        scfx_rep temp;
        sc_dt::multiply(temp, frac_part, pow10_fx(frac_zeros));
        frac_part = temp;
        if (frac_part.m_msw == frac_part.size() - 1)
            frac_part.resize_to(frac_part.size() + 1, 1);

        frac_digits = frac_zeros;
        if (!zero_digits) {
            for (i = 0; i < frac_zeros; i++)
                s += '0';
            frac_zeros = 0;
        }

        while (!frac_part.is_zero()) {
            frac_part.multiply_by_ten();
            int n = frac_part.m_mant[frac_part.m_msw + 1];

            if (zero_digits) {
                if (n == 0)
                    frac_zeros++;
                else
                    zero_digits = false;
            }

            if (! zero_digits)
                s += static_cast<char>('0' + n);

            frac_part.m_mant[frac_part.m_msw + 1] = 0;
            frac_digits++;
        }
    }

    // print exponent
    if (fmt != SC_F) {
        if (frac_digits == 0)
            scfx_print_exp(s, int_zeros);
        else if (int_digits == 0)
            scfx_print_exp(s, -frac_zeros);
    }
}

void
print_other(scfx_string &s, const scfx_rep &a, sc_numrep numrep, int w_prefix,
            sc_fmt fmt, const scfx_params *params)
{
    scfx_rep b = a;

    sc_numrep numrep2 = numrep;

    bool numrep_is_sm = (numrep == SC_BIN_SM ||
                         numrep == SC_OCT_SM ||
                         numrep == SC_HEX_SM);

    if (numrep_is_sm) {
        if (b.is_neg()) {
            s += '-';
            b = *neg_scfx_rep(a);
        }
        switch (numrep) {
          case SC_BIN_SM:
            numrep2 = SC_BIN_US;
            break;
          case SC_OCT_SM:
            numrep2 = SC_OCT_US;
            break;
          case SC_HEX_SM:
            numrep2 = SC_HEX_US;
            break;
          default:
            ;
        }
    }

    if (w_prefix != 0) {
        scfx_print_prefix(s, numrep);
    }

    numrep = numrep2;

    int msb, lsb;

    if (params != 0) {
        msb = params->iwl() - 1;
        lsb = params->iwl() - params->wl();

        if (params->enc() == SC_TC_ &&
            (numrep == SC_BIN_US ||
              numrep == SC_OCT_US ||
              numrep == SC_HEX_US) &&
            !numrep_is_sm &&
            params->wl() > 1) {
            --msb;
        } else if (params->enc() == SC_US_ &&
            (numrep == SC_BIN ||
              numrep == SC_OCT ||
              numrep == SC_HEX ||
              numrep == SC_CSD)) {
            ++msb;
        }
    } else {
        if (b.is_zero()) {
            msb = 0;
            lsb = 0;
        } else {
            msb = (b.m_msw - b.m_wp) * bits_in_word
                + scfx_find_msb(b.m_mant[ b.m_msw ]) + 1;
            while (b.get_bit(msb) == b.get_bit(msb - 1))
                --msb;

            if (numrep == SC_BIN_US ||
                numrep == SC_OCT_US ||
                numrep == SC_HEX_US) {
                --msb;
            }

            lsb = (b.m_lsw - b.m_wp) * bits_in_word +
                scfx_find_lsb(b.m_mant[b.m_lsw]);

        }
    }

    int step;

    switch (numrep) {
      case SC_BIN:
      case SC_BIN_US:
      case SC_CSD:
        step = 1;
       break;
      case SC_OCT:
      case SC_OCT_US:
        step = 3;
        break;
      case SC_HEX:
      case SC_HEX_US:
        step = 4;
        break;
      default:
        SC_REPORT_FATAL(sc_core::SC_ID_ASSERTION_FAILED_,
                "unexpected sc_numrep");
        sc_core::sc_abort();
    }

    msb = (int)std::ceil(double(msb + 1) / step) * step - 1;

    lsb = (int)std::floor(double(lsb) / step) * step;

    if (msb < 0) {
        s += '.';
        if (fmt == SC_F) {
            int sign = (b.is_neg()) ? (1 << step) - 1 : 0;
            for (int i = (msb + 1) / step; i < 0; i++) {
                if (sign < 10)
                    s += static_cast<char>(sign + '0');
                else
                    s += static_cast<char>(sign + 'a' - 10);
            }
        }
    }

    int i = msb;
    while (i >= lsb) {
        int value = 0;
        for (int j = step - 1; j >= 0; --j) {
            value += static_cast<int>(b.get_bit(i)) << j;
            --i;
        }
        if (value < 10)
            s += static_cast<char>(value + '0');
        else
            s += static_cast<char>(value + 'a' - 10);
        if (i == -1)
            s += '.';
    }

    if (lsb > 0 && fmt == SC_F) {
        for (int i = lsb / step; i > 0; i--)
            s += '0';
    }

    if (s[s.length() - 1] == '.')
        s.discard(1);

    if (fmt != SC_F) {
        if (msb < 0)
            scfx_print_exp(s, (msb + 1) / step);
        else if (lsb > 0)
            scfx_print_exp(s, lsb / step);
    }

    if (numrep == SC_CSD)
        scfx_tc2csd(s, w_prefix);
}

const char *
scfx_rep::to_string(sc_numrep numrep, int w_prefix,
                    sc_fmt fmt, const scfx_params *params) const
{
    static scfx_string s;

    s.clear();

    if (is_nan()) {
        scfx_print_nan(s);
    } else if (is_inf()) {
        scfx_print_inf(s, is_neg());
    } else if (is_neg() && !is_zero() &&
               (numrep == SC_BIN_US ||
                numrep == SC_OCT_US ||
                numrep == SC_HEX_US)) {
        s += "negative";
    } else if (numrep == SC_DEC || numrep == SC_NOBASE) {
        sc_dt::print_dec(s, *this, w_prefix, fmt);
    } else {
        sc_dt::print_other(s, *this, numrep, w_prefix, fmt, params);
    }

    return s;
}


// ----------------------------------------------------------------------------
//  ADD
//
//  add two mantissas of the same size
//  result has the same size
//  returns carry of operation
// ----------------------------------------------------------------------------

static inline int
add_mants(int size, scfx_mant &result, const scfx_mant &a, const scfx_mant &b)
{
    unsigned int carry = 0;

    int index = 0;

    do {
        word x = a[index];
        word y = b[index];

        y += carry;
        carry = y < carry;
        y += x;
        carry += y < x;
        result[index] = y;
    } while (++index < size);

    return (carry ? 1 : 0);
}

static inline int
sub_mants(int size, scfx_mant &result, const scfx_mant &a, const scfx_mant &b)
{
    unsigned carry = 0;

    int index = 0;

    do {
        word x = a[index];
        word y = b[index];

        y += carry;
        carry = y < carry;
        y = x - y;
        carry += y > x;
        result[index] = y;
    } while (++index < size);

    return (carry ? 1 : 0);
}

scfx_rep *
add_scfx_rep(const scfx_rep &lhs, const scfx_rep &rhs, int max_wl)
{
    scfx_rep &result = *new scfx_rep;

    //
    // check for special cases
    //
    if (lhs.is_nan() || rhs.is_nan() ||
        (lhs.is_inf() && rhs.is_inf() && lhs.m_sign != rhs.m_sign)) {
        result.set_nan();
        return &result;
    }

    if (lhs.is_inf()) {
        result.set_inf(lhs.m_sign);
        return &result;
    }

    if (rhs.is_inf()) {
        result.set_inf(rhs.m_sign);
        return &result;
    }

    //
    // align operands if needed
    //
    scfx_mant_ref lhs_mant;
    scfx_mant_ref rhs_mant;

    int len_mant = lhs.size();
    int new_wp = lhs.m_wp;

    align(lhs, rhs, new_wp, len_mant, lhs_mant, rhs_mant);

    //
    // size the result mantissa
    //
    result.resize_to(len_mant);
    result.m_wp = new_wp;

    //
    // do it
    //
    if (lhs.m_sign == rhs.m_sign) {
        add_mants(len_mant, result.m_mant, lhs_mant, rhs_mant);
        result.m_sign = lhs.m_sign;
    } else {
        int cmp = compare_abs(lhs, rhs);

        if (cmp == 1) {
            sub_mants(len_mant, result.m_mant, lhs_mant, rhs_mant);
            result.m_sign = lhs.m_sign;
        } else if (cmp == -1) {
            sub_mants(len_mant, result.m_mant, rhs_mant, lhs_mant);
            result.m_sign = rhs.m_sign;
        } else {
            result.m_mant.clear();
            result.m_sign = 1;
        }
    }

    result.find_sw();
    result.round(max_wl);

    return &result;
}


// ----------------------------------------------------------------------------
//  SUB
//
//  sub two word's of the same size
//  result has the same size
//  returns carry of operation
// ----------------------------------------------------------------------------

static inline int
sub_with_index(scfx_mant &a, int a_msw, int /*a_lsw*/,
               const scfx_mant &b, int b_msw, int b_lsw)
{
    unsigned carry = 0;

    int size = b_msw - b_lsw;
    int a_index = a_msw - size;
    int b_index = b_msw - size;

    do {
        word x = a[a_index];
        word y = b[b_index];

        y += carry;
        carry = y < carry;
        y = x - y;
        carry += y > x;
        a[a_index] = y;

        a_index++;
        b_index++;
    } while (size--);

    if (carry) {
        // special case: a[a_msw + 1] == 1
        a[a_msw + 1] = 0;
    }

    return (carry ? 1 : 0);
}

scfx_rep *
sub_scfx_rep(const scfx_rep &lhs, const scfx_rep &rhs, int max_wl)
{
    scfx_rep &result = *new scfx_rep;

    //
    // check for special cases
    //
    if (lhs.is_nan() || rhs.is_nan() ||
        (lhs.is_inf() && rhs.is_inf() && lhs.m_sign == rhs.m_sign)) {
        result.set_nan();
        return &result;
    }

    if (lhs.is_inf()) {
        result.set_inf(lhs.m_sign);
        return &result;
    }

    if (rhs.is_inf()) {
        result.set_inf(-1 * rhs.m_sign);
        return &result;
    }

    //
    // align operands if needed
    //
    scfx_mant_ref lhs_mant;
    scfx_mant_ref rhs_mant;

    int len_mant = lhs.size();
    int new_wp = lhs.m_wp;

    align(lhs, rhs, new_wp, len_mant, lhs_mant, rhs_mant);

    //
    // size the result mantissa
    //
    result.resize_to(len_mant);
    result.m_wp = new_wp;

    //
    // do it
    //
    if (lhs.m_sign != rhs.m_sign) {
        add_mants(len_mant, result.m_mant, lhs_mant, rhs_mant);
        result.m_sign = lhs.m_sign;
    } else {
        int cmp = compare_abs(lhs, rhs);

        if (cmp == 1) {
            sub_mants(len_mant, result.m_mant, lhs_mant, rhs_mant);
            result.m_sign = lhs.m_sign;
        } else if (cmp == -1) {
            sub_mants(len_mant, result.m_mant, rhs_mant, lhs_mant);
            result.m_sign = -rhs.m_sign;
        } else {
            result.m_mant.clear();
            result.m_sign = 1;
        }
    }

    result.find_sw();
    result.round(max_wl);

    return &result;
}


// ----------------------------------------------------------------------------
//  MUL
// ----------------------------------------------------------------------------

union word_short
{
    word l;
    struct
    {
#if defined(SC_BOOST_BIG_ENDIAN)
        half_word u;
        half_word l;
#elif defined(SC_BOOST_LITTLE_ENDIAN)
        half_word l;
        half_word u;
#endif
    } s;
};

#if defined(SC_BOOST_BIG_ENDIAN)
static const int half_word_incr = -1;
#elif defined(SC_BOOST_LITTLE_ENDIAN)
static const int half_word_incr = 1;
#endif

void
multiply(scfx_rep &result, const scfx_rep &lhs, const scfx_rep &rhs,
         int max_wl)
{
    //
    // check for special cases
    //
    if (lhs.is_nan() || rhs.is_nan() ||
        (lhs.is_inf() && rhs.is_zero()) ||
        (lhs.is_zero() && rhs.is_inf())) {
        result.set_nan();
        return;
    }

    if (lhs.is_inf() || rhs.is_inf()) {
        result.set_inf(lhs.m_sign * rhs.m_sign);
        return;
    }

    if (lhs.is_zero() || rhs.is_zero()) {
        result.set_zero(lhs.m_sign * rhs.m_sign);
        return;
    }

    //
    // do it
    //
    int len_lhs = lhs.m_msw - lhs.m_lsw + 1;
    int len_rhs = rhs.m_msw - rhs.m_lsw + 1;

    int new_size = sc_max(min_mant, len_lhs + len_rhs);
    int new_wp = (lhs.m_wp - lhs.m_lsw) + (rhs.m_wp - rhs.m_lsw);
    int new_sign = lhs.m_sign * rhs.m_sign;

    result.resize_to(new_size);
    result.m_mant.clear();
    result.m_wp = new_wp;
    result.m_sign = new_sign;
    result.m_state = scfx_rep::normal;

    half_word *s1 = lhs.m_mant.half_addr(lhs.m_lsw);
    half_word *s2 = rhs.m_mant.half_addr(rhs.m_lsw);

    half_word *t = result.m_mant.half_addr();

    len_lhs <<= 1;
    len_rhs <<= 1;

    int i1, i2;

    for (i1 = 0; i1 * half_word_incr < len_lhs; i1 += half_word_incr) {
        word_short ls;
        ls.l = 0;

        half_word v1 = s1[i1];

        for (i2  = 0; i2 * half_word_incr < len_rhs; i2 += half_word_incr) {
            ls.l  += v1 * s2[i2];
            ls.s.l = ls.s.u + ((t[i2] += ls.s.l) < ls.s.l);
            ls.s.u = 0;
        }

        t[i2] = ls.s.l;
        t += half_word_incr;
    }

    result.find_sw();
    result.round(max_wl);
}


// ----------------------------------------------------------------------------
//  DIV
// ----------------------------------------------------------------------------

scfx_rep *
div_scfx_rep(const scfx_rep &lhs, const scfx_rep &rhs, int div_wl)
{
    scfx_rep &result = *new scfx_rep;

    //
    // check for special cases
    //
    if (lhs.is_nan() || rhs.is_nan() || (lhs.is_inf() && rhs.is_inf()) ||
        (lhs.is_zero() && rhs.is_zero())) {
        result.set_nan();
        return &result;
    }

    if (lhs.is_inf() || rhs.is_zero()) {
        result.set_inf(lhs.m_sign * rhs.m_sign);
        return &result;
    }

    if (lhs.is_zero() || rhs.is_inf()) {
        result.set_zero(lhs.m_sign * rhs.m_sign);
        return &result;
    }

    //
    // do it
    //

    // compute one bit more for rounding
    div_wl++;

    result.resize_to(sc_max(n_word(div_wl) + 1, min_mant));
    result.m_mant.clear();
    result.m_sign = lhs.m_sign * rhs.m_sign;

    int msb_lhs = scfx_find_msb(lhs.m_mant[lhs.m_msw]) +
                  (lhs.m_msw - lhs.m_wp) * bits_in_word;
    int msb_rhs = scfx_find_msb(rhs.m_mant[rhs.m_msw]) +
                  (rhs.m_msw - rhs.m_wp) * bits_in_word;

    int msb_res = msb_lhs - msb_rhs;
    int to_shift = -msb_res % bits_in_word;
    int result_index;

    int c = (msb_res % bits_in_word >= 0) ? 1 : 0;

    result_index = (result.size() - c) * bits_in_word + msb_res % bits_in_word;
    result.m_wp = (result.size() - c) - msb_res / bits_in_word;

    scfx_rep remainder = lhs;

    // align msb from remainder to msb from rhs
    remainder.lshift(to_shift);

    // make sure msw(remainder) < size - 1
    if (remainder.m_msw == remainder.size() - 1)
        remainder.resize_to(remainder.size() + 1, 1);

    // make sure msw(remainder) >= msw(rhs)!
    int msw_diff = rhs.m_msw - remainder.m_msw;
    if (msw_diff > 0)
        remainder.resize_to(remainder.size() + msw_diff, -1);

    int counter;

    for (counter = div_wl; counter && !remainder.is_zero(); counter--) {
        if (compare_msw_ff(rhs, remainder) <= 0) {
            result.set_bin(result_index);
            sub_with_index(remainder.m_mant, remainder.m_msw, remainder.m_lsw,
                           rhs.m_mant, rhs.m_msw, rhs.m_lsw);
        }
        result_index--;
        remainder.shift_left(1);
        remainder.m_lsw = remainder.find_lsw();
    }

    // perform convergent rounding, if needed
    if (counter == 0) {
        int index = result_index + 1 - result.m_wp * bits_in_word;

        scfx_index x = result.calc_indices(index);
        scfx_index x1 = result.calc_indices(index + 1);

        if (result.o_bit_at(x) && result.o_bit_at(x1))
            result.q_incr(x);

        result.m_r_flag = true;
    }

    result.find_sw();

    return &result;
}

// ----------------------------------------------------------------------------
//  destructive shift mantissa to the left
// ----------------------------------------------------------------------------

void
scfx_rep::lshift(int n)
{
    if (n == 0)
        return;

    if (n < 0) {
        rshift(-n);
        return;
    }

    if (is_normal()) {
        int shift_bits = n % bits_in_word;
        int shift_words = n / bits_in_word;

        // resize if needed
        if (m_msw == size() - 1 &&
            scfx_find_msb(m_mant[m_msw]) >= bits_in_word - shift_bits)
            resize_to(size() + 1, 1);

        // do it
        m_wp -= shift_words;
        shift_left(shift_bits);
        find_sw();
    }
}

// ----------------------------------------------------------------------------
//  destructive shift mantissa to the right
// ----------------------------------------------------------------------------

void
scfx_rep::rshift(int n)
{
    if (n == 0)
        return;

    if (n < 0) {
        lshift(-n);
        return;
    }

    if (is_normal()) {
        int shift_bits = n % bits_in_word;
        int shift_words = n / bits_in_word;

        // resize if needed
        if (m_lsw == 0 && scfx_find_lsb(m_mant[m_lsw]) < shift_bits)
            resize_to(size() + 1, -1);

        // do it
        m_wp += shift_words;
        shift_right(shift_bits);
        find_sw();
    }
}


// ----------------------------------------------------------------------------
//  FRIEND FUNCTION : compare_abs
//
//  Compares the absolute values of two scfx_reps, excluding the special cases.
// ----------------------------------------------------------------------------

int
compare_abs(const scfx_rep &a, const scfx_rep &b)
{
    // check for zero
    word a_word = a.m_mant[a.m_msw];
    word b_word = b.m_mant[b.m_msw];

    if (a_word == 0 || b_word == 0) {
        if (a_word != 0)
            return 1;
        if (b_word != 0)
            return -1;
        return 0;
    }

    // compare msw index
    int a_msw = a.m_msw - a.m_wp;
    int b_msw = b.m_msw - b.m_wp;

    if (a_msw > b_msw)
        return 1;

    if (a_msw < b_msw)
        return -1;

    // compare content
    int a_i = a.m_msw;
    int b_i = b.m_msw;

    while (a_i >= a.m_lsw && b_i >= b.m_lsw) {
        a_word = a.m_mant[a_i];
        b_word = b.m_mant[b_i];
        if (a_word > b_word)
            return 1;
        if (a_word < b_word)
            return -1;
        --a_i;
        --b_i;
    }

    bool a_zero = true;
    while (a_i >= a.m_lsw) {
        a_zero = a_zero && (a.m_mant[a_i] == 0);
        --a_i;
    }

    bool b_zero = true;
    while (b_i >= b.m_lsw) {
        b_zero = b_zero && (b.m_mant[b_i] == 0);
        --b_i;
    }

    // assertion: a_zero || b_zero

    if (!a_zero && b_zero)
        return 1;

    if (a_zero && !b_zero)
        return -1;

    return 0;
}

// ----------------------------------------------------------------------------
//  FRIEND FUNCTION : cmp_scfx_rep
//
//  Compares the values of two scfx_reps, including the special cases.
// ----------------------------------------------------------------------------

int
cmp_scfx_rep(const scfx_rep &a, const scfx_rep &b)
{
    // handle special cases

    if (a.is_nan() || b.is_nan()) {
        return 2;
    }

    if (a.is_inf() || b.is_inf()) {
        if (a.is_inf()) {
            if (!a.is_neg()) {
                if (b.is_inf() && !b.is_neg()) {
                    return 0;
                } else {
                    return 1;
                }
            } else {
                if (b.is_inf() && b.is_neg()) {
                    return 0;
                } else {
                    return -1;
                }
            }
        }
        if (b.is_inf()) {
            if (!b.is_neg()) {
                return -1;
            } else {
                return 1;
            }
        }
    }

    if (a.is_zero() && b.is_zero()) {
        return 0;
    }

    // compare sign
    if (a.m_sign != b.m_sign) {
        return a.m_sign;
    }

    return (a.m_sign * compare_abs(a, b));
}


// ----------------------------------------------------------------------------
//  PRIVATE METHOD : quantization
//
//  Performs destructive quantization.
// ----------------------------------------------------------------------------

void
scfx_rep::quantization(const scfx_params &params, bool &q_flag)
{
    scfx_index x = calc_indices(params.iwl() - params.wl());

    if (x.wi() < 0)
        return;

    if (x.wi() >= size())
        resize_to(x.wi() + 1, 1);

    bool qb = q_bit(x);
    bool qz = q_zero(x);

    q_flag = (qb || ! qz);

    if (q_flag) {
        switch (params.q_mode()) {
          case SC_TRN: // truncation
            {
                if (is_neg())
                    q_incr(x);
                break;
            }
          case SC_RND: // rounding to plus infinity
            {
                if (!is_neg()) {
                    if (qb)
                        q_incr(x);
                } else {
                    if (qb && !qz)
                        q_incr(x);
                }
                break;
            }
          case SC_TRN_ZERO: // truncation to zero
            {
                break;
            }
          case SC_RND_INF: // rounding to infinity
            {
                if (qb)
                    q_incr(x);
                break;
            }
          case SC_RND_CONV: // convergent rounding
            {
                if ((qb && !qz) || (qb && qz && q_odd(x)))
                    q_incr(x);
                break;
            }
          case SC_RND_ZERO: // rounding to zero
            {
                if (qb && !qz)
                    q_incr(x);
                break;
            }
          case SC_RND_MIN_INF: // rounding to minus infinity
            {
                if (!is_neg()) {
                    if (qb && !qz)
                        q_incr(x);
                } else {
                    if (qb)
                        q_incr(x);
                }
                break;
            }
          default:
            ;
        }
        q_clear(x);

        find_sw();
    }
}


// ----------------------------------------------------------------------------
//  PRIVATE METHOD : overflow
//
//  Performs destructive overflow handling.
// ----------------------------------------------------------------------------

void
scfx_rep::overflow(const scfx_params &params, bool &o_flag)
{
    scfx_index x = calc_indices(params.iwl() - 1);

    if (x.wi() >= size())
        resize_to(x.wi() + 1, 1);

    if (x.wi() < 0) {
        resize_to(size() - x.wi(), -1);
        x.wi(0);
    }

    bool zero_left = o_zero_left(x);
    bool bit_at = o_bit_at(x);
    bool zero_right = o_zero_right(x);

    bool under = false;
    bool over = false;

    sc_enc enc = params.enc();

    if (enc == SC_TC_) {
        if (is_neg()) {
            if (params.o_mode() == SC_SAT_SYM)
                under = (!zero_left || bit_at);
            else
                under = (!zero_left || (zero_left && bit_at && ! zero_right));
        } else {
            over = (! zero_left || bit_at);
        }
    } else {
        if (is_neg())
            under = (!is_zero());
        else
            over = (!zero_left);
    }

    o_flag = (under || over);

    if (o_flag) {
        scfx_index x2 = calc_indices(params.iwl() - params.wl());

        if (x2.wi() < 0) {
            resize_to(size() - x2.wi(), -1);
            x.wi(x.wi() - x2.wi());
            x2.wi(0);
        }

        switch (params.o_mode()) {
          case SC_WRAP: // wrap-around
            {
                int n_bits = params.n_bits();

                if (n_bits == 0) {
                    // wrap-around all 'wl' bits
                    toggle_tc();
                    o_extend(x, enc);
                    toggle_tc();
                } else if (n_bits < params.wl()) {
                    scfx_index x3 = calc_indices(params.iwl() - 1 - n_bits);

                    // wrap-around least significant 'wl - n_bits' bits;
                    // saturate most significant 'n_bits' bits
                    toggle_tc();
                    o_set(x, x3, enc, under);
                    o_extend(x, enc);
                    toggle_tc();
                } else {
                    // saturate all 'wl' bits
                    if (under)
                        o_set_low(x, enc);
                    else
                        o_set_high(x, x2, enc);
                }
                break;
            }
          case SC_SAT: // saturation
            {
                if (under)
                    o_set_low(x, enc);
                else
                    o_set_high(x, x2, enc);
                break;
            }
          case SC_SAT_SYM: // symmetrical saturation
            {
                if (under) {
                    if (enc == SC_TC_)
                        o_set_high(x, x2, SC_TC_, -1);
                    else
                        o_set_low(x, SC_US_);
                } else {
                    o_set_high(x, x2, enc);
                }
                break;
            }
          case SC_SAT_ZERO: // saturation to zero
            {
                set_zero();
                break;
            }
          case SC_WRAP_SM: // sign magnitude wrap-around
            {
                SC_ERROR_IF_(enc == SC_US_,
                             "SC_WRAP_SM not defined for unsigned numbers");

                int n_bits = params.n_bits();

                if (n_bits == 0) {
                    scfx_index x4 = calc_indices(params.iwl());

                    if (x4.wi() >= size())
                        resize_to(x4.wi() + 1, 1);

                    toggle_tc();
                    if (o_bit_at(x4) != o_bit_at(x))
                        o_invert(x2);
                    o_extend(x, SC_TC_);
                    toggle_tc();
                } else if (n_bits == 1) {
                    toggle_tc();
                    if (is_neg() != o_bit_at(x))
                        o_invert(x2);
                    o_extend(x, SC_TC_);
                    toggle_tc();
                } else if (n_bits < params.wl()) {
                    scfx_index x3 = calc_indices(params.iwl() - 1 - n_bits);
                    scfx_index x4 = calc_indices(params.iwl() - n_bits);

                    // wrap-around least significant 'wl - n_bits' bits;
                    // saturate most significant 'n_bits' bits
                    toggle_tc();
                    if (is_neg() == o_bit_at(x4))
                        o_invert(x2);
                    o_set(x, x3, SC_TC_, under);
                    o_extend(x, SC_TC_);
                    toggle_tc();
                } else {
                    if (under)
                        o_set_low(x, SC_TC_);
                    else
                        o_set_high(x, x2, SC_TC_);
                }
                break;
            }
          default:
            ;
        }

        find_sw();
    }
}


// ----------------------------------------------------------------------------
//  PUBLIC METHOD : cast
//
//  Performs a destructive cast operation on a scfx_rep.
// ----------------------------------------------------------------------------

void
scfx_rep::cast(const scfx_params &params, bool &q_flag, bool &o_flag)
{
    q_flag = false;
    o_flag = false;

    // check for special cases
    if (is_zero()) {
        if (is_neg())
            m_sign = 1;
        return;
    }

    // perform casting
    quantization(params, q_flag);
    overflow(params, o_flag);

    // check for special case: -0
    if (is_zero() && is_neg())
        m_sign = 1;
}


// ----------------------------------------------------------------------------
//  make sure, the two mantissas are aligned
// ----------------------------------------------------------------------------

void
align(const scfx_rep &lhs, const scfx_rep &rhs, int &new_wp,
      int &len_mant, scfx_mant_ref &lhs_mant, scfx_mant_ref &rhs_mant)
{
    bool need_lhs = true;
    bool need_rhs = true;

    if (lhs.m_wp != rhs.m_wp || lhs.size() != rhs.size()) {
        int lower_bound_lhs = lhs.m_lsw - lhs.m_wp;
        int upper_bound_lhs = lhs.m_msw - lhs.m_wp;
        int lower_bound_rhs = rhs.m_lsw - rhs.m_wp;
        int upper_bound_rhs = rhs.m_msw - rhs.m_wp;

        int lower_bound = sc_min(lower_bound_lhs, lower_bound_rhs);
        int upper_bound = sc_max(upper_bound_lhs, upper_bound_rhs);

        new_wp = -lower_bound;
        len_mant = sc_max(min_mant, upper_bound - lower_bound + 1);

        if (new_wp != lhs.m_wp || len_mant != lhs.size()) {
            lhs_mant = lhs.resize(len_mant, new_wp);
            need_lhs = false;
        }

        if (new_wp != rhs.m_wp || len_mant != rhs.size()) {
            rhs_mant = rhs.resize(len_mant, new_wp);
            need_rhs = false;
        }
    }

    if (need_lhs) {
        lhs_mant = lhs.m_mant;
    }

    if (need_rhs) {
        rhs_mant = rhs.m_mant;
    }
}


// ----------------------------------------------------------------------------
//  compare two mantissas
// ----------------------------------------------------------------------------

int
compare_msw_ff(const scfx_rep &lhs, const scfx_rep &rhs)
{
    // special case: rhs.m_mant[rhs.m_msw + 1] == 1
    if (rhs.m_msw < rhs.size() - 1 && rhs.m_mant[rhs.m_msw + 1 ] != 0) {
        return -1;
    }

    int lhs_size = lhs.m_msw - lhs.m_lsw + 1;
    int rhs_size = rhs.m_msw - rhs.m_lsw + 1;

    int size = sc_min(lhs_size, rhs_size);

    int lhs_index = lhs.m_msw;
    int rhs_index = rhs.m_msw;

    int i;

    for (i = 0;
         i < size && lhs.m_mant[lhs_index] == rhs.m_mant[rhs_index];
         i++) {
        lhs_index--;
        rhs_index--;
    }

    if (i == size) {
        if (lhs_size == rhs_size) {
            return 0;
        }

        if (lhs_size < rhs_size) {
            return -1;
        } else {
            return 1;
        }
    }

    if (lhs.m_mant[lhs_index] < rhs.m_mant[rhs_index]) {
        return -1;
    } else {
        return 1;
    }
}


// ----------------------------------------------------------------------------
//  divide the mantissa by ten
// ----------------------------------------------------------------------------

unsigned int
scfx_rep::divide_by_ten()
{
#if defined(SC_BOOST_BIG_ENDIAN)
    half_word *hw = (half_word *)&m_mant[m_msw];
#elif defined(SC_BOOST_LITTLE_ENDIAN)
    half_word *hw = ((half_word *)&m_mant[m_msw]) + 1;
#endif

    unsigned int remainder = 0;

    word_short ls;
    ls.l = 0;

#if defined(SC_BOOST_BIG_ENDIAN)
    for (int i = 0, end = (m_msw - m_wp + 1) * 2; i < end; i++) {
#elif defined(SC_BOOST_LITTLE_ENDIAN)
    for (int i = 0, end = -(m_msw - m_wp + 1) * 2; i > end; i--) {
#endif
        ls.s.u = static_cast<half_word>(remainder);
        ls.s.l = hw[i];
        remainder = ls.l % 10;
        ls.l /= 10;
        hw[i] = ls.s.l;
    }

    return remainder;
}


// ----------------------------------------------------------------------------
//  multiply the mantissa by ten
// ----------------------------------------------------------------------------

void
scfx_rep::multiply_by_ten()
{
    int size = m_mant.size() + 1;

    scfx_mant mant8(size);
    scfx_mant mant2(size);

    size--;

    mant8[size] = (m_mant[size - 1] >> (bits_in_word - 3));
    mant2[size] = (m_mant[size - 1] >> (bits_in_word - 1));

    while (--size) {
        mant8[size] = (m_mant[size] << 3) |
                      (m_mant[size - 1] >> (bits_in_word - 3));
        mant2[size] = (m_mant[size] << 1) |
                      (m_mant[size - 1] >> (bits_in_word - 1));
    }

    mant8[0] = (m_mant[0] << 3);
    mant2[0] = (m_mant[0] << 1);

    add_mants(m_mant.size(), m_mant, mant8, mant2);
}


// ----------------------------------------------------------------------------
//  normalize
// ----------------------------------------------------------------------------

void
scfx_rep::normalize(int exponent)
{
    int shift = exponent % bits_in_word;
    if (shift < 0) {
        shift += bits_in_word;
    }

    if (shift) {
        shift_left(shift);
    }

    find_sw();

    m_wp = (shift - exponent) / bits_in_word;
}


// ----------------------------------------------------------------------------
//  return a new mantissa that is aligned and resized
// ----------------------------------------------------------------------------

scfx_mant *
scfx_rep::resize(int new_size, int new_wp) const
{
    scfx_mant *result = new scfx_mant(new_size);

    result->clear();

    int shift = new_wp - m_wp;

    for (int j = m_lsw; j <= m_msw; j++) {
        (*result)[j + shift] = m_mant[j];
    }

    return result;
}


// ----------------------------------------------------------------------------
//  set a single bit
// ----------------------------------------------------------------------------

void
scfx_rep::set_bin(int i)
{
    m_mant[i >> 5] |= 1 << (i & 31);
}


// ----------------------------------------------------------------------------
//  set three bits
// ----------------------------------------------------------------------------

void
scfx_rep::set_oct(int i, int n)
{
    if (n & 1) {
        m_mant[i >> 5] |= 1 << (i & 31);
    }
    i++;
    if (n & 2) {
        m_mant[i >> 5] |= 1 << (i & 31);
    }
    i++;
    if (n & 4) {
        m_mant[i >> 5] |= 1 << (i & 31);
    }
}


// ----------------------------------------------------------------------------
//  set four bits
// ----------------------------------------------------------------------------

void
scfx_rep::set_hex(int i, int n)
{
    if (n & 1) {
        m_mant[i >> 5] |= 1 << (i & 31);
    }
    i++;
    if (n & 2) {
        m_mant[i >> 5] |= 1 << (i & 31);
    }
    i++;
    if (n & 4) {
        m_mant[i >> 5] |= 1 << (i & 31);
    }
    i++;
    if (n & 8) {
        m_mant[i >> 5] |= 1 << (i & 31);
    }
}


// ----------------------------------------------------------------------------
//  PRIVATE METHOD : shift_left
//
//  Shifts a scfx_rep to the left by a MAXIMUM of bits_in_word - 1 bits.
// ----------------------------------------------------------------------------

void
scfx_rep::shift_left(int n)
{
    if (n != 0) {
        int shift_left = n;
        int shift_right = bits_in_word - n;

        SC_ASSERT_(!(m_mant[size() - 1] >> shift_right),
                   "shift_left overflow");

        for (int i = size() - 1; i > 0; i--) {
            m_mant[i] = (m_mant[i] << shift_left) |
                        (m_mant[i - 1] >> shift_right);
        }
        m_mant[0] <<= shift_left;
    }
}


// ----------------------------------------------------------------------------
//  PRIVATE METHOD : shift_right
//
//  Shifts a scfx_rep to the right by a MAXIMUM of bits_in_word - 1 bits.
// ----------------------------------------------------------------------------

void
scfx_rep::shift_right(int n)
{
    if (n != 0) {
        int shift_left = bits_in_word - n;
        int shift_right = n;

        SC_ASSERT_(!(m_mant[0] << shift_left), "shift_right overflow");

        for (int i = 0; i < size() - 1; i++) {
            m_mant[i] = (m_mant[i] >> shift_right) |
                        (m_mant[i + 1] << shift_left);
        }
        m_mant[size() - 1] >>= shift_right;
    }
}


// ----------------------------------------------------------------------------
//  METHOD : get_bit
//
//  Tests a bit, in two's complement.
// ----------------------------------------------------------------------------

bool
scfx_rep::get_bit(int i) const
{
    if (!is_normal())
        return false;

    scfx_index x = calc_indices(i);

    if (x.wi() >= size())
        return is_neg();

    if (x.wi() < 0)
        return false;

    const_cast<scfx_rep*>(this)->toggle_tc();

    bool result = (m_mant[x.wi()] & (1 << x.bi())) != 0;

    const_cast<scfx_rep *>(this)->toggle_tc();

    return result;
}


// ----------------------------------------------------------------------------
//  METHOD : set
//
//  Sets a bit, in two's complement, between iwl-1 and -fwl.
// ----------------------------------------------------------------------------

bool
scfx_rep::set(int i, const scfx_params &params)
{
    if (!is_normal())
        return false;

    scfx_index x = calc_indices(i);

    if (x.wi() >= size()) {
        if (is_neg())
            return true;
        else
            resize_to(x.wi() + 1, 1);
    } else if (x.wi() < 0) {
        resize_to(size() - x.wi(), -1);
        x.wi(0);
    }

    toggle_tc();

    m_mant[x.wi()] |= 1 << x.bi();

    if (i == params.iwl() - 1)
        o_extend(x, params.enc()); // sign extension

    toggle_tc();

    find_sw();

    return true;
}


// ----------------------------------------------------------------------------
//  METHOD : clear
//
//  Clears a bit, in two's complement, between iwl-1 and -fwl.
// ----------------------------------------------------------------------------

bool
scfx_rep::clear(int i, const scfx_params &params)
{
    if (!is_normal())
        return false;

    scfx_index x = calc_indices(i);

    if (x.wi() >= size()) {
        if (!is_neg())
            return true;
        else
            resize_to(x.wi() + 1, 1);
    } else if (x.wi() < 0) {
        return true;
    }

    toggle_tc();

    m_mant[x.wi()] &= ~(1 << x.bi());

    if (i == params.iwl() - 1)
        o_extend(x, params.enc()); // sign extension

    toggle_tc();

    find_sw();

    return true;
}


// ----------------------------------------------------------------------------
//  METHOD : get_slice
// ----------------------------------------------------------------------------

bool
scfx_rep::get_slice(int i, int j, const scfx_params &, sc_bv_base &bv) const
{
    if (is_nan() || is_inf())
        return false;

    // get the bits

    int l = j;
    for (int k = 0; k < bv.length(); ++k) {
        bv[k] = get_bit(l);

        if (i >= j)
            ++l;
        else
            --l;
    }

    return true;
}

bool
scfx_rep::set_slice(int i, int j, const scfx_params &params,
                    const sc_bv_base &bv)
{
    if (is_nan() || is_inf())
        return false;

    // set the bits
    int l = j;
    for (int k = 0; k < bv.length(); ++k) {
        if (bv[k].to_bool())
            set(l, params);
        else
            clear(l, params);

        if (i >= j)
            ++l;
        else
            --l;
    }

    return true;
}


// ----------------------------------------------------------------------------
//  METHOD : print
// ----------------------------------------------------------------------------

void
scfx_rep::print(::std::ostream &os) const
{
    os << to_string(SC_DEC, -1, SC_E);
}


// ----------------------------------------------------------------------------
//  METHOD : dump
// ----------------------------------------------------------------------------

void
scfx_rep::dump(::std::ostream &os) const
{
    os << "scfx_rep" << ::std::endl;
    os << "(" << ::std::endl;

    os << "mant  =" << ::std::endl;
    for (int i = size() - 1; i >= 0; i--) {
        char buf[BUFSIZ];
        std::sprintf(buf, " %d: %10u (%8x)", i,
                     (int)m_mant[i], (int)m_mant[i]);
        os << buf << ::std::endl;
    }

    os << "wp = " << m_wp << ::std::endl;
    os << "sign = " << m_sign << ::std::endl;

    os << "state = ";
    switch (m_state) {
      case normal:
        os << "normal";
        break;
      case infinity:
        os << "infinity";
        break;
      case not_a_number:
        os << "not_a_number";
        break;
      default:
        os << "unknown";
    }
    os << ::std::endl;

    os << "msw = " << m_msw << ::std::endl;
    os << "lsw = " << m_lsw << ::std::endl;

    os << ")" << ::std::endl;
}


// ----------------------------------------------------------------------------
//  METHOD : get_type
// ----------------------------------------------------------------------------

void
scfx_rep::get_type(int &wl, int &iwl, sc_enc &enc) const
{
    if (is_nan() || is_inf()) {
        wl  = 0;
        iwl = 0;
        enc = SC_TC_;
        return;
    }

    if (is_zero()) {
        wl  = 1;
        iwl = 1;
        enc = SC_US_;
        return;
    }

    int msb = (m_msw - m_wp) * bits_in_word +
              scfx_find_msb(m_mant[ m_msw ]) + 1;
    while (get_bit(msb) == get_bit(msb - 1)) {
        --msb;
    }

    int lsb = (m_lsw - m_wp) * bits_in_word +
              scfx_find_lsb(m_mant[m_lsw]);

    if (is_neg()) {
        wl  = msb - lsb + 1;
        iwl = msb + 1;
        enc = SC_TC_;
    } else {
        wl  = msb - lsb;
        iwl = msb;
        enc = SC_US_;
    }
}


// ----------------------------------------------------------------------------
//  PRIVATE METHOD : round
//
//  Performs convergent rounding (rounding to even) as in floating-point.
// ----------------------------------------------------------------------------

void
scfx_rep::round(int wl)
{
    // check for special cases

    if (is_nan() || is_inf() || is_zero())
        return;

    // estimate effective wordlength and compare
    int wl_effective;
    wl_effective = (m_msw - m_lsw + 1) * bits_in_word;
    if (wl_effective <= wl)
        return;

    // calculate effective wordlength and compare
    int msb = scfx_find_msb(m_mant[m_msw]);
    int lsb = scfx_find_lsb(m_mant[m_lsw]);
    wl_effective = (m_msw * bits_in_word + msb) -
                   (m_lsw * bits_in_word + lsb) + 1;
    if (wl_effective <= wl)
        return;

    // perform rounding
    int wi = m_msw - (wl - 1) / bits_in_word;
    int bi = msb - (wl - 1) % bits_in_word;
    if (bi < 0) {
        --wi;
        bi += bits_in_word;
    }

    scfx_index x(wi, bi);

    if ((q_bit(x) && ! q_zero(x)) || (q_bit(x) && q_zero(x) && q_odd(x))) {
        q_incr(x);
    }
    q_clear(x);

    find_sw();

    m_r_flag = true;
}

} // namespace sc_dt
