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

  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"

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 defined(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 defined(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("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
