112027Sjungma@eit.uni-kl.de/*****************************************************************************
212027Sjungma@eit.uni-kl.de
312027Sjungma@eit.uni-kl.de  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
412027Sjungma@eit.uni-kl.de  more contributor license agreements.  See the NOTICE file distributed
512027Sjungma@eit.uni-kl.de  with this work for additional information regarding copyright ownership.
612027Sjungma@eit.uni-kl.de  Accellera licenses this file to you under the Apache License, Version 2.0
712027Sjungma@eit.uni-kl.de  (the "License"); you may not use this file except in compliance with the
812027Sjungma@eit.uni-kl.de  License.  You may obtain a copy of the License at
912027Sjungma@eit.uni-kl.de
1012027Sjungma@eit.uni-kl.de    http://www.apache.org/licenses/LICENSE-2.0
1112027Sjungma@eit.uni-kl.de
1212027Sjungma@eit.uni-kl.de  Unless required by applicable law or agreed to in writing, software
1312027Sjungma@eit.uni-kl.de  distributed under the License is distributed on an "AS IS" BASIS,
1412027Sjungma@eit.uni-kl.de  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
1512027Sjungma@eit.uni-kl.de  implied.  See the License for the specific language governing
1612027Sjungma@eit.uni-kl.de  permissions and limitations under the License.
1712027Sjungma@eit.uni-kl.de
1812027Sjungma@eit.uni-kl.de *****************************************************************************/
1912027Sjungma@eit.uni-kl.de
2012027Sjungma@eit.uni-kl.de/*****************************************************************************
2112027Sjungma@eit.uni-kl.de
2212027Sjungma@eit.uni-kl.de  scfx_rep.cpp -
2312027Sjungma@eit.uni-kl.de
2412027Sjungma@eit.uni-kl.de  Original Author: Robert Graulich, Synopsys, Inc.
2512027Sjungma@eit.uni-kl.de                   Martin Janssen,  Synopsys, Inc.
2612027Sjungma@eit.uni-kl.de
2712027Sjungma@eit.uni-kl.de *****************************************************************************/
2812027Sjungma@eit.uni-kl.de
2912027Sjungma@eit.uni-kl.de/*****************************************************************************
3012027Sjungma@eit.uni-kl.de
3112027Sjungma@eit.uni-kl.de  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
3212027Sjungma@eit.uni-kl.de  changes you are making here.
3312027Sjungma@eit.uni-kl.de
3412027Sjungma@eit.uni-kl.de      Name, Affiliation, Date:
3512027Sjungma@eit.uni-kl.de  Description of Modification:
3612027Sjungma@eit.uni-kl.de
3712027Sjungma@eit.uni-kl.de *****************************************************************************/
3812027Sjungma@eit.uni-kl.de
3912027Sjungma@eit.uni-kl.de
4012027Sjungma@eit.uni-kl.de// $Log: scfx_rep.cpp,v $
4112027Sjungma@eit.uni-kl.de// Revision 1.4  2011/08/24 22:05:43  acg
4212027Sjungma@eit.uni-kl.de//  Torsten Maehne: initialization changes to remove warnings.
4312027Sjungma@eit.uni-kl.de//
4412027Sjungma@eit.uni-kl.de// Revision 1.3  2011/08/15 16:43:24  acg
4512027Sjungma@eit.uni-kl.de//  Torsten Maehne: changes to remove unused argument warnings.
4612027Sjungma@eit.uni-kl.de//
4712027Sjungma@eit.uni-kl.de// Revision 1.2  2009/02/28 00:26:20  acg
4812027Sjungma@eit.uni-kl.de//  Andy Goodrich: bug fixes.
4912027Sjungma@eit.uni-kl.de//
5012027Sjungma@eit.uni-kl.de// Revision 1.2  2008/11/06 17:22:47  acg
5112027Sjungma@eit.uni-kl.de//  Andy Goodrich: bug fixes for 2.2.1.
5212027Sjungma@eit.uni-kl.de//
5312027Sjungma@eit.uni-kl.de// Revision 1.1.1.1  2006/12/15 20:31:36  acg
5412027Sjungma@eit.uni-kl.de// SystemC 2.2
5512027Sjungma@eit.uni-kl.de//
5612027Sjungma@eit.uni-kl.de// Revision 1.3  2006/01/13 18:53:58  acg
5712027Sjungma@eit.uni-kl.de// Andy Goodrich: added $Log command so that CVS comments are reproduced in
5812027Sjungma@eit.uni-kl.de// the source.
5912027Sjungma@eit.uni-kl.de//
6012027Sjungma@eit.uni-kl.de
6112027Sjungma@eit.uni-kl.de#include "sysc/utils/sc_machine.h"
6212027Sjungma@eit.uni-kl.de#include "sysc/datatypes/fx/scfx_rep.h"
6312027Sjungma@eit.uni-kl.de
6412027Sjungma@eit.uni-kl.de#include "sysc/datatypes/fx/scfx_ieee.h"
6512027Sjungma@eit.uni-kl.de#include "sysc/datatypes/fx/scfx_pow10.h"
6612027Sjungma@eit.uni-kl.de#include "sysc/datatypes/fx/scfx_utils.h"
6712027Sjungma@eit.uni-kl.de
6812027Sjungma@eit.uni-kl.de#include "sysc/datatypes/bit/sc_bv_base.h"
6912027Sjungma@eit.uni-kl.de
7012027Sjungma@eit.uni-kl.de#include <ctype.h>
7112027Sjungma@eit.uni-kl.de#include <cstdio>
7212027Sjungma@eit.uni-kl.de#include <stdlib.h>
7312027Sjungma@eit.uni-kl.de#include <math.h>
7412027Sjungma@eit.uni-kl.de
7512027Sjungma@eit.uni-kl.de
7612027Sjungma@eit.uni-kl.denamespace sc_dt
7712027Sjungma@eit.uni-kl.de{
7812027Sjungma@eit.uni-kl.de
7912027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
8012027Sjungma@eit.uni-kl.de//  some utilities
8112027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
8212027Sjungma@eit.uni-kl.de
8312027Sjungma@eit.uni-kl.destatic scfx_pow10 pow10_fx;
8412027Sjungma@eit.uni-kl.de
8512027Sjungma@eit.uni-kl.destatic const int mantissa0_size = SCFX_IEEE_DOUBLE_M_SIZE - bits_in_int;
8612027Sjungma@eit.uni-kl.de
8712027Sjungma@eit.uni-kl.destatic inline
8812027Sjungma@eit.uni-kl.deint
8912027Sjungma@eit.uni-kl.den_word( int x )
9012027Sjungma@eit.uni-kl.de{
9112027Sjungma@eit.uni-kl.de    return ( x + bits_in_word - 1 ) / bits_in_word;
9212027Sjungma@eit.uni-kl.de}
9312027Sjungma@eit.uni-kl.de
9412027Sjungma@eit.uni-kl.de
9512027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
9612027Sjungma@eit.uni-kl.de//  CONSTRUCTORS
9712027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
9812027Sjungma@eit.uni-kl.de
9912027Sjungma@eit.uni-kl.descfx_rep::scfx_rep()
10012027Sjungma@eit.uni-kl.de: m_mant( min_mant ), m_wp(), m_sign(), m_state(), m_msw(), m_lsw(),
10112027Sjungma@eit.uni-kl.de  m_r_flag( false )
10212027Sjungma@eit.uni-kl.de{
10312027Sjungma@eit.uni-kl.de    set_zero();
10412027Sjungma@eit.uni-kl.de}
10512027Sjungma@eit.uni-kl.de
10612027Sjungma@eit.uni-kl.descfx_rep::scfx_rep( int a )
10712027Sjungma@eit.uni-kl.de: m_mant( min_mant ), m_wp(), m_sign(), m_state(), m_msw(), m_lsw(),
10812027Sjungma@eit.uni-kl.de  m_r_flag( false )
10912027Sjungma@eit.uni-kl.de{
11012027Sjungma@eit.uni-kl.de    if( a != 0 )
11112027Sjungma@eit.uni-kl.de    {
11212027Sjungma@eit.uni-kl.de        m_mant.clear();
11312027Sjungma@eit.uni-kl.de	m_wp = m_msw = m_lsw = 2;
11412027Sjungma@eit.uni-kl.de	m_state = normal;
11512027Sjungma@eit.uni-kl.de	if( a > 0 )
11612027Sjungma@eit.uni-kl.de	{
11712027Sjungma@eit.uni-kl.de	    m_mant[2] = a;
11812027Sjungma@eit.uni-kl.de	    m_sign = 1;
11912027Sjungma@eit.uni-kl.de	}
12012027Sjungma@eit.uni-kl.de	else
12112027Sjungma@eit.uni-kl.de	{
12212027Sjungma@eit.uni-kl.de	    m_mant[2] = -a;
12312027Sjungma@eit.uni-kl.de	    m_sign = -1;
12412027Sjungma@eit.uni-kl.de	}
12512027Sjungma@eit.uni-kl.de    }
12612027Sjungma@eit.uni-kl.de    else
12712027Sjungma@eit.uni-kl.de        set_zero();
12812027Sjungma@eit.uni-kl.de}
12912027Sjungma@eit.uni-kl.de
13012027Sjungma@eit.uni-kl.descfx_rep::scfx_rep( unsigned int a )
13112027Sjungma@eit.uni-kl.de: m_mant( min_mant ), m_wp(), m_sign(), m_state(), m_msw(), m_lsw(),
13212027Sjungma@eit.uni-kl.de  m_r_flag( false )
13312027Sjungma@eit.uni-kl.de{
13412027Sjungma@eit.uni-kl.de    if( a != 0 )
13512027Sjungma@eit.uni-kl.de    {
13612027Sjungma@eit.uni-kl.de        m_mant.clear();
13712027Sjungma@eit.uni-kl.de	m_wp = m_msw = m_lsw = 2;
13812027Sjungma@eit.uni-kl.de	m_state = normal;
13912027Sjungma@eit.uni-kl.de	m_mant[2] = a;
14012027Sjungma@eit.uni-kl.de	m_sign = 1;
14112027Sjungma@eit.uni-kl.de    }
14212027Sjungma@eit.uni-kl.de    else
14312027Sjungma@eit.uni-kl.de        set_zero();
14412027Sjungma@eit.uni-kl.de}
14512027Sjungma@eit.uni-kl.de
14612027Sjungma@eit.uni-kl.descfx_rep::scfx_rep( long a )
14712027Sjungma@eit.uni-kl.de: m_mant( min_mant ), m_wp(), m_sign(), m_state(), m_msw(), m_lsw(),
14812027Sjungma@eit.uni-kl.de  m_r_flag( false )
14912027Sjungma@eit.uni-kl.de{
15012027Sjungma@eit.uni-kl.de    if( a != 0 )
15112027Sjungma@eit.uni-kl.de    {
15212027Sjungma@eit.uni-kl.de        m_mant.clear();
15312027Sjungma@eit.uni-kl.de	m_state = normal;
15412027Sjungma@eit.uni-kl.de        if ( a > 0 )
15512027Sjungma@eit.uni-kl.de        {
15612027Sjungma@eit.uni-kl.de	    m_sign = 1;
15712027Sjungma@eit.uni-kl.de        }
15812027Sjungma@eit.uni-kl.de        else
15912027Sjungma@eit.uni-kl.de        {
16012027Sjungma@eit.uni-kl.de            a = -a;
16112027Sjungma@eit.uni-kl.de            m_sign = -1;
16212027Sjungma@eit.uni-kl.de        }
16312027Sjungma@eit.uni-kl.de#       if defined(SC_LONG_64)
16412027Sjungma@eit.uni-kl.de            m_wp = 1;
16512027Sjungma@eit.uni-kl.de            m_mant[1] = static_cast<word>( a );
16612027Sjungma@eit.uni-kl.de            m_mant[2] = static_cast<word>( a >> bits_in_word );
16712027Sjungma@eit.uni-kl.de	    find_sw();
16812027Sjungma@eit.uni-kl.de#       else
16912027Sjungma@eit.uni-kl.de            m_wp = 2;
17012027Sjungma@eit.uni-kl.de            m_msw = 2;
17112027Sjungma@eit.uni-kl.de            m_lsw = 2;
17212027Sjungma@eit.uni-kl.de            m_mant[2] = a;
17312027Sjungma@eit.uni-kl.de#       endif
17412027Sjungma@eit.uni-kl.de
17512027Sjungma@eit.uni-kl.de    }
17612027Sjungma@eit.uni-kl.de    else
17712027Sjungma@eit.uni-kl.de        set_zero();
17812027Sjungma@eit.uni-kl.de}
17912027Sjungma@eit.uni-kl.de
18012027Sjungma@eit.uni-kl.descfx_rep::scfx_rep( unsigned long a )
18112027Sjungma@eit.uni-kl.de: m_mant( min_mant ), m_wp(), m_sign(), m_state(), m_msw(), m_lsw(),
18212027Sjungma@eit.uni-kl.de  m_r_flag( false )
18312027Sjungma@eit.uni-kl.de{
18412027Sjungma@eit.uni-kl.de    if( a != 0 )
18512027Sjungma@eit.uni-kl.de    {
18612027Sjungma@eit.uni-kl.de        m_mant.clear();
18712027Sjungma@eit.uni-kl.de	m_wp = m_msw = m_lsw = 2;
18812027Sjungma@eit.uni-kl.de	m_state = normal;
18912027Sjungma@eit.uni-kl.de#       if defined(SC_LONG_64)
19012027Sjungma@eit.uni-kl.de	    m_wp = 1;
19112027Sjungma@eit.uni-kl.de	    m_mant[1] = static_cast<word>( a );
19212027Sjungma@eit.uni-kl.de	    m_mant[2] = static_cast<word>( a >> bits_in_word );
19312027Sjungma@eit.uni-kl.de	    find_sw();
19412027Sjungma@eit.uni-kl.de#       else
19512027Sjungma@eit.uni-kl.de	    m_wp = 2;
19612027Sjungma@eit.uni-kl.de	    m_msw = 2;
19712027Sjungma@eit.uni-kl.de	    m_lsw = 2;
19812027Sjungma@eit.uni-kl.de	    m_mant[2] = a;
19912027Sjungma@eit.uni-kl.de#	endif
20012027Sjungma@eit.uni-kl.de	m_sign = 1;
20112027Sjungma@eit.uni-kl.de    }
20212027Sjungma@eit.uni-kl.de    else
20312027Sjungma@eit.uni-kl.de        set_zero();
20412027Sjungma@eit.uni-kl.de}
20512027Sjungma@eit.uni-kl.de
20612027Sjungma@eit.uni-kl.descfx_rep::scfx_rep( double a )
20712027Sjungma@eit.uni-kl.de: m_mant( min_mant ), m_wp( 0 ), m_sign(), m_state( normal ), m_msw( 0 ),
20812027Sjungma@eit.uni-kl.de  m_lsw( 0 ), m_r_flag( false )
20912027Sjungma@eit.uni-kl.de{
21012027Sjungma@eit.uni-kl.de    m_mant.clear();
21112027Sjungma@eit.uni-kl.de
21212027Sjungma@eit.uni-kl.de    scfx_ieee_double id( a );
21312027Sjungma@eit.uni-kl.de
21412027Sjungma@eit.uni-kl.de    m_sign = id.negative() ? -1 : 1;
21512027Sjungma@eit.uni-kl.de
21612027Sjungma@eit.uni-kl.de    if( id.is_nan() )
21712027Sjungma@eit.uni-kl.de        m_state = not_a_number;
21812027Sjungma@eit.uni-kl.de    else if( id.is_inf() )
21912027Sjungma@eit.uni-kl.de        m_state = infinity;
22012027Sjungma@eit.uni-kl.de    else if( id.is_subnormal() )
22112027Sjungma@eit.uni-kl.de    {
22212027Sjungma@eit.uni-kl.de	m_mant[0] = id.mantissa1();
22312027Sjungma@eit.uni-kl.de	m_mant[1] = id.mantissa0();
22412027Sjungma@eit.uni-kl.de	normalize( id.exponent() + 1 - SCFX_IEEE_DOUBLE_M_SIZE );
22512027Sjungma@eit.uni-kl.de    }
22612027Sjungma@eit.uni-kl.de    else if( id.is_normal() )
22712027Sjungma@eit.uni-kl.de    {
22812027Sjungma@eit.uni-kl.de	m_mant[0] = id.mantissa1();
22912027Sjungma@eit.uni-kl.de	m_mant[1] = id.mantissa0() | ( 1 << mantissa0_size );
23012027Sjungma@eit.uni-kl.de	normalize( id.exponent() - SCFX_IEEE_DOUBLE_M_SIZE );
23112027Sjungma@eit.uni-kl.de    }
23212027Sjungma@eit.uni-kl.de}
23312027Sjungma@eit.uni-kl.de
23412027Sjungma@eit.uni-kl.descfx_rep::scfx_rep( int64 a )
23512027Sjungma@eit.uni-kl.de: m_mant( min_mant ), m_wp(), m_sign(), m_state(), m_msw(), m_lsw(),
23612027Sjungma@eit.uni-kl.de  m_r_flag( false )
23712027Sjungma@eit.uni-kl.de{
23812027Sjungma@eit.uni-kl.de    if( a != 0 )
23912027Sjungma@eit.uni-kl.de    {
24012027Sjungma@eit.uni-kl.de        m_mant.clear();
24112027Sjungma@eit.uni-kl.de	m_wp = 1;
24212027Sjungma@eit.uni-kl.de	m_state = normal;
24312027Sjungma@eit.uni-kl.de	if( a > 0 )
24412027Sjungma@eit.uni-kl.de	{
24512027Sjungma@eit.uni-kl.de	    m_mant[1] = static_cast<word>( a );
24612027Sjungma@eit.uni-kl.de	    m_mant[2] = static_cast<word>( a >> bits_in_word );
24712027Sjungma@eit.uni-kl.de	    m_sign = 1;
24812027Sjungma@eit.uni-kl.de	}
24912027Sjungma@eit.uni-kl.de	else
25012027Sjungma@eit.uni-kl.de	{
25112027Sjungma@eit.uni-kl.de	    m_mant[1] = static_cast<word>( -a );
25212027Sjungma@eit.uni-kl.de	    m_mant[2] = static_cast<word>( (-a) >> bits_in_word );
25312027Sjungma@eit.uni-kl.de	    m_sign = -1;
25412027Sjungma@eit.uni-kl.de	}
25512027Sjungma@eit.uni-kl.de	find_sw();
25612027Sjungma@eit.uni-kl.de    }
25712027Sjungma@eit.uni-kl.de    else
25812027Sjungma@eit.uni-kl.de        set_zero();
25912027Sjungma@eit.uni-kl.de}
26012027Sjungma@eit.uni-kl.de
26112027Sjungma@eit.uni-kl.descfx_rep::scfx_rep( uint64 a )
26212027Sjungma@eit.uni-kl.de: m_mant( min_mant ), m_wp(), m_sign(), m_state(), m_msw(), m_lsw(),
26312027Sjungma@eit.uni-kl.de  m_r_flag( false )
26412027Sjungma@eit.uni-kl.de{
26512027Sjungma@eit.uni-kl.de    if( a != 0 )
26612027Sjungma@eit.uni-kl.de    {
26712027Sjungma@eit.uni-kl.de        m_mant.clear();
26812027Sjungma@eit.uni-kl.de	m_wp = 1;
26912027Sjungma@eit.uni-kl.de	m_state = normal;
27012027Sjungma@eit.uni-kl.de	m_mant[1] = static_cast<word>( a );
27112027Sjungma@eit.uni-kl.de	m_mant[2] = static_cast<word>( a >> bits_in_word );
27212027Sjungma@eit.uni-kl.de	m_sign = 1;
27312027Sjungma@eit.uni-kl.de	find_sw();
27412027Sjungma@eit.uni-kl.de    }
27512027Sjungma@eit.uni-kl.de    else
27612027Sjungma@eit.uni-kl.de        set_zero();
27712027Sjungma@eit.uni-kl.de}
27812027Sjungma@eit.uni-kl.de
27912027Sjungma@eit.uni-kl.descfx_rep::scfx_rep( const sc_signed& a )
28012027Sjungma@eit.uni-kl.de: m_mant( min_mant ), m_wp(), m_sign(), m_state(), m_msw(), m_lsw(),
28112027Sjungma@eit.uni-kl.de  m_r_flag( false )
28212027Sjungma@eit.uni-kl.de{
28312027Sjungma@eit.uni-kl.de    if( a.iszero() )
28412027Sjungma@eit.uni-kl.de	set_zero();
28512027Sjungma@eit.uni-kl.de    else
28612027Sjungma@eit.uni-kl.de    {
28712027Sjungma@eit.uni-kl.de	int words = n_word( a.length() );
28812027Sjungma@eit.uni-kl.de	if( words > size() )
28912027Sjungma@eit.uni-kl.de	    resize_to( words );
29012027Sjungma@eit.uni-kl.de	m_mant.clear();
29112027Sjungma@eit.uni-kl.de	m_wp = 0;
29212027Sjungma@eit.uni-kl.de	m_state = normal;
29312027Sjungma@eit.uni-kl.de	if( a.sign() )
29412027Sjungma@eit.uni-kl.de	{
29512027Sjungma@eit.uni-kl.de	    sc_signed a2 = -a;
29612027Sjungma@eit.uni-kl.de	    for( int i = 0; i < a2.length(); ++ i )
29712027Sjungma@eit.uni-kl.de	    {
29812027Sjungma@eit.uni-kl.de		if( a2[i] )
29912027Sjungma@eit.uni-kl.de		{
30012027Sjungma@eit.uni-kl.de		    scfx_index x = calc_indices( i );
30112027Sjungma@eit.uni-kl.de		    m_mant[x.wi()] |= 1 << x.bi();
30212027Sjungma@eit.uni-kl.de		}
30312027Sjungma@eit.uni-kl.de	    }
30412027Sjungma@eit.uni-kl.de	    m_sign = -1;
30512027Sjungma@eit.uni-kl.de	}
30612027Sjungma@eit.uni-kl.de	else
30712027Sjungma@eit.uni-kl.de	{
30812027Sjungma@eit.uni-kl.de	    for( int i = 0; i < a.length(); ++ i )
30912027Sjungma@eit.uni-kl.de	    {
31012027Sjungma@eit.uni-kl.de		if( a[i] )
31112027Sjungma@eit.uni-kl.de		{
31212027Sjungma@eit.uni-kl.de		    scfx_index x = calc_indices( i );
31312027Sjungma@eit.uni-kl.de		    m_mant[x.wi()] |= 1 << x.bi();
31412027Sjungma@eit.uni-kl.de		}
31512027Sjungma@eit.uni-kl.de	    }
31612027Sjungma@eit.uni-kl.de	    m_sign = 1;
31712027Sjungma@eit.uni-kl.de	}
31812027Sjungma@eit.uni-kl.de	find_sw();
31912027Sjungma@eit.uni-kl.de    }
32012027Sjungma@eit.uni-kl.de}
32112027Sjungma@eit.uni-kl.de
32212027Sjungma@eit.uni-kl.descfx_rep::scfx_rep( const sc_unsigned& a )
32312027Sjungma@eit.uni-kl.de: m_mant( min_mant ), m_wp(), m_sign(), m_state(), m_msw(), m_lsw(),
32412027Sjungma@eit.uni-kl.de  m_r_flag( false )
32512027Sjungma@eit.uni-kl.de{
32612027Sjungma@eit.uni-kl.de    if( a.iszero() )
32712027Sjungma@eit.uni-kl.de	set_zero();
32812027Sjungma@eit.uni-kl.de    else
32912027Sjungma@eit.uni-kl.de    {
33012027Sjungma@eit.uni-kl.de	int words = n_word( a.length() );
33112027Sjungma@eit.uni-kl.de	if( words > size() )
33212027Sjungma@eit.uni-kl.de	    resize_to( words );
33312027Sjungma@eit.uni-kl.de	m_mant.clear();
33412027Sjungma@eit.uni-kl.de	m_wp = 0;
33512027Sjungma@eit.uni-kl.de	m_state = normal;
33612027Sjungma@eit.uni-kl.de	for( int i = 0; i < a.length(); ++ i )
33712027Sjungma@eit.uni-kl.de	{
33812027Sjungma@eit.uni-kl.de	    if( a[i] )
33912027Sjungma@eit.uni-kl.de	    {
34012027Sjungma@eit.uni-kl.de		scfx_index x = calc_indices( i );
34112027Sjungma@eit.uni-kl.de		m_mant[x.wi()] |= 1 << x.bi();
34212027Sjungma@eit.uni-kl.de	    }
34312027Sjungma@eit.uni-kl.de	}
34412027Sjungma@eit.uni-kl.de	m_sign = 1;
34512027Sjungma@eit.uni-kl.de	find_sw();
34612027Sjungma@eit.uni-kl.de    }
34712027Sjungma@eit.uni-kl.de}
34812027Sjungma@eit.uni-kl.de
34912027Sjungma@eit.uni-kl.de
35012027Sjungma@eit.uni-kl.de// copy constructor
35112027Sjungma@eit.uni-kl.de
35212027Sjungma@eit.uni-kl.descfx_rep::scfx_rep( const scfx_rep& a )
35312027Sjungma@eit.uni-kl.de: m_mant( a.m_mant ), m_wp( a.m_wp ), m_sign( a.m_sign ), m_state( a.m_state ),
35412027Sjungma@eit.uni-kl.de  m_msw( a.m_msw ), m_lsw( a.m_lsw ), m_r_flag( false )
35512027Sjungma@eit.uni-kl.de{}
35612027Sjungma@eit.uni-kl.de
35712027Sjungma@eit.uni-kl.de
35812027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
35912027Sjungma@eit.uni-kl.de//  OPERATORS : new, delete
36012027Sjungma@eit.uni-kl.de//
36112027Sjungma@eit.uni-kl.de//  Memory management for class scfx_rep.
36212027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
36312027Sjungma@eit.uni-kl.de
36412027Sjungma@eit.uni-kl.deunion scfx_rep_node
36512027Sjungma@eit.uni-kl.de{
36612027Sjungma@eit.uni-kl.de    char           data[sizeof( scfx_rep )];
36712027Sjungma@eit.uni-kl.de    scfx_rep_node* next;
36812027Sjungma@eit.uni-kl.de};
36912027Sjungma@eit.uni-kl.de
37012027Sjungma@eit.uni-kl.de
37112027Sjungma@eit.uni-kl.destatic scfx_rep_node* list = 0;
37212027Sjungma@eit.uni-kl.de
37312027Sjungma@eit.uni-kl.de
37412027Sjungma@eit.uni-kl.devoid*
37512027Sjungma@eit.uni-kl.descfx_rep::operator new( std::size_t size )
37612027Sjungma@eit.uni-kl.de{
37712027Sjungma@eit.uni-kl.de    const int ALLOC_SIZE = 1024;
37812027Sjungma@eit.uni-kl.de
37912027Sjungma@eit.uni-kl.de    if( size != sizeof( scfx_rep ) )
38012027Sjungma@eit.uni-kl.de	return ::operator new( size );
38112027Sjungma@eit.uni-kl.de
38212027Sjungma@eit.uni-kl.de    if( ! list )
38312027Sjungma@eit.uni-kl.de    {
38412027Sjungma@eit.uni-kl.de	list = new scfx_rep_node[ALLOC_SIZE];
38512027Sjungma@eit.uni-kl.de	for( int i = 0; i < ALLOC_SIZE - 1; i ++ )
38612027Sjungma@eit.uni-kl.de	    list[i].next = list + i + 1;
38712027Sjungma@eit.uni-kl.de	list[ALLOC_SIZE - 1].next = 0;
38812027Sjungma@eit.uni-kl.de    }
38912027Sjungma@eit.uni-kl.de
39012027Sjungma@eit.uni-kl.de    scfx_rep* ptr = reinterpret_cast<scfx_rep*>( list->data );
39112027Sjungma@eit.uni-kl.de    list = list->next;
39212027Sjungma@eit.uni-kl.de
39312027Sjungma@eit.uni-kl.de    return ptr;
39412027Sjungma@eit.uni-kl.de}
39512027Sjungma@eit.uni-kl.de
39612027Sjungma@eit.uni-kl.de
39712027Sjungma@eit.uni-kl.devoid scfx_rep::operator delete( void* ptr, std::size_t size )
39812027Sjungma@eit.uni-kl.de{
39912027Sjungma@eit.uni-kl.de    if( size != sizeof( scfx_rep ) )
40012027Sjungma@eit.uni-kl.de    {
40112027Sjungma@eit.uni-kl.de	::operator delete( ptr );
40212027Sjungma@eit.uni-kl.de	return;
40312027Sjungma@eit.uni-kl.de    }
40412027Sjungma@eit.uni-kl.de
40512027Sjungma@eit.uni-kl.de    scfx_rep_node* node = static_cast<scfx_rep_node*>( ptr );
40612027Sjungma@eit.uni-kl.de    node->next = list;
40712027Sjungma@eit.uni-kl.de    list = node;
40812027Sjungma@eit.uni-kl.de}
40912027Sjungma@eit.uni-kl.de
41012027Sjungma@eit.uni-kl.de
41112027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
41212027Sjungma@eit.uni-kl.de//  METHOD : from_string
41312027Sjungma@eit.uni-kl.de//
41412027Sjungma@eit.uni-kl.de//  Convert from character string to sc_fxrep.
41512027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
41612027Sjungma@eit.uni-kl.de
41712027Sjungma@eit.uni-kl.de#define SCFX_FAIL_IF_(cnd)                                                    \
41812027Sjungma@eit.uni-kl.de{                                                                             \
41912027Sjungma@eit.uni-kl.de    if( ( cnd ) )                                                             \
42012027Sjungma@eit.uni-kl.de    {                                                                         \
42112027Sjungma@eit.uni-kl.de        m_state = not_a_number;                                               \
42212027Sjungma@eit.uni-kl.de	m_mant.clear(); /* to avoid Purify UMRs during assignment */          \
42312027Sjungma@eit.uni-kl.de        return;                                                               \
42412027Sjungma@eit.uni-kl.de    }                                                                         \
42512027Sjungma@eit.uni-kl.de}
42612027Sjungma@eit.uni-kl.de
42712027Sjungma@eit.uni-kl.de
42812027Sjungma@eit.uni-kl.devoid
42912027Sjungma@eit.uni-kl.descfx_rep::from_string( const char* s, int cte_wl )
43012027Sjungma@eit.uni-kl.de{
43112027Sjungma@eit.uni-kl.de    SCFX_FAIL_IF_( s == 0 || *s == 0 );
43212027Sjungma@eit.uni-kl.de
43312027Sjungma@eit.uni-kl.de    scfx_string s2;
43412027Sjungma@eit.uni-kl.de    s2 += s;
43512027Sjungma@eit.uni-kl.de    s2 += '\0';
43612027Sjungma@eit.uni-kl.de
43712027Sjungma@eit.uni-kl.de    bool sign_char;
43812027Sjungma@eit.uni-kl.de    m_sign = scfx_parse_sign( s, sign_char );
43912027Sjungma@eit.uni-kl.de
44012027Sjungma@eit.uni-kl.de    sc_numrep numrep = scfx_parse_prefix( s );
44112027Sjungma@eit.uni-kl.de
44212027Sjungma@eit.uni-kl.de    int base = 0;
44312027Sjungma@eit.uni-kl.de
44412027Sjungma@eit.uni-kl.de    switch( numrep )
44512027Sjungma@eit.uni-kl.de    {
44612027Sjungma@eit.uni-kl.de	case SC_DEC:
44712027Sjungma@eit.uni-kl.de	{
44812027Sjungma@eit.uni-kl.de	    base = 10;
44912027Sjungma@eit.uni-kl.de	    if( scfx_is_nan( s ) )
45012027Sjungma@eit.uni-kl.de	    {   // special case: NaN
45112027Sjungma@eit.uni-kl.de		m_state = not_a_number;
45212027Sjungma@eit.uni-kl.de		m_mant.clear(); /* to avoid Purify UMRs during assignment */
45312027Sjungma@eit.uni-kl.de		return;
45412027Sjungma@eit.uni-kl.de	    }
45512027Sjungma@eit.uni-kl.de	    if( scfx_is_inf( s ) )
45612027Sjungma@eit.uni-kl.de	    {   // special case: Infinity
45712027Sjungma@eit.uni-kl.de		m_state = infinity;
45812027Sjungma@eit.uni-kl.de		m_mant.clear(); /* to avoid Purify UMRs during assignment */
45912027Sjungma@eit.uni-kl.de		return;
46012027Sjungma@eit.uni-kl.de	    }
46112027Sjungma@eit.uni-kl.de	    break;
46212027Sjungma@eit.uni-kl.de	}
46312027Sjungma@eit.uni-kl.de	case SC_BIN:
46412027Sjungma@eit.uni-kl.de	case SC_BIN_US:
46512027Sjungma@eit.uni-kl.de	{
46612027Sjungma@eit.uni-kl.de	    SCFX_FAIL_IF_( sign_char );
46712027Sjungma@eit.uni-kl.de	    base = 2;
46812027Sjungma@eit.uni-kl.de	    break;
46912027Sjungma@eit.uni-kl.de	}
47012027Sjungma@eit.uni-kl.de
47112027Sjungma@eit.uni-kl.de	case SC_BIN_SM:
47212027Sjungma@eit.uni-kl.de	{
47312027Sjungma@eit.uni-kl.de	    base = 2;
47412027Sjungma@eit.uni-kl.de	    break;
47512027Sjungma@eit.uni-kl.de	}
47612027Sjungma@eit.uni-kl.de	case SC_OCT:
47712027Sjungma@eit.uni-kl.de	case SC_OCT_US:
47812027Sjungma@eit.uni-kl.de	{
47912027Sjungma@eit.uni-kl.de	    SCFX_FAIL_IF_( sign_char );
48012027Sjungma@eit.uni-kl.de	    base = 8;
48112027Sjungma@eit.uni-kl.de	    break;
48212027Sjungma@eit.uni-kl.de	}
48312027Sjungma@eit.uni-kl.de	case SC_OCT_SM:
48412027Sjungma@eit.uni-kl.de	{
48512027Sjungma@eit.uni-kl.de	    base = 8;
48612027Sjungma@eit.uni-kl.de	    break;
48712027Sjungma@eit.uni-kl.de	}
48812027Sjungma@eit.uni-kl.de	case SC_HEX:
48912027Sjungma@eit.uni-kl.de	case SC_HEX_US:
49012027Sjungma@eit.uni-kl.de	{
49112027Sjungma@eit.uni-kl.de	    SCFX_FAIL_IF_( sign_char );
49212027Sjungma@eit.uni-kl.de	    base = 16;
49312027Sjungma@eit.uni-kl.de	    break;
49412027Sjungma@eit.uni-kl.de	}
49512027Sjungma@eit.uni-kl.de	case SC_HEX_SM:
49612027Sjungma@eit.uni-kl.de	{
49712027Sjungma@eit.uni-kl.de	    base = 16;
49812027Sjungma@eit.uni-kl.de	    break;
49912027Sjungma@eit.uni-kl.de	}
50012027Sjungma@eit.uni-kl.de	case SC_CSD:
50112027Sjungma@eit.uni-kl.de	{
50212027Sjungma@eit.uni-kl.de	    SCFX_FAIL_IF_( sign_char );
50312027Sjungma@eit.uni-kl.de	    base = 2;
50412027Sjungma@eit.uni-kl.de	    scfx_csd2tc( s2 );
50512027Sjungma@eit.uni-kl.de	    s = (const char*) s2 + 4;
50612027Sjungma@eit.uni-kl.de	    numrep = SC_BIN;
50712027Sjungma@eit.uni-kl.de	    break;
50812027Sjungma@eit.uni-kl.de	}
50912027Sjungma@eit.uni-kl.de        default:;
51012027Sjungma@eit.uni-kl.de    }
51112027Sjungma@eit.uni-kl.de
51212027Sjungma@eit.uni-kl.de    //
51312027Sjungma@eit.uni-kl.de    // find end of mantissa and count the digits and points
51412027Sjungma@eit.uni-kl.de    //
51512027Sjungma@eit.uni-kl.de
51612027Sjungma@eit.uni-kl.de    const char *end = s;
51712027Sjungma@eit.uni-kl.de    bool based_point = false;
51812027Sjungma@eit.uni-kl.de    int int_digits = 0;
51912027Sjungma@eit.uni-kl.de    int frac_digits = 0;
52012027Sjungma@eit.uni-kl.de
52112027Sjungma@eit.uni-kl.de    while( *end )
52212027Sjungma@eit.uni-kl.de    {
52312027Sjungma@eit.uni-kl.de	if( scfx_exp_start( end ) )
52412027Sjungma@eit.uni-kl.de	    break;
52512027Sjungma@eit.uni-kl.de
52612027Sjungma@eit.uni-kl.de	if( *end == '.' )
52712027Sjungma@eit.uni-kl.de	{
52812027Sjungma@eit.uni-kl.de	    SCFX_FAIL_IF_( based_point );
52912027Sjungma@eit.uni-kl.de	    based_point = true;
53012027Sjungma@eit.uni-kl.de	}
53112027Sjungma@eit.uni-kl.de	else
53212027Sjungma@eit.uni-kl.de	{
53312027Sjungma@eit.uni-kl.de	    SCFX_FAIL_IF_( ! scfx_is_digit( *end, numrep ) );
53412027Sjungma@eit.uni-kl.de	    if( based_point )
53512027Sjungma@eit.uni-kl.de		frac_digits ++;
53612027Sjungma@eit.uni-kl.de	    else
53712027Sjungma@eit.uni-kl.de		int_digits ++;
53812027Sjungma@eit.uni-kl.de	}
53912027Sjungma@eit.uni-kl.de
54012027Sjungma@eit.uni-kl.de	++ end;
54112027Sjungma@eit.uni-kl.de    }
54212027Sjungma@eit.uni-kl.de
54312027Sjungma@eit.uni-kl.de    SCFX_FAIL_IF_( int_digits == 0 && frac_digits == 0 );
54412027Sjungma@eit.uni-kl.de
54512027Sjungma@eit.uni-kl.de    // [ exponent ]
54612027Sjungma@eit.uni-kl.de
54712027Sjungma@eit.uni-kl.de    int exponent = 0;
54812027Sjungma@eit.uni-kl.de
54912027Sjungma@eit.uni-kl.de    if( *end )
55012027Sjungma@eit.uni-kl.de    {
55112027Sjungma@eit.uni-kl.de	for( const char *e = end + 2; *e; ++ e )
55212027Sjungma@eit.uni-kl.de	    SCFX_FAIL_IF_( ! scfx_is_digit( *e, SC_DEC ) );
55312027Sjungma@eit.uni-kl.de	exponent = atoi( end + 1 );
55412027Sjungma@eit.uni-kl.de    }
55512027Sjungma@eit.uni-kl.de
55612027Sjungma@eit.uni-kl.de    //
55712027Sjungma@eit.uni-kl.de    // check if the mantissa is negative
55812027Sjungma@eit.uni-kl.de    //
55912027Sjungma@eit.uni-kl.de
56012027Sjungma@eit.uni-kl.de    bool mant_is_neg = false;
56112027Sjungma@eit.uni-kl.de
56212027Sjungma@eit.uni-kl.de    switch( numrep )
56312027Sjungma@eit.uni-kl.de    {
56412027Sjungma@eit.uni-kl.de	case SC_BIN:
56512027Sjungma@eit.uni-kl.de	case SC_OCT:
56612027Sjungma@eit.uni-kl.de	case SC_HEX:
56712027Sjungma@eit.uni-kl.de	{
56812027Sjungma@eit.uni-kl.de	    const char* p = s;
56912027Sjungma@eit.uni-kl.de	    if( *p == '.' )
57012027Sjungma@eit.uni-kl.de		++ p;
57112027Sjungma@eit.uni-kl.de
57212027Sjungma@eit.uni-kl.de	    mant_is_neg = ( scfx_to_digit( *p, numrep ) >= ( base >> 1 ) );
57312027Sjungma@eit.uni-kl.de
57412027Sjungma@eit.uni-kl.de	    break;
57512027Sjungma@eit.uni-kl.de	}
57612027Sjungma@eit.uni-kl.de	default:
57712027Sjungma@eit.uni-kl.de	    ;
57812027Sjungma@eit.uni-kl.de    }
57912027Sjungma@eit.uni-kl.de
58012027Sjungma@eit.uni-kl.de    //
58112027Sjungma@eit.uni-kl.de    // convert the mantissa
58212027Sjungma@eit.uni-kl.de    //
58312027Sjungma@eit.uni-kl.de
58412027Sjungma@eit.uni-kl.de    switch( base )
58512027Sjungma@eit.uni-kl.de    {
58612027Sjungma@eit.uni-kl.de        case 2:
58712027Sjungma@eit.uni-kl.de	{
58812027Sjungma@eit.uni-kl.de	    int bit_offset = exponent % bits_in_word;
58912027Sjungma@eit.uni-kl.de	    int word_offset = exponent / bits_in_word;
59012027Sjungma@eit.uni-kl.de
59112027Sjungma@eit.uni-kl.de	    int_digits += bit_offset;
59212027Sjungma@eit.uni-kl.de	    frac_digits -= bit_offset;
59312027Sjungma@eit.uni-kl.de
59412027Sjungma@eit.uni-kl.de	    int words = n_word( int_digits ) + n_word( frac_digits );
59512027Sjungma@eit.uni-kl.de	    if( words > size() )
59612027Sjungma@eit.uni-kl.de		resize_to( words );
59712027Sjungma@eit.uni-kl.de	    m_mant.clear();
59812027Sjungma@eit.uni-kl.de
59912027Sjungma@eit.uni-kl.de	    int j = n_word( frac_digits ) * bits_in_word + int_digits - 1;
60012027Sjungma@eit.uni-kl.de
60112027Sjungma@eit.uni-kl.de	    for( ; s < end; s ++ )
60212027Sjungma@eit.uni-kl.de	    {
60312027Sjungma@eit.uni-kl.de		switch( *s )
60412027Sjungma@eit.uni-kl.de		{
60512027Sjungma@eit.uni-kl.de		    case '1':
60612027Sjungma@eit.uni-kl.de		        set_bin( j );
60712027Sjungma@eit.uni-kl.de		    case '0':
60812027Sjungma@eit.uni-kl.de			j --;
60912027Sjungma@eit.uni-kl.de		    case '.':
61012027Sjungma@eit.uni-kl.de			break;
61112027Sjungma@eit.uni-kl.de		    default:
61212027Sjungma@eit.uni-kl.de			SCFX_FAIL_IF_( true );  // should not happen
61312027Sjungma@eit.uni-kl.de		}
61412027Sjungma@eit.uni-kl.de	    }
61512027Sjungma@eit.uni-kl.de
61612027Sjungma@eit.uni-kl.de	    m_wp = n_word( frac_digits ) - word_offset;
61712027Sjungma@eit.uni-kl.de	    break;
61812027Sjungma@eit.uni-kl.de	}
61912027Sjungma@eit.uni-kl.de        case 8:
62012027Sjungma@eit.uni-kl.de	{
62112027Sjungma@eit.uni-kl.de	    exponent *= 3;
62212027Sjungma@eit.uni-kl.de	    int_digits *= 3;
62312027Sjungma@eit.uni-kl.de	    frac_digits *= 3;
62412027Sjungma@eit.uni-kl.de
62512027Sjungma@eit.uni-kl.de	    int bit_offset = exponent % bits_in_word;
62612027Sjungma@eit.uni-kl.de	    int word_offset = exponent / bits_in_word;
62712027Sjungma@eit.uni-kl.de
62812027Sjungma@eit.uni-kl.de	    int_digits += bit_offset;
62912027Sjungma@eit.uni-kl.de	    frac_digits -= bit_offset;
63012027Sjungma@eit.uni-kl.de
63112027Sjungma@eit.uni-kl.de	    int words = n_word( int_digits ) + n_word( frac_digits );
63212027Sjungma@eit.uni-kl.de	    if( words > size() )
63312027Sjungma@eit.uni-kl.de		resize_to( words );
63412027Sjungma@eit.uni-kl.de	    m_mant.clear();
63512027Sjungma@eit.uni-kl.de
63612027Sjungma@eit.uni-kl.de	    int j = n_word( frac_digits ) * bits_in_word + int_digits - 3;
63712027Sjungma@eit.uni-kl.de
63812027Sjungma@eit.uni-kl.de	    for( ; s < end; s ++ )
63912027Sjungma@eit.uni-kl.de	    {
64012027Sjungma@eit.uni-kl.de		switch( *s )
64112027Sjungma@eit.uni-kl.de		{
64212027Sjungma@eit.uni-kl.de		    case '7': case '6': case '5': case '4':
64312027Sjungma@eit.uni-kl.de		    case '3': case '2': case '1':
64412027Sjungma@eit.uni-kl.de		        set_oct( j, *s - '0' );
64512027Sjungma@eit.uni-kl.de		    case '0':
64612027Sjungma@eit.uni-kl.de			j -= 3;
64712027Sjungma@eit.uni-kl.de		    case '.':
64812027Sjungma@eit.uni-kl.de			break;
64912027Sjungma@eit.uni-kl.de		    default:
65012027Sjungma@eit.uni-kl.de			SCFX_FAIL_IF_( true );  // should not happen
65112027Sjungma@eit.uni-kl.de		}
65212027Sjungma@eit.uni-kl.de	    }
65312027Sjungma@eit.uni-kl.de
65412027Sjungma@eit.uni-kl.de	    m_wp = n_word( frac_digits ) - word_offset;
65512027Sjungma@eit.uni-kl.de	    break;
65612027Sjungma@eit.uni-kl.de	}
65712027Sjungma@eit.uni-kl.de        case 10:
65812027Sjungma@eit.uni-kl.de	{
65912027Sjungma@eit.uni-kl.de	    word carry, temp;
66012027Sjungma@eit.uni-kl.de	    int length = int_digits + frac_digits;
66112027Sjungma@eit.uni-kl.de	    resize_to( sc_max( min_mant, n_word( 4 * length ) ) );
66212027Sjungma@eit.uni-kl.de
66312027Sjungma@eit.uni-kl.de	    m_mant.clear();
66412027Sjungma@eit.uni-kl.de	    m_msw = m_lsw = 0;
66512027Sjungma@eit.uni-kl.de
66612027Sjungma@eit.uni-kl.de	    for( ; s < end; s ++ )
66712027Sjungma@eit.uni-kl.de	    {
66812027Sjungma@eit.uni-kl.de		switch( *s )
66912027Sjungma@eit.uni-kl.de		{
67012027Sjungma@eit.uni-kl.de		    case '9': case '8': case '7': case '6': case '5':
67112027Sjungma@eit.uni-kl.de		    case '4': case '3': case '2': case '1': case '0':
67212027Sjungma@eit.uni-kl.de		        multiply_by_ten();
67312027Sjungma@eit.uni-kl.de			carry = *s - '0';
67412027Sjungma@eit.uni-kl.de			for ( int i = 0; carry && i < m_mant.size(); i++ )
67512027Sjungma@eit.uni-kl.de			{
67612027Sjungma@eit.uni-kl.de			    temp = m_mant[i];
67712027Sjungma@eit.uni-kl.de                            temp += carry;
67812027Sjungma@eit.uni-kl.de			    carry = temp < m_mant[i];
67912027Sjungma@eit.uni-kl.de			    m_mant[i] = temp;
68012027Sjungma@eit.uni-kl.de			}
68112027Sjungma@eit.uni-kl.de		    case '.':
68212027Sjungma@eit.uni-kl.de			break;
68312027Sjungma@eit.uni-kl.de		    default:
68412027Sjungma@eit.uni-kl.de			SCFX_FAIL_IF_( true );  // should not happen
68512027Sjungma@eit.uni-kl.de		}
68612027Sjungma@eit.uni-kl.de	    }
68712027Sjungma@eit.uni-kl.de
68812027Sjungma@eit.uni-kl.de	    m_wp = 0;
68912027Sjungma@eit.uni-kl.de	    find_sw();
69012027Sjungma@eit.uni-kl.de
69112027Sjungma@eit.uni-kl.de	    int denominator = frac_digits - exponent;
69212027Sjungma@eit.uni-kl.de
69312027Sjungma@eit.uni-kl.de	    if( denominator )
69412027Sjungma@eit.uni-kl.de	    {
69512027Sjungma@eit.uni-kl.de		scfx_rep frac_num = pow10_fx( denominator );
69612027Sjungma@eit.uni-kl.de		scfx_rep* temp_num =
69712027Sjungma@eit.uni-kl.de		    div_scfx_rep( const_cast<const scfx_rep&>( *this ),
69812027Sjungma@eit.uni-kl.de				   frac_num, cte_wl );
69912027Sjungma@eit.uni-kl.de		*this = *temp_num;
70012027Sjungma@eit.uni-kl.de		delete temp_num;
70112027Sjungma@eit.uni-kl.de	    }
70212027Sjungma@eit.uni-kl.de
70312027Sjungma@eit.uni-kl.de	    break;
70412027Sjungma@eit.uni-kl.de	}
70512027Sjungma@eit.uni-kl.de        case 16:
70612027Sjungma@eit.uni-kl.de	{
70712027Sjungma@eit.uni-kl.de	    exponent *= 4;
70812027Sjungma@eit.uni-kl.de	    int_digits *= 4;
70912027Sjungma@eit.uni-kl.de	    frac_digits *= 4;
71012027Sjungma@eit.uni-kl.de
71112027Sjungma@eit.uni-kl.de	    int bit_offset = exponent % bits_in_word;
71212027Sjungma@eit.uni-kl.de	    int word_offset = exponent / bits_in_word;
71312027Sjungma@eit.uni-kl.de
71412027Sjungma@eit.uni-kl.de	    int_digits += bit_offset;
71512027Sjungma@eit.uni-kl.de	    frac_digits -= bit_offset;
71612027Sjungma@eit.uni-kl.de
71712027Sjungma@eit.uni-kl.de	    int words = n_word( int_digits ) + n_word( frac_digits );
71812027Sjungma@eit.uni-kl.de	    if( words > size() )
71912027Sjungma@eit.uni-kl.de		resize_to( words );
72012027Sjungma@eit.uni-kl.de	    m_mant.clear();
72112027Sjungma@eit.uni-kl.de
72212027Sjungma@eit.uni-kl.de	    int j = n_word( frac_digits ) * bits_in_word + int_digits - 4;
72312027Sjungma@eit.uni-kl.de
72412027Sjungma@eit.uni-kl.de	    for( ; s < end; s ++ )
72512027Sjungma@eit.uni-kl.de	    {
72612027Sjungma@eit.uni-kl.de		switch( *s )
72712027Sjungma@eit.uni-kl.de		{
72812027Sjungma@eit.uni-kl.de		    case 'f': case 'e': case 'd': case 'c': case 'b': case 'a':
72912027Sjungma@eit.uni-kl.de		       set_hex( j, *s - 'a' + 10 );
73012027Sjungma@eit.uni-kl.de		       j -= 4;
73112027Sjungma@eit.uni-kl.de		       break;
73212027Sjungma@eit.uni-kl.de		    case 'F': case 'E': case 'D': case 'C': case 'B': case 'A':
73312027Sjungma@eit.uni-kl.de		       set_hex( j, *s - 'A' + 10 );
73412027Sjungma@eit.uni-kl.de		       j -= 4;
73512027Sjungma@eit.uni-kl.de		       break;
73612027Sjungma@eit.uni-kl.de		    case '9': case '8': case '7': case '6': case '5':
73712027Sjungma@eit.uni-kl.de		    case '4': case '3': case '2': case '1':
73812027Sjungma@eit.uni-kl.de		       set_hex( j, *s - '0' );
73912027Sjungma@eit.uni-kl.de		    case '0':
74012027Sjungma@eit.uni-kl.de		       j -= 4;
74112027Sjungma@eit.uni-kl.de		    case '.':
74212027Sjungma@eit.uni-kl.de		       break;
74312027Sjungma@eit.uni-kl.de		   default:
74412027Sjungma@eit.uni-kl.de		       SCFX_FAIL_IF_( true );  // should not happen
74512027Sjungma@eit.uni-kl.de		}
74612027Sjungma@eit.uni-kl.de	    }
74712027Sjungma@eit.uni-kl.de
74812027Sjungma@eit.uni-kl.de	    m_wp = n_word( frac_digits ) - word_offset;
74912027Sjungma@eit.uni-kl.de	    break;
75012027Sjungma@eit.uni-kl.de	}
75112027Sjungma@eit.uni-kl.de    }
75212027Sjungma@eit.uni-kl.de
75312027Sjungma@eit.uni-kl.de    m_state = normal;
75412027Sjungma@eit.uni-kl.de    find_sw();
75512027Sjungma@eit.uni-kl.de
75612027Sjungma@eit.uni-kl.de    //
75712027Sjungma@eit.uni-kl.de    // two's complement of mantissa if it is negative
75812027Sjungma@eit.uni-kl.de    //
75912027Sjungma@eit.uni-kl.de
76012027Sjungma@eit.uni-kl.de    if( mant_is_neg )
76112027Sjungma@eit.uni-kl.de    {
76212027Sjungma@eit.uni-kl.de	m_mant[m_msw] |=  -1 << scfx_find_msb( m_mant[m_msw] );
76312027Sjungma@eit.uni-kl.de	for( int i = m_msw + 1; i < m_mant.size(); ++ i )
76412027Sjungma@eit.uni-kl.de	    m_mant[i] = static_cast<word>( -1 );
76512027Sjungma@eit.uni-kl.de	complement( m_mant, m_mant, m_mant.size() );
76612027Sjungma@eit.uni-kl.de	inc( m_mant );
76712027Sjungma@eit.uni-kl.de	m_sign *= -1;
76812027Sjungma@eit.uni-kl.de	find_sw();
76912027Sjungma@eit.uni-kl.de    }
77012027Sjungma@eit.uni-kl.de}
77112027Sjungma@eit.uni-kl.de
77212027Sjungma@eit.uni-kl.de
77312027Sjungma@eit.uni-kl.de#undef SCFX_FAIL_IF_
77412027Sjungma@eit.uni-kl.de
77512027Sjungma@eit.uni-kl.de
77612027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
77712027Sjungma@eit.uni-kl.de//  METHOD : to_double
77812027Sjungma@eit.uni-kl.de//
77912027Sjungma@eit.uni-kl.de//  Convert from scfx_rep to double.
78012027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
78112027Sjungma@eit.uni-kl.de
78212027Sjungma@eit.uni-kl.dedouble
78312027Sjungma@eit.uni-kl.descfx_rep::to_double() const
78412027Sjungma@eit.uni-kl.de{
78512027Sjungma@eit.uni-kl.de    scfx_ieee_double id;
78612027Sjungma@eit.uni-kl.de
78712027Sjungma@eit.uni-kl.de    // handle special cases
78812027Sjungma@eit.uni-kl.de
78912027Sjungma@eit.uni-kl.de    if( is_nan() )
79012027Sjungma@eit.uni-kl.de    {
79112027Sjungma@eit.uni-kl.de        id.set_nan();
79212027Sjungma@eit.uni-kl.de	return id;
79312027Sjungma@eit.uni-kl.de    }
79412027Sjungma@eit.uni-kl.de
79512027Sjungma@eit.uni-kl.de    if( is_inf() )
79612027Sjungma@eit.uni-kl.de    {
79712027Sjungma@eit.uni-kl.de        id.set_inf();
79812027Sjungma@eit.uni-kl.de	id.negative( m_sign < 0 );
79912027Sjungma@eit.uni-kl.de	return id;
80012027Sjungma@eit.uni-kl.de    }
80112027Sjungma@eit.uni-kl.de
80212027Sjungma@eit.uni-kl.de    if( is_zero() )
80312027Sjungma@eit.uni-kl.de    {
80412027Sjungma@eit.uni-kl.de	id = 0.;
80512027Sjungma@eit.uni-kl.de	id.negative( m_sign < 0 );
80612027Sjungma@eit.uni-kl.de	return id;
80712027Sjungma@eit.uni-kl.de    }
80812027Sjungma@eit.uni-kl.de
80912027Sjungma@eit.uni-kl.de    int msb = scfx_find_msb( m_mant[m_msw] );
81012027Sjungma@eit.uni-kl.de
81112027Sjungma@eit.uni-kl.de    int exp = (m_msw - m_wp) * bits_in_word + msb;
81212027Sjungma@eit.uni-kl.de
81312027Sjungma@eit.uni-kl.de    if( exp > SCFX_IEEE_DOUBLE_E_MAX )
81412027Sjungma@eit.uni-kl.de    {
81512027Sjungma@eit.uni-kl.de	id.set_inf();
81612027Sjungma@eit.uni-kl.de	id.negative( m_sign < 0 );
81712027Sjungma@eit.uni-kl.de	return id;
81812027Sjungma@eit.uni-kl.de    }
81912027Sjungma@eit.uni-kl.de
82012027Sjungma@eit.uni-kl.de    if( exp < SCFX_IEEE_DOUBLE_E_MIN
82112027Sjungma@eit.uni-kl.de	- static_cast<int>( SCFX_IEEE_DOUBLE_M_SIZE ) )
82212027Sjungma@eit.uni-kl.de    {
82312027Sjungma@eit.uni-kl.de	id = 0.;
82412027Sjungma@eit.uni-kl.de	return id;
82512027Sjungma@eit.uni-kl.de    }
82612027Sjungma@eit.uni-kl.de
82712027Sjungma@eit.uni-kl.de    int shift = mantissa0_size - msb;
82812027Sjungma@eit.uni-kl.de
82912027Sjungma@eit.uni-kl.de    unsigned int m0;
83012027Sjungma@eit.uni-kl.de    unsigned int m1 = 0;
83112027Sjungma@eit.uni-kl.de    unsigned int guard = 0;
83212027Sjungma@eit.uni-kl.de
83312027Sjungma@eit.uni-kl.de    if( shift == 0 )
83412027Sjungma@eit.uni-kl.de    {
83512027Sjungma@eit.uni-kl.de        m0 = m_mant[m_msw] & ~( 1 << mantissa0_size );
83612027Sjungma@eit.uni-kl.de	if( m_msw > m_lsw )
83712027Sjungma@eit.uni-kl.de	{
83812027Sjungma@eit.uni-kl.de	    m1 = m_mant[m_msw - 1];
83912027Sjungma@eit.uni-kl.de	    if( m_msw - 1 > m_lsw )
84012027Sjungma@eit.uni-kl.de	        guard = m_mant[m_msw - 2] >> ( bits_in_word - 1 );
84112027Sjungma@eit.uni-kl.de	}
84212027Sjungma@eit.uni-kl.de    }
84312027Sjungma@eit.uni-kl.de    else if( shift < 0 )
84412027Sjungma@eit.uni-kl.de    {
84512027Sjungma@eit.uni-kl.de	m0 = ( m_mant[m_msw] >> -shift ) & ~( 1 << mantissa0_size );
84612027Sjungma@eit.uni-kl.de	m1 = m_mant[m_msw] << ( bits_in_word + shift );
84712027Sjungma@eit.uni-kl.de	if( m_msw > m_lsw )
84812027Sjungma@eit.uni-kl.de	{
84912027Sjungma@eit.uni-kl.de	    m1 |= m_mant[m_msw - 1] >> -shift;
85012027Sjungma@eit.uni-kl.de	    guard = ( m_mant[m_msw - 1] >> ( -shift - 1 ) ) & 1;
85112027Sjungma@eit.uni-kl.de	}
85212027Sjungma@eit.uni-kl.de    }
85312027Sjungma@eit.uni-kl.de    else
85412027Sjungma@eit.uni-kl.de    {
85512027Sjungma@eit.uni-kl.de	m0 = ( m_mant[m_msw] << shift ) & ~( 1 << mantissa0_size );
85612027Sjungma@eit.uni-kl.de	if( m_msw > m_lsw )
85712027Sjungma@eit.uni-kl.de	{
85812027Sjungma@eit.uni-kl.de	    m0 |= m_mant[m_msw - 1] >> ( bits_in_word - shift );
85912027Sjungma@eit.uni-kl.de	    m1 = m_mant[m_msw - 1] << shift;
86012027Sjungma@eit.uni-kl.de	    if( m_msw - 1 > m_lsw )
86112027Sjungma@eit.uni-kl.de	    {
86212027Sjungma@eit.uni-kl.de	        m1 |= m_mant[m_msw - 2] >> ( bits_in_word - shift );
86312027Sjungma@eit.uni-kl.de		guard = ( m_mant[m_msw - 2] >> (bits_in_word - shift - 1) )
86412027Sjungma@eit.uni-kl.de                      & 1;
86512027Sjungma@eit.uni-kl.de	    }
86612027Sjungma@eit.uni-kl.de	}
86712027Sjungma@eit.uni-kl.de    }
86812027Sjungma@eit.uni-kl.de
86912027Sjungma@eit.uni-kl.de    if( exp < SCFX_IEEE_DOUBLE_E_MIN )
87012027Sjungma@eit.uni-kl.de    {
87112027Sjungma@eit.uni-kl.de	m0 |= ( 1 << mantissa0_size );
87212027Sjungma@eit.uni-kl.de
87312027Sjungma@eit.uni-kl.de	int subnormal_shift = SCFX_IEEE_DOUBLE_E_MIN - exp;
87412027Sjungma@eit.uni-kl.de
87512027Sjungma@eit.uni-kl.de	if( subnormal_shift < bits_in_word )
87612027Sjungma@eit.uni-kl.de	{
87712027Sjungma@eit.uni-kl.de	    m1 = m1 >> subnormal_shift
87812027Sjungma@eit.uni-kl.de	       | m0 << ( bits_in_word - subnormal_shift );
87912027Sjungma@eit.uni-kl.de	    m0 = m0 >> subnormal_shift;
88012027Sjungma@eit.uni-kl.de	}
88112027Sjungma@eit.uni-kl.de	else
88212027Sjungma@eit.uni-kl.de	{
88312027Sjungma@eit.uni-kl.de	    m1 = m0 >> ( subnormal_shift - bits_in_word );
88412027Sjungma@eit.uni-kl.de	    m0 = 0;
88512027Sjungma@eit.uni-kl.de	}
88612027Sjungma@eit.uni-kl.de
88712027Sjungma@eit.uni-kl.de	guard = 0;
88812027Sjungma@eit.uni-kl.de
88912027Sjungma@eit.uni-kl.de	exp = SCFX_IEEE_DOUBLE_E_MIN - 1;
89012027Sjungma@eit.uni-kl.de    }
89112027Sjungma@eit.uni-kl.de
89212027Sjungma@eit.uni-kl.de    id.mantissa0( m0 );
89312027Sjungma@eit.uni-kl.de    id.mantissa1( m1 );
89412027Sjungma@eit.uni-kl.de    id.exponent( exp );
89512027Sjungma@eit.uni-kl.de    id.negative( m_sign < 0 );
89612027Sjungma@eit.uni-kl.de
89712027Sjungma@eit.uni-kl.de    double result = id;
89812027Sjungma@eit.uni-kl.de
89912027Sjungma@eit.uni-kl.de    if( guard != 0 )
90012027Sjungma@eit.uni-kl.de        result += m_sign * scfx_pow2( exp - SCFX_IEEE_DOUBLE_M_SIZE );
90112027Sjungma@eit.uni-kl.de
90212027Sjungma@eit.uni-kl.de    return result;
90312027Sjungma@eit.uni-kl.de}
90412027Sjungma@eit.uni-kl.de
90512027Sjungma@eit.uni-kl.de
90612027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
90712027Sjungma@eit.uni-kl.de//  METHOD : to_string
90812027Sjungma@eit.uni-kl.de//
90912027Sjungma@eit.uni-kl.de//  Convert from scfx_rep to character string.
91012027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
91112027Sjungma@eit.uni-kl.de
91212027Sjungma@eit.uni-kl.devoid
91312027Sjungma@eit.uni-kl.deprint_dec( scfx_string& s, const scfx_rep& num, int w_prefix, sc_fmt fmt )
91412027Sjungma@eit.uni-kl.de{
91512027Sjungma@eit.uni-kl.de    if( num.is_neg() )
91612027Sjungma@eit.uni-kl.de	s += '-';
91712027Sjungma@eit.uni-kl.de
91812027Sjungma@eit.uni-kl.de    if( w_prefix == 1 ) {
91912027Sjungma@eit.uni-kl.de	scfx_print_prefix( s, SC_DEC );
92012027Sjungma@eit.uni-kl.de    }
92112027Sjungma@eit.uni-kl.de
92212027Sjungma@eit.uni-kl.de    if( num.is_zero() )
92312027Sjungma@eit.uni-kl.de    {
92412027Sjungma@eit.uni-kl.de	s += '0';
92512027Sjungma@eit.uni-kl.de	return;
92612027Sjungma@eit.uni-kl.de    }
92712027Sjungma@eit.uni-kl.de
92812027Sjungma@eit.uni-kl.de    // split 'num' into its integer and fractional part
92912027Sjungma@eit.uni-kl.de
93012027Sjungma@eit.uni-kl.de    scfx_rep int_part  = num;
93112027Sjungma@eit.uni-kl.de    scfx_rep frac_part = num;
93212027Sjungma@eit.uni-kl.de
93312027Sjungma@eit.uni-kl.de    int i;
93412027Sjungma@eit.uni-kl.de
93512027Sjungma@eit.uni-kl.de    for( i = int_part.m_lsw; i <= int_part.m_msw && i < int_part.m_wp; i ++ )
93612027Sjungma@eit.uni-kl.de	int_part.m_mant[i] = 0;
93712027Sjungma@eit.uni-kl.de    int_part.find_sw();
93812027Sjungma@eit.uni-kl.de    if( int_part.m_wp < int_part.m_lsw )
93912027Sjungma@eit.uni-kl.de	int_part.resize_to( int_part.size() - int_part.m_wp, -1 );
94012027Sjungma@eit.uni-kl.de
94112027Sjungma@eit.uni-kl.de    for( i = frac_part.m_msw;
94212027Sjungma@eit.uni-kl.de	 i >= frac_part.m_lsw && i >= frac_part.m_wp;
94312027Sjungma@eit.uni-kl.de	 i -- )
94412027Sjungma@eit.uni-kl.de	frac_part.m_mant[i] = 0;
94512027Sjungma@eit.uni-kl.de    frac_part.find_sw();
94612027Sjungma@eit.uni-kl.de    if( frac_part.m_msw == frac_part.size() - 1 )
94712027Sjungma@eit.uni-kl.de	frac_part.resize_to( frac_part.size() + 1, 1 );
94812027Sjungma@eit.uni-kl.de
94912027Sjungma@eit.uni-kl.de    // print integer part
95012027Sjungma@eit.uni-kl.de
95112027Sjungma@eit.uni-kl.de    int int_digits = 0;
95212027Sjungma@eit.uni-kl.de    int int_zeros  = 0;
95312027Sjungma@eit.uni-kl.de
95412027Sjungma@eit.uni-kl.de    if( ! int_part.is_zero() )
95512027Sjungma@eit.uni-kl.de    {
95612027Sjungma@eit.uni-kl.de	double int_wl = ( int_part.m_msw - int_part.m_wp ) * bits_in_word
95712027Sjungma@eit.uni-kl.de	              + scfx_find_msb( int_part.m_mant[int_part.m_msw] ) + 1;
95812027Sjungma@eit.uni-kl.de	int_digits = (int) ceil( int_wl * log10( 2. ) );
95912027Sjungma@eit.uni-kl.de
96012027Sjungma@eit.uni-kl.de	int len = s.length();
96112027Sjungma@eit.uni-kl.de	s.append( int_digits );
96212027Sjungma@eit.uni-kl.de
96312027Sjungma@eit.uni-kl.de	bool zero_digits = ( frac_part.is_zero() && fmt != SC_F );
96412027Sjungma@eit.uni-kl.de
96512027Sjungma@eit.uni-kl.de	for( i = int_digits + len - 1; i >= len; i-- )
96612027Sjungma@eit.uni-kl.de	{
96712027Sjungma@eit.uni-kl.de	    unsigned int remainder = int_part.divide_by_ten();
96812027Sjungma@eit.uni-kl.de	    s[i] = static_cast<char>( '0' + remainder );
96912027Sjungma@eit.uni-kl.de
97012027Sjungma@eit.uni-kl.de	    if( zero_digits )
97112027Sjungma@eit.uni-kl.de	    {
97212027Sjungma@eit.uni-kl.de		if( remainder == 0 )
97312027Sjungma@eit.uni-kl.de		    int_zeros ++;
97412027Sjungma@eit.uni-kl.de		else
97512027Sjungma@eit.uni-kl.de		    zero_digits = false;
97612027Sjungma@eit.uni-kl.de	    }
97712027Sjungma@eit.uni-kl.de	}
97812027Sjungma@eit.uni-kl.de
97912027Sjungma@eit.uni-kl.de	// discard trailing zeros from int_part
98012027Sjungma@eit.uni-kl.de	s.discard( int_zeros );
98112027Sjungma@eit.uni-kl.de
98212027Sjungma@eit.uni-kl.de	if( s[len] == '0' )
98312027Sjungma@eit.uni-kl.de	{
98412027Sjungma@eit.uni-kl.de	    // int_digits was overestimated by one
98512027Sjungma@eit.uni-kl.de	    s.remove( len );
98612027Sjungma@eit.uni-kl.de	    -- int_digits;
98712027Sjungma@eit.uni-kl.de	}
98812027Sjungma@eit.uni-kl.de    }
98912027Sjungma@eit.uni-kl.de
99012027Sjungma@eit.uni-kl.de    // print fractional part
99112027Sjungma@eit.uni-kl.de
99212027Sjungma@eit.uni-kl.de    int frac_digits = 0;
99312027Sjungma@eit.uni-kl.de    int frac_zeros  = 0;
99412027Sjungma@eit.uni-kl.de
99512027Sjungma@eit.uni-kl.de    if( ! frac_part.is_zero() )
99612027Sjungma@eit.uni-kl.de    {
99712027Sjungma@eit.uni-kl.de	s += '.';
99812027Sjungma@eit.uni-kl.de
99912027Sjungma@eit.uni-kl.de	bool zero_digits = ( int_digits == 0 && fmt != SC_F );
100012027Sjungma@eit.uni-kl.de
100112027Sjungma@eit.uni-kl.de	double frac_wl = ( frac_part.m_wp - frac_part.m_msw ) * bits_in_word
100212027Sjungma@eit.uni-kl.de	               - scfx_find_msb( frac_part.m_mant[frac_part.m_msw] )
100312027Sjungma@eit.uni-kl.de                       - 1;
100412027Sjungma@eit.uni-kl.de	frac_zeros = (int) floor( frac_wl * log10( 2. ) );
100512027Sjungma@eit.uni-kl.de
100612027Sjungma@eit.uni-kl.de	scfx_rep temp;
100712027Sjungma@eit.uni-kl.de	sc_dt::multiply( temp, frac_part, pow10_fx( frac_zeros ) );
100812027Sjungma@eit.uni-kl.de	frac_part = temp;
100912027Sjungma@eit.uni-kl.de	if( frac_part.m_msw == frac_part.size() - 1 )
101012027Sjungma@eit.uni-kl.de	    frac_part.resize_to( frac_part.size() + 1, 1 );
101112027Sjungma@eit.uni-kl.de
101212027Sjungma@eit.uni-kl.de	frac_digits = frac_zeros;
101312027Sjungma@eit.uni-kl.de	if( ! zero_digits )
101412027Sjungma@eit.uni-kl.de	{
101512027Sjungma@eit.uni-kl.de	    for( i = 0; i < frac_zeros; i ++ )
101612027Sjungma@eit.uni-kl.de		s += '0';
101712027Sjungma@eit.uni-kl.de	    frac_zeros = 0;
101812027Sjungma@eit.uni-kl.de	}
101912027Sjungma@eit.uni-kl.de
102012027Sjungma@eit.uni-kl.de	while( ! frac_part.is_zero() )
102112027Sjungma@eit.uni-kl.de	{
102212027Sjungma@eit.uni-kl.de	    frac_part.multiply_by_ten();
102312027Sjungma@eit.uni-kl.de	    int n = frac_part.m_mant[frac_part.m_msw + 1];
102412027Sjungma@eit.uni-kl.de
102512027Sjungma@eit.uni-kl.de	    if( zero_digits )
102612027Sjungma@eit.uni-kl.de	    {
102712027Sjungma@eit.uni-kl.de		if( n == 0 )
102812027Sjungma@eit.uni-kl.de		    frac_zeros ++;
102912027Sjungma@eit.uni-kl.de		else
103012027Sjungma@eit.uni-kl.de		    zero_digits = false;
103112027Sjungma@eit.uni-kl.de	    }
103212027Sjungma@eit.uni-kl.de
103312027Sjungma@eit.uni-kl.de	    if( ! zero_digits )
103412027Sjungma@eit.uni-kl.de		s += static_cast<char>( '0' + n );
103512027Sjungma@eit.uni-kl.de
103612027Sjungma@eit.uni-kl.de	    frac_part.m_mant[frac_part.m_msw + 1] = 0;
103712027Sjungma@eit.uni-kl.de	    frac_digits ++;
103812027Sjungma@eit.uni-kl.de	}
103912027Sjungma@eit.uni-kl.de    }
104012027Sjungma@eit.uni-kl.de
104112027Sjungma@eit.uni-kl.de    // print exponent
104212027Sjungma@eit.uni-kl.de
104312027Sjungma@eit.uni-kl.de    if( fmt != SC_F )
104412027Sjungma@eit.uni-kl.de    {
104512027Sjungma@eit.uni-kl.de        if( frac_digits == 0 )
104612027Sjungma@eit.uni-kl.de	    scfx_print_exp( s, int_zeros );
104712027Sjungma@eit.uni-kl.de	else if( int_digits == 0 )
104812027Sjungma@eit.uni-kl.de	    scfx_print_exp( s, - frac_zeros );
104912027Sjungma@eit.uni-kl.de    }
105012027Sjungma@eit.uni-kl.de}
105112027Sjungma@eit.uni-kl.de
105212027Sjungma@eit.uni-kl.devoid
105312027Sjungma@eit.uni-kl.deprint_other( scfx_string& s, const scfx_rep& a, sc_numrep numrep, int w_prefix,
105412027Sjungma@eit.uni-kl.de	     sc_fmt fmt, const scfx_params* params )
105512027Sjungma@eit.uni-kl.de{
105612027Sjungma@eit.uni-kl.de    scfx_rep b = a;
105712027Sjungma@eit.uni-kl.de
105812027Sjungma@eit.uni-kl.de    sc_numrep numrep2 = numrep;
105912027Sjungma@eit.uni-kl.de
106012027Sjungma@eit.uni-kl.de    bool numrep_is_sm = ( numrep == SC_BIN_SM ||
106112027Sjungma@eit.uni-kl.de			  numrep == SC_OCT_SM ||
106212027Sjungma@eit.uni-kl.de			  numrep == SC_HEX_SM );
106312027Sjungma@eit.uni-kl.de
106412027Sjungma@eit.uni-kl.de    if( numrep_is_sm )
106512027Sjungma@eit.uni-kl.de    {
106612027Sjungma@eit.uni-kl.de	if( b.is_neg() )
106712027Sjungma@eit.uni-kl.de	{
106812027Sjungma@eit.uni-kl.de	    s += '-';
106912027Sjungma@eit.uni-kl.de	    b = *neg_scfx_rep( a );
107012027Sjungma@eit.uni-kl.de	}
107112027Sjungma@eit.uni-kl.de	switch( numrep )
107212027Sjungma@eit.uni-kl.de	{
107312027Sjungma@eit.uni-kl.de	    case SC_BIN_SM:
107412027Sjungma@eit.uni-kl.de		numrep2 = SC_BIN_US;
107512027Sjungma@eit.uni-kl.de		break;
107612027Sjungma@eit.uni-kl.de	    case SC_OCT_SM:
107712027Sjungma@eit.uni-kl.de		numrep2 = SC_OCT_US;
107812027Sjungma@eit.uni-kl.de		break;
107912027Sjungma@eit.uni-kl.de	    case SC_HEX_SM:
108012027Sjungma@eit.uni-kl.de		numrep2 = SC_HEX_US;
108112027Sjungma@eit.uni-kl.de		break;
108212027Sjungma@eit.uni-kl.de	    default:
108312027Sjungma@eit.uni-kl.de		;
108412027Sjungma@eit.uni-kl.de	}
108512027Sjungma@eit.uni-kl.de    }
108612027Sjungma@eit.uni-kl.de
108712027Sjungma@eit.uni-kl.de    if( w_prefix != 0 ) {
108812027Sjungma@eit.uni-kl.de	scfx_print_prefix( s, numrep );
108912027Sjungma@eit.uni-kl.de    }
109012027Sjungma@eit.uni-kl.de
109112027Sjungma@eit.uni-kl.de    numrep = numrep2;
109212027Sjungma@eit.uni-kl.de
109312027Sjungma@eit.uni-kl.de    int msb, lsb;
109412027Sjungma@eit.uni-kl.de
109512027Sjungma@eit.uni-kl.de    if( params != 0 )
109612027Sjungma@eit.uni-kl.de    {
109712027Sjungma@eit.uni-kl.de	msb = params->iwl() - 1;
109812027Sjungma@eit.uni-kl.de	lsb = params->iwl() - params->wl();
109912027Sjungma@eit.uni-kl.de
110012027Sjungma@eit.uni-kl.de	if( params->enc() == SC_TC_ &&
110112027Sjungma@eit.uni-kl.de	    ( numrep == SC_BIN_US ||
110212027Sjungma@eit.uni-kl.de	      numrep == SC_OCT_US ||
110312027Sjungma@eit.uni-kl.de	      numrep == SC_HEX_US ) &&
110412027Sjungma@eit.uni-kl.de	    ! numrep_is_sm &&
110512027Sjungma@eit.uni-kl.de	    params->wl() > 1 )
110612027Sjungma@eit.uni-kl.de	    -- msb;
110712027Sjungma@eit.uni-kl.de	else if( params->enc() == SC_US_ &&
110812027Sjungma@eit.uni-kl.de	    ( numrep == SC_BIN ||
110912027Sjungma@eit.uni-kl.de	      numrep == SC_OCT ||
111012027Sjungma@eit.uni-kl.de	      numrep == SC_HEX ||
111112027Sjungma@eit.uni-kl.de	      numrep == SC_CSD ) )
111212027Sjungma@eit.uni-kl.de	    ++ msb;
111312027Sjungma@eit.uni-kl.de    }
111412027Sjungma@eit.uni-kl.de    else
111512027Sjungma@eit.uni-kl.de    {
111612027Sjungma@eit.uni-kl.de	if( b.is_zero() )
111712027Sjungma@eit.uni-kl.de	{
111812027Sjungma@eit.uni-kl.de	    msb = 0;
111912027Sjungma@eit.uni-kl.de	    lsb = 0;
112012027Sjungma@eit.uni-kl.de	}
112112027Sjungma@eit.uni-kl.de	else
112212027Sjungma@eit.uni-kl.de	{
112312027Sjungma@eit.uni-kl.de	    msb = ( b.m_msw - b.m_wp ) * bits_in_word
112412027Sjungma@eit.uni-kl.de		+ scfx_find_msb( b.m_mant[ b.m_msw ] ) + 1;
112512027Sjungma@eit.uni-kl.de	    while( b.get_bit( msb ) == b.get_bit( msb - 1 ) )
112612027Sjungma@eit.uni-kl.de		-- msb;
112712027Sjungma@eit.uni-kl.de
112812027Sjungma@eit.uni-kl.de	    if( numrep == SC_BIN_US ||
112912027Sjungma@eit.uni-kl.de		numrep == SC_OCT_US ||
113012027Sjungma@eit.uni-kl.de		numrep == SC_HEX_US )
113112027Sjungma@eit.uni-kl.de		-- msb;
113212027Sjungma@eit.uni-kl.de
113312027Sjungma@eit.uni-kl.de	    lsb = ( b.m_lsw - b.m_wp ) * bits_in_word
113412027Sjungma@eit.uni-kl.de		+ scfx_find_lsb( b.m_mant[ b.m_lsw ] );
113512027Sjungma@eit.uni-kl.de	}
113612027Sjungma@eit.uni-kl.de    }
113712027Sjungma@eit.uni-kl.de
113812027Sjungma@eit.uni-kl.de    int step;
113912027Sjungma@eit.uni-kl.de
114012027Sjungma@eit.uni-kl.de    switch( numrep )
114112027Sjungma@eit.uni-kl.de    {
114212027Sjungma@eit.uni-kl.de	case SC_BIN:
114312027Sjungma@eit.uni-kl.de	case SC_BIN_US:
114412027Sjungma@eit.uni-kl.de	case SC_CSD:
114512027Sjungma@eit.uni-kl.de	    step = 1;
114612027Sjungma@eit.uni-kl.de	   break;
114712027Sjungma@eit.uni-kl.de	case SC_OCT:
114812027Sjungma@eit.uni-kl.de	case SC_OCT_US:
114912027Sjungma@eit.uni-kl.de	    step = 3;
115012027Sjungma@eit.uni-kl.de	    break;
115112027Sjungma@eit.uni-kl.de	case SC_HEX:
115212027Sjungma@eit.uni-kl.de	case SC_HEX_US:
115312027Sjungma@eit.uni-kl.de	    step = 4;
115412027Sjungma@eit.uni-kl.de	    break;
115512027Sjungma@eit.uni-kl.de	default:
115612027Sjungma@eit.uni-kl.de	    step = 0;
115712027Sjungma@eit.uni-kl.de    }
115812027Sjungma@eit.uni-kl.de
115912027Sjungma@eit.uni-kl.de    msb = (int) ceil( double( msb + 1 ) / step ) * step - 1;
116012027Sjungma@eit.uni-kl.de
116112027Sjungma@eit.uni-kl.de    lsb = (int) floor( double( lsb ) / step ) * step;
116212027Sjungma@eit.uni-kl.de
116312027Sjungma@eit.uni-kl.de    if( msb < 0 )
116412027Sjungma@eit.uni-kl.de    {
116512027Sjungma@eit.uni-kl.de	s += '.';
116612027Sjungma@eit.uni-kl.de	if( fmt == SC_F )
116712027Sjungma@eit.uni-kl.de	{
116812027Sjungma@eit.uni-kl.de	    int sign = ( b.is_neg() ) ? ( 1 << step ) - 1 : 0;
116912027Sjungma@eit.uni-kl.de	    for( int i = ( msb + 1 ) / step; i < 0; i ++ )
117012027Sjungma@eit.uni-kl.de	    {
117112027Sjungma@eit.uni-kl.de		if( sign < 10 )
117212027Sjungma@eit.uni-kl.de		    s += static_cast<char>( sign + '0' );
117312027Sjungma@eit.uni-kl.de		else
117412027Sjungma@eit.uni-kl.de		    s += static_cast<char>( sign + 'a' - 10 );
117512027Sjungma@eit.uni-kl.de	    }
117612027Sjungma@eit.uni-kl.de	}
117712027Sjungma@eit.uni-kl.de    }
117812027Sjungma@eit.uni-kl.de
117912027Sjungma@eit.uni-kl.de    int i = msb;
118012027Sjungma@eit.uni-kl.de    while( i >= lsb )
118112027Sjungma@eit.uni-kl.de    {
118212027Sjungma@eit.uni-kl.de        int value = 0;
118312027Sjungma@eit.uni-kl.de        for( int j = step - 1; j >= 0; -- j )
118412027Sjungma@eit.uni-kl.de	{
118512027Sjungma@eit.uni-kl.de            value += static_cast<int>( b.get_bit( i ) ) << j;
118612027Sjungma@eit.uni-kl.de            -- i;
118712027Sjungma@eit.uni-kl.de        }
118812027Sjungma@eit.uni-kl.de        if( value < 10 )
118912027Sjungma@eit.uni-kl.de            s += static_cast<char>( value + '0' );
119012027Sjungma@eit.uni-kl.de	else
119112027Sjungma@eit.uni-kl.de            s += static_cast<char>( value + 'a' - 10 );
119212027Sjungma@eit.uni-kl.de	if( i == -1 )
119312027Sjungma@eit.uni-kl.de	    s += '.';
119412027Sjungma@eit.uni-kl.de    }
119512027Sjungma@eit.uni-kl.de
119612027Sjungma@eit.uni-kl.de    if( lsb > 0 && fmt == SC_F )
119712027Sjungma@eit.uni-kl.de    {
119812027Sjungma@eit.uni-kl.de	for( int i = lsb / step; i > 0; i -- )
119912027Sjungma@eit.uni-kl.de	    s += '0';
120012027Sjungma@eit.uni-kl.de    }
120112027Sjungma@eit.uni-kl.de
120212027Sjungma@eit.uni-kl.de    if( s[s.length() - 1] == '.' )
120312027Sjungma@eit.uni-kl.de	s.discard( 1 );
120412027Sjungma@eit.uni-kl.de
120512027Sjungma@eit.uni-kl.de    if( fmt != SC_F )
120612027Sjungma@eit.uni-kl.de    {
120712027Sjungma@eit.uni-kl.de	if( msb < 0 )
120812027Sjungma@eit.uni-kl.de	    scfx_print_exp( s, ( msb + 1 ) / step );
120912027Sjungma@eit.uni-kl.de	else if( lsb > 0 )
121012027Sjungma@eit.uni-kl.de	    scfx_print_exp( s, lsb / step );
121112027Sjungma@eit.uni-kl.de    }
121212027Sjungma@eit.uni-kl.de
121312027Sjungma@eit.uni-kl.de    if( numrep == SC_CSD )
121412027Sjungma@eit.uni-kl.de	scfx_tc2csd( s, w_prefix );
121512027Sjungma@eit.uni-kl.de}
121612027Sjungma@eit.uni-kl.de
121712027Sjungma@eit.uni-kl.deconst char*
121812027Sjungma@eit.uni-kl.descfx_rep::to_string( sc_numrep numrep, int w_prefix,
121912027Sjungma@eit.uni-kl.de		     sc_fmt fmt, const scfx_params* params ) const
122012027Sjungma@eit.uni-kl.de{
122112027Sjungma@eit.uni-kl.de    static scfx_string s;
122212027Sjungma@eit.uni-kl.de
122312027Sjungma@eit.uni-kl.de    s.clear();
122412027Sjungma@eit.uni-kl.de
122512027Sjungma@eit.uni-kl.de    if( is_nan() )
122612027Sjungma@eit.uni-kl.de        scfx_print_nan( s );
122712027Sjungma@eit.uni-kl.de    else if( is_inf() )
122812027Sjungma@eit.uni-kl.de        scfx_print_inf( s, is_neg() );
122912027Sjungma@eit.uni-kl.de    else if( is_neg() && ! is_zero() &&
123012027Sjungma@eit.uni-kl.de	     ( numrep == SC_BIN_US ||
123112027Sjungma@eit.uni-kl.de	       numrep == SC_OCT_US ||
123212027Sjungma@eit.uni-kl.de	       numrep == SC_HEX_US ) )
123312027Sjungma@eit.uni-kl.de        s += "negative";
123412027Sjungma@eit.uni-kl.de    else if( numrep == SC_DEC || numrep == SC_NOBASE )
123512027Sjungma@eit.uni-kl.de        sc_dt::print_dec( s, *this, w_prefix, fmt );
123612027Sjungma@eit.uni-kl.de    else
123712027Sjungma@eit.uni-kl.de        sc_dt::print_other( s, *this, numrep, w_prefix, fmt, params );
123812027Sjungma@eit.uni-kl.de
123912027Sjungma@eit.uni-kl.de    return s;
124012027Sjungma@eit.uni-kl.de}
124112027Sjungma@eit.uni-kl.de
124212027Sjungma@eit.uni-kl.de
124312027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
124412027Sjungma@eit.uni-kl.de//  ADD
124512027Sjungma@eit.uni-kl.de//
124612027Sjungma@eit.uni-kl.de//  add two mantissas of the same size
124712027Sjungma@eit.uni-kl.de//  result has the same size
124812027Sjungma@eit.uni-kl.de//  returns carry of operation
124912027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
125012027Sjungma@eit.uni-kl.de
125112027Sjungma@eit.uni-kl.destatic inline
125212027Sjungma@eit.uni-kl.deint
125312027Sjungma@eit.uni-kl.deadd_mants( int size, scfx_mant& result,
125412027Sjungma@eit.uni-kl.de	   const scfx_mant& a, const scfx_mant& b )
125512027Sjungma@eit.uni-kl.de{
125612027Sjungma@eit.uni-kl.de    unsigned int carry = 0;
125712027Sjungma@eit.uni-kl.de
125812027Sjungma@eit.uni-kl.de    int index = 0;
125912027Sjungma@eit.uni-kl.de
126012027Sjungma@eit.uni-kl.de    do
126112027Sjungma@eit.uni-kl.de    {
126212027Sjungma@eit.uni-kl.de        word x = a[index];
126312027Sjungma@eit.uni-kl.de	word y = b[index];
126412027Sjungma@eit.uni-kl.de
126512027Sjungma@eit.uni-kl.de	y += carry;
126612027Sjungma@eit.uni-kl.de	carry = y < carry;
126712027Sjungma@eit.uni-kl.de	y += x;
126812027Sjungma@eit.uni-kl.de	carry += y < x;
126912027Sjungma@eit.uni-kl.de	result[index] = y;
127012027Sjungma@eit.uni-kl.de    }
127112027Sjungma@eit.uni-kl.de    while( ++ index < size );
127212027Sjungma@eit.uni-kl.de
127312027Sjungma@eit.uni-kl.de    return ( carry ? 1 : 0 );
127412027Sjungma@eit.uni-kl.de}
127512027Sjungma@eit.uni-kl.de
127612027Sjungma@eit.uni-kl.de
127712027Sjungma@eit.uni-kl.destatic inline
127812027Sjungma@eit.uni-kl.deint
127912027Sjungma@eit.uni-kl.desub_mants( int size, scfx_mant& result,
128012027Sjungma@eit.uni-kl.de	   const scfx_mant& a, const scfx_mant& b )
128112027Sjungma@eit.uni-kl.de{
128212027Sjungma@eit.uni-kl.de    unsigned carry = 0;
128312027Sjungma@eit.uni-kl.de
128412027Sjungma@eit.uni-kl.de    int index = 0;
128512027Sjungma@eit.uni-kl.de
128612027Sjungma@eit.uni-kl.de    do
128712027Sjungma@eit.uni-kl.de    {
128812027Sjungma@eit.uni-kl.de	word x = a[index];
128912027Sjungma@eit.uni-kl.de	word y = b[index];
129012027Sjungma@eit.uni-kl.de
129112027Sjungma@eit.uni-kl.de	y += carry;
129212027Sjungma@eit.uni-kl.de	carry = y < carry;
129312027Sjungma@eit.uni-kl.de	y = x - y;
129412027Sjungma@eit.uni-kl.de	carry += y > x;
129512027Sjungma@eit.uni-kl.de	result[index] = y;
129612027Sjungma@eit.uni-kl.de    }
129712027Sjungma@eit.uni-kl.de    while( ++ index < size );
129812027Sjungma@eit.uni-kl.de
129912027Sjungma@eit.uni-kl.de    return ( carry ? 1 : 0 );
130012027Sjungma@eit.uni-kl.de}
130112027Sjungma@eit.uni-kl.de
130212027Sjungma@eit.uni-kl.de
130312027Sjungma@eit.uni-kl.descfx_rep*
130412027Sjungma@eit.uni-kl.deadd_scfx_rep( const scfx_rep& lhs, const scfx_rep& rhs, int max_wl )
130512027Sjungma@eit.uni-kl.de{
130612027Sjungma@eit.uni-kl.de    scfx_rep& result = *new scfx_rep;
130712027Sjungma@eit.uni-kl.de
130812027Sjungma@eit.uni-kl.de    //
130912027Sjungma@eit.uni-kl.de    // check for special cases
131012027Sjungma@eit.uni-kl.de    //
131112027Sjungma@eit.uni-kl.de
131212027Sjungma@eit.uni-kl.de    if( lhs.is_nan() || rhs.is_nan()
131312027Sjungma@eit.uni-kl.de    ||  ( lhs.is_inf() && rhs.is_inf() && lhs.m_sign != rhs.m_sign ) )
131412027Sjungma@eit.uni-kl.de    {
131512027Sjungma@eit.uni-kl.de	result.set_nan();
131612027Sjungma@eit.uni-kl.de	return &result;
131712027Sjungma@eit.uni-kl.de    }
131812027Sjungma@eit.uni-kl.de
131912027Sjungma@eit.uni-kl.de    if( lhs.is_inf() )
132012027Sjungma@eit.uni-kl.de    {
132112027Sjungma@eit.uni-kl.de	result.set_inf( lhs.m_sign );
132212027Sjungma@eit.uni-kl.de	return &result;
132312027Sjungma@eit.uni-kl.de    }
132412027Sjungma@eit.uni-kl.de
132512027Sjungma@eit.uni-kl.de    if( rhs.is_inf() )
132612027Sjungma@eit.uni-kl.de    {
132712027Sjungma@eit.uni-kl.de	result.set_inf( rhs.m_sign );
132812027Sjungma@eit.uni-kl.de	return &result;
132912027Sjungma@eit.uni-kl.de    }
133012027Sjungma@eit.uni-kl.de
133112027Sjungma@eit.uni-kl.de    //
133212027Sjungma@eit.uni-kl.de    // align operands if needed
133312027Sjungma@eit.uni-kl.de    //
133412027Sjungma@eit.uni-kl.de
133512027Sjungma@eit.uni-kl.de    scfx_mant_ref lhs_mant;
133612027Sjungma@eit.uni-kl.de    scfx_mant_ref rhs_mant;
133712027Sjungma@eit.uni-kl.de
133812027Sjungma@eit.uni-kl.de    int len_mant = lhs.size();
133912027Sjungma@eit.uni-kl.de    int new_wp = lhs.m_wp;
134012027Sjungma@eit.uni-kl.de
134112027Sjungma@eit.uni-kl.de    align( lhs, rhs, new_wp, len_mant, lhs_mant, rhs_mant );
134212027Sjungma@eit.uni-kl.de
134312027Sjungma@eit.uni-kl.de    //
134412027Sjungma@eit.uni-kl.de    // size the result mantissa
134512027Sjungma@eit.uni-kl.de    //
134612027Sjungma@eit.uni-kl.de
134712027Sjungma@eit.uni-kl.de    result.resize_to( len_mant );
134812027Sjungma@eit.uni-kl.de    result.m_wp = new_wp;
134912027Sjungma@eit.uni-kl.de
135012027Sjungma@eit.uni-kl.de    //
135112027Sjungma@eit.uni-kl.de    // do it
135212027Sjungma@eit.uni-kl.de    //
135312027Sjungma@eit.uni-kl.de
135412027Sjungma@eit.uni-kl.de    if( lhs.m_sign == rhs.m_sign )
135512027Sjungma@eit.uni-kl.de    {
135612027Sjungma@eit.uni-kl.de	add_mants( len_mant, result.m_mant, lhs_mant, rhs_mant );
135712027Sjungma@eit.uni-kl.de	result.m_sign = lhs.m_sign;
135812027Sjungma@eit.uni-kl.de    }
135912027Sjungma@eit.uni-kl.de    else
136012027Sjungma@eit.uni-kl.de    {
136112027Sjungma@eit.uni-kl.de	int cmp = compare_abs( lhs, rhs );
136212027Sjungma@eit.uni-kl.de
136312027Sjungma@eit.uni-kl.de	if( cmp == 1 )
136412027Sjungma@eit.uni-kl.de	{
136512027Sjungma@eit.uni-kl.de	    sub_mants( len_mant, result.m_mant, lhs_mant, rhs_mant );
136612027Sjungma@eit.uni-kl.de	    result.m_sign = lhs.m_sign;
136712027Sjungma@eit.uni-kl.de	}
136812027Sjungma@eit.uni-kl.de	else if ( cmp == -1 )
136912027Sjungma@eit.uni-kl.de	{
137012027Sjungma@eit.uni-kl.de	    sub_mants( len_mant, result.m_mant, rhs_mant, lhs_mant );
137112027Sjungma@eit.uni-kl.de	    result.m_sign = rhs.m_sign;
137212027Sjungma@eit.uni-kl.de	}
137312027Sjungma@eit.uni-kl.de	else
137412027Sjungma@eit.uni-kl.de	{
137512027Sjungma@eit.uni-kl.de	    result.m_mant.clear();
137612027Sjungma@eit.uni-kl.de	    result.m_sign = 1;
137712027Sjungma@eit.uni-kl.de	}
137812027Sjungma@eit.uni-kl.de    }
137912027Sjungma@eit.uni-kl.de
138012027Sjungma@eit.uni-kl.de    result.find_sw();
138112027Sjungma@eit.uni-kl.de    result.round( max_wl );
138212027Sjungma@eit.uni-kl.de
138312027Sjungma@eit.uni-kl.de    return &result;
138412027Sjungma@eit.uni-kl.de}
138512027Sjungma@eit.uni-kl.de
138612027Sjungma@eit.uni-kl.de
138712027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
138812027Sjungma@eit.uni-kl.de//  SUB
138912027Sjungma@eit.uni-kl.de//
139012027Sjungma@eit.uni-kl.de//  sub two word's of the same size
139112027Sjungma@eit.uni-kl.de//  result has the same size
139212027Sjungma@eit.uni-kl.de//  returns carry of operation
139312027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
139412027Sjungma@eit.uni-kl.de
139512027Sjungma@eit.uni-kl.destatic inline
139612027Sjungma@eit.uni-kl.deint
139712027Sjungma@eit.uni-kl.desub_with_index(       scfx_mant& a, int a_msw, int /*a_lsw*/,
139812027Sjungma@eit.uni-kl.de		const scfx_mant& b, int b_msw, int b_lsw )
139912027Sjungma@eit.uni-kl.de{
140012027Sjungma@eit.uni-kl.de    unsigned carry = 0;
140112027Sjungma@eit.uni-kl.de
140212027Sjungma@eit.uni-kl.de    int size    = b_msw - b_lsw;
140312027Sjungma@eit.uni-kl.de    int a_index = a_msw - size;
140412027Sjungma@eit.uni-kl.de    int b_index = b_msw - size;
140512027Sjungma@eit.uni-kl.de
140612027Sjungma@eit.uni-kl.de    do
140712027Sjungma@eit.uni-kl.de    {
140812027Sjungma@eit.uni-kl.de	word x = a[a_index];
140912027Sjungma@eit.uni-kl.de	word y = b[b_index];
141012027Sjungma@eit.uni-kl.de
141112027Sjungma@eit.uni-kl.de	y += carry;
141212027Sjungma@eit.uni-kl.de	carry = y < carry;
141312027Sjungma@eit.uni-kl.de	y = x - y;
141412027Sjungma@eit.uni-kl.de	carry += y > x;
141512027Sjungma@eit.uni-kl.de	a[a_index] = y;
141612027Sjungma@eit.uni-kl.de
141712027Sjungma@eit.uni-kl.de	a_index ++;
141812027Sjungma@eit.uni-kl.de	b_index ++;
141912027Sjungma@eit.uni-kl.de    }
142012027Sjungma@eit.uni-kl.de    while( size -- );
142112027Sjungma@eit.uni-kl.de
142212027Sjungma@eit.uni-kl.de    if( carry )
142312027Sjungma@eit.uni-kl.de    {
142412027Sjungma@eit.uni-kl.de        // special case: a[a_msw + 1 ] == 1
142512027Sjungma@eit.uni-kl.de        a[a_msw + 1] = 0;
142612027Sjungma@eit.uni-kl.de    }
142712027Sjungma@eit.uni-kl.de
142812027Sjungma@eit.uni-kl.de    return ( carry ? 1 : 0 );
142912027Sjungma@eit.uni-kl.de}
143012027Sjungma@eit.uni-kl.de
143112027Sjungma@eit.uni-kl.de
143212027Sjungma@eit.uni-kl.descfx_rep*
143312027Sjungma@eit.uni-kl.desub_scfx_rep( const scfx_rep& lhs, const scfx_rep& rhs, int max_wl )
143412027Sjungma@eit.uni-kl.de{
143512027Sjungma@eit.uni-kl.de    scfx_rep& result = *new scfx_rep;
143612027Sjungma@eit.uni-kl.de
143712027Sjungma@eit.uni-kl.de    //
143812027Sjungma@eit.uni-kl.de    // check for special cases
143912027Sjungma@eit.uni-kl.de    //
144012027Sjungma@eit.uni-kl.de
144112027Sjungma@eit.uni-kl.de    if( lhs.is_nan() || rhs.is_nan()
144212027Sjungma@eit.uni-kl.de    ||  ( lhs.is_inf() && rhs.is_inf() && lhs.m_sign == rhs.m_sign ) )
144312027Sjungma@eit.uni-kl.de    {
144412027Sjungma@eit.uni-kl.de	result.set_nan();
144512027Sjungma@eit.uni-kl.de	return &result;
144612027Sjungma@eit.uni-kl.de    }
144712027Sjungma@eit.uni-kl.de
144812027Sjungma@eit.uni-kl.de    if( lhs.is_inf() )
144912027Sjungma@eit.uni-kl.de    {
145012027Sjungma@eit.uni-kl.de	result.set_inf( lhs.m_sign );
145112027Sjungma@eit.uni-kl.de	return &result;
145212027Sjungma@eit.uni-kl.de    }
145312027Sjungma@eit.uni-kl.de
145412027Sjungma@eit.uni-kl.de    if( rhs.is_inf() )
145512027Sjungma@eit.uni-kl.de    {
145612027Sjungma@eit.uni-kl.de	result.set_inf( -1 * rhs.m_sign );
145712027Sjungma@eit.uni-kl.de	return &result;
145812027Sjungma@eit.uni-kl.de    }
145912027Sjungma@eit.uni-kl.de
146012027Sjungma@eit.uni-kl.de    //
146112027Sjungma@eit.uni-kl.de    // align operands if needed
146212027Sjungma@eit.uni-kl.de    //
146312027Sjungma@eit.uni-kl.de
146412027Sjungma@eit.uni-kl.de    scfx_mant_ref lhs_mant;
146512027Sjungma@eit.uni-kl.de    scfx_mant_ref rhs_mant;
146612027Sjungma@eit.uni-kl.de
146712027Sjungma@eit.uni-kl.de    int len_mant = lhs.size();
146812027Sjungma@eit.uni-kl.de    int new_wp = lhs.m_wp;
146912027Sjungma@eit.uni-kl.de
147012027Sjungma@eit.uni-kl.de    align( lhs, rhs, new_wp, len_mant, lhs_mant, rhs_mant );
147112027Sjungma@eit.uni-kl.de
147212027Sjungma@eit.uni-kl.de    //
147312027Sjungma@eit.uni-kl.de    // size the result mantissa
147412027Sjungma@eit.uni-kl.de    //
147512027Sjungma@eit.uni-kl.de
147612027Sjungma@eit.uni-kl.de    result.resize_to( len_mant );
147712027Sjungma@eit.uni-kl.de    result.m_wp = new_wp;
147812027Sjungma@eit.uni-kl.de
147912027Sjungma@eit.uni-kl.de    //
148012027Sjungma@eit.uni-kl.de    // do it
148112027Sjungma@eit.uni-kl.de    //
148212027Sjungma@eit.uni-kl.de
148312027Sjungma@eit.uni-kl.de    if( lhs.m_sign != rhs.m_sign )
148412027Sjungma@eit.uni-kl.de    {
148512027Sjungma@eit.uni-kl.de	add_mants( len_mant, result.m_mant, lhs_mant, rhs_mant );
148612027Sjungma@eit.uni-kl.de	result.m_sign = lhs.m_sign;
148712027Sjungma@eit.uni-kl.de    }
148812027Sjungma@eit.uni-kl.de    else
148912027Sjungma@eit.uni-kl.de    {
149012027Sjungma@eit.uni-kl.de	int cmp = compare_abs( lhs, rhs );
149112027Sjungma@eit.uni-kl.de
149212027Sjungma@eit.uni-kl.de	if( cmp == 1 )
149312027Sjungma@eit.uni-kl.de	{
149412027Sjungma@eit.uni-kl.de	    sub_mants( len_mant, result.m_mant, lhs_mant, rhs_mant );
149512027Sjungma@eit.uni-kl.de	    result.m_sign = lhs.m_sign;
149612027Sjungma@eit.uni-kl.de	}
149712027Sjungma@eit.uni-kl.de	else if ( cmp == -1 )
149812027Sjungma@eit.uni-kl.de	{
149912027Sjungma@eit.uni-kl.de	    sub_mants( len_mant, result.m_mant, rhs_mant, lhs_mant );
150012027Sjungma@eit.uni-kl.de	    result.m_sign = -rhs.m_sign;
150112027Sjungma@eit.uni-kl.de	} else {
150212027Sjungma@eit.uni-kl.de	    result.m_mant.clear();
150312027Sjungma@eit.uni-kl.de	    result.m_sign = 1;
150412027Sjungma@eit.uni-kl.de	}
150512027Sjungma@eit.uni-kl.de    }
150612027Sjungma@eit.uni-kl.de
150712027Sjungma@eit.uni-kl.de    result.find_sw();
150812027Sjungma@eit.uni-kl.de    result.round( max_wl );
150912027Sjungma@eit.uni-kl.de
151012027Sjungma@eit.uni-kl.de    return &result;
151112027Sjungma@eit.uni-kl.de}
151212027Sjungma@eit.uni-kl.de
151312027Sjungma@eit.uni-kl.de
151412027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
151512027Sjungma@eit.uni-kl.de//  MUL
151612027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
151712027Sjungma@eit.uni-kl.de
151812027Sjungma@eit.uni-kl.deunion word_short
151912027Sjungma@eit.uni-kl.de{
152012027Sjungma@eit.uni-kl.de    word l;
152112027Sjungma@eit.uni-kl.de    struct
152212027Sjungma@eit.uni-kl.de    {
152312027Sjungma@eit.uni-kl.de#if defined( SC_BIG_ENDIAN )
152412027Sjungma@eit.uni-kl.de        half_word u;
152512027Sjungma@eit.uni-kl.de        half_word l;
152612027Sjungma@eit.uni-kl.de#elif defined( SC_LITTLE_ENDIAN )
152712027Sjungma@eit.uni-kl.de        half_word l;
152812027Sjungma@eit.uni-kl.de        half_word u;
152912027Sjungma@eit.uni-kl.de#endif
153012027Sjungma@eit.uni-kl.de    } s;
153112027Sjungma@eit.uni-kl.de};
153212027Sjungma@eit.uni-kl.de
153312027Sjungma@eit.uni-kl.de
153412027Sjungma@eit.uni-kl.de#if defined( SC_BIG_ENDIAN )
153512027Sjungma@eit.uni-kl.destatic const int half_word_incr = -1;
153612027Sjungma@eit.uni-kl.de#elif defined( SC_LITTLE_ENDIAN )
153712027Sjungma@eit.uni-kl.destatic const int half_word_incr = 1;
153812027Sjungma@eit.uni-kl.de#endif
153912027Sjungma@eit.uni-kl.de
154012027Sjungma@eit.uni-kl.de
154112027Sjungma@eit.uni-kl.devoid
154212027Sjungma@eit.uni-kl.demultiply( scfx_rep& result, const scfx_rep& lhs, const scfx_rep& rhs,
154312027Sjungma@eit.uni-kl.de	  int max_wl )
154412027Sjungma@eit.uni-kl.de{
154512027Sjungma@eit.uni-kl.de    //
154612027Sjungma@eit.uni-kl.de    // check for special cases
154712027Sjungma@eit.uni-kl.de    //
154812027Sjungma@eit.uni-kl.de
154912027Sjungma@eit.uni-kl.de    if( lhs.is_nan() || rhs.is_nan()
155012027Sjungma@eit.uni-kl.de    ||  (lhs.is_inf() && rhs.is_zero())
155112027Sjungma@eit.uni-kl.de    ||  (lhs.is_zero() && rhs.is_inf()) )
155212027Sjungma@eit.uni-kl.de    {
155312027Sjungma@eit.uni-kl.de	result.set_nan();
155412027Sjungma@eit.uni-kl.de	return;
155512027Sjungma@eit.uni-kl.de    }
155612027Sjungma@eit.uni-kl.de
155712027Sjungma@eit.uni-kl.de    if( lhs.is_inf() || rhs.is_inf() )
155812027Sjungma@eit.uni-kl.de    {
155912027Sjungma@eit.uni-kl.de	result.set_inf( lhs.m_sign * rhs.m_sign );
156012027Sjungma@eit.uni-kl.de	return;
156112027Sjungma@eit.uni-kl.de    }
156212027Sjungma@eit.uni-kl.de
156312027Sjungma@eit.uni-kl.de    if( lhs.is_zero() || rhs.is_zero() ) {
156412027Sjungma@eit.uni-kl.de	result.set_zero( lhs.m_sign * rhs.m_sign );
156512027Sjungma@eit.uni-kl.de	return;
156612027Sjungma@eit.uni-kl.de    }
156712027Sjungma@eit.uni-kl.de
156812027Sjungma@eit.uni-kl.de    //
156912027Sjungma@eit.uni-kl.de    // do it
157012027Sjungma@eit.uni-kl.de    //
157112027Sjungma@eit.uni-kl.de
157212027Sjungma@eit.uni-kl.de    int len_lhs = lhs.m_msw - lhs.m_lsw + 1;
157312027Sjungma@eit.uni-kl.de    int len_rhs = rhs.m_msw - rhs.m_lsw + 1;
157412027Sjungma@eit.uni-kl.de
157512027Sjungma@eit.uni-kl.de    int new_size = sc_max( min_mant, len_lhs + len_rhs );
157612027Sjungma@eit.uni-kl.de    int new_wp   = ( lhs.m_wp - lhs.m_lsw ) + ( rhs.m_wp - rhs.m_lsw );
157712027Sjungma@eit.uni-kl.de    int new_sign = lhs.m_sign * rhs.m_sign;
157812027Sjungma@eit.uni-kl.de
157912027Sjungma@eit.uni-kl.de    result.resize_to( new_size );
158012027Sjungma@eit.uni-kl.de    result.m_mant.clear();
158112027Sjungma@eit.uni-kl.de    result.m_wp    = new_wp;
158212027Sjungma@eit.uni-kl.de    result.m_sign  = new_sign;
158312027Sjungma@eit.uni-kl.de    result.m_state = scfx_rep::normal;
158412027Sjungma@eit.uni-kl.de
158512027Sjungma@eit.uni-kl.de    half_word *s1 = lhs.m_mant.half_addr( lhs.m_lsw );
158612027Sjungma@eit.uni-kl.de    half_word *s2 = rhs.m_mant.half_addr( rhs.m_lsw );
158712027Sjungma@eit.uni-kl.de
158812027Sjungma@eit.uni-kl.de    half_word *t = result.m_mant.half_addr();
158912027Sjungma@eit.uni-kl.de
159012027Sjungma@eit.uni-kl.de    len_lhs <<= 1;
159112027Sjungma@eit.uni-kl.de    len_rhs <<= 1;
159212027Sjungma@eit.uni-kl.de
159312027Sjungma@eit.uni-kl.de    int i1, i2;
159412027Sjungma@eit.uni-kl.de
159512027Sjungma@eit.uni-kl.de    for( i1 = 0; i1 * half_word_incr < len_lhs; i1 += half_word_incr )
159612027Sjungma@eit.uni-kl.de    {
159712027Sjungma@eit.uni-kl.de	word_short ls;
159812027Sjungma@eit.uni-kl.de	ls.l = 0;
159912027Sjungma@eit.uni-kl.de
160012027Sjungma@eit.uni-kl.de	half_word v1 = s1[i1];
160112027Sjungma@eit.uni-kl.de
160212027Sjungma@eit.uni-kl.de	for( i2  = 0; i2 * half_word_incr < len_rhs; i2 += half_word_incr )
160312027Sjungma@eit.uni-kl.de	{
160412027Sjungma@eit.uni-kl.de	    ls.l  += v1 * s2[i2];
160512027Sjungma@eit.uni-kl.de	    ls.s.l = ls.s.u + ( ( t[i2] += ls.s.l ) < ls.s.l );
160612027Sjungma@eit.uni-kl.de	    ls.s.u = 0;
160712027Sjungma@eit.uni-kl.de	}
160812027Sjungma@eit.uni-kl.de
160912027Sjungma@eit.uni-kl.de	t[i2] = ls.s.l;
161012027Sjungma@eit.uni-kl.de	t += half_word_incr;
161112027Sjungma@eit.uni-kl.de    }
161212027Sjungma@eit.uni-kl.de
161312027Sjungma@eit.uni-kl.de    result.find_sw();
161412027Sjungma@eit.uni-kl.de    result.round( max_wl );
161512027Sjungma@eit.uni-kl.de}
161612027Sjungma@eit.uni-kl.de
161712027Sjungma@eit.uni-kl.de
161812027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
161912027Sjungma@eit.uni-kl.de//  DIV
162012027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
162112027Sjungma@eit.uni-kl.de
162212027Sjungma@eit.uni-kl.descfx_rep*
162312027Sjungma@eit.uni-kl.dediv_scfx_rep( const scfx_rep& lhs, const scfx_rep& rhs, int div_wl )
162412027Sjungma@eit.uni-kl.de{
162512027Sjungma@eit.uni-kl.de    scfx_rep& result = *new scfx_rep;
162612027Sjungma@eit.uni-kl.de
162712027Sjungma@eit.uni-kl.de    //
162812027Sjungma@eit.uni-kl.de    // check for special cases
162912027Sjungma@eit.uni-kl.de    //
163012027Sjungma@eit.uni-kl.de
163112027Sjungma@eit.uni-kl.de    if( lhs.is_nan() || rhs.is_nan() || (lhs.is_inf() && rhs.is_inf()) ||
163212027Sjungma@eit.uni-kl.de	(lhs.is_zero() && rhs.is_zero()) )
163312027Sjungma@eit.uni-kl.de    {
163412027Sjungma@eit.uni-kl.de	result.set_nan();
163512027Sjungma@eit.uni-kl.de	return &result;
163612027Sjungma@eit.uni-kl.de    }
163712027Sjungma@eit.uni-kl.de
163812027Sjungma@eit.uni-kl.de    if( lhs.is_inf() || rhs.is_zero() )
163912027Sjungma@eit.uni-kl.de    {
164012027Sjungma@eit.uni-kl.de	result.set_inf( lhs.m_sign * rhs.m_sign );
164112027Sjungma@eit.uni-kl.de	return &result;
164212027Sjungma@eit.uni-kl.de    }
164312027Sjungma@eit.uni-kl.de
164412027Sjungma@eit.uni-kl.de    if( lhs.is_zero() || rhs.is_inf() )
164512027Sjungma@eit.uni-kl.de    {
164612027Sjungma@eit.uni-kl.de	result.set_zero( lhs.m_sign * rhs.m_sign );
164712027Sjungma@eit.uni-kl.de	return &result;
164812027Sjungma@eit.uni-kl.de    }
164912027Sjungma@eit.uni-kl.de
165012027Sjungma@eit.uni-kl.de    //
165112027Sjungma@eit.uni-kl.de    // do it
165212027Sjungma@eit.uni-kl.de    //
165312027Sjungma@eit.uni-kl.de
165412027Sjungma@eit.uni-kl.de    // compute one bit more for rounding
165512027Sjungma@eit.uni-kl.de    div_wl ++;
165612027Sjungma@eit.uni-kl.de
165712027Sjungma@eit.uni-kl.de    result.resize_to( sc_max( n_word( div_wl ) + 1, min_mant ) );
165812027Sjungma@eit.uni-kl.de    result.m_mant.clear();
165912027Sjungma@eit.uni-kl.de    result.m_sign = lhs.m_sign * rhs.m_sign;
166012027Sjungma@eit.uni-kl.de
166112027Sjungma@eit.uni-kl.de    int msb_lhs = scfx_find_msb( lhs.m_mant[lhs.m_msw] )
166212027Sjungma@eit.uni-kl.de	        + ( lhs.m_msw - lhs.m_wp ) * bits_in_word;
166312027Sjungma@eit.uni-kl.de    int msb_rhs = scfx_find_msb( rhs.m_mant[rhs.m_msw] )
166412027Sjungma@eit.uni-kl.de	        + ( rhs.m_msw - rhs.m_wp ) * bits_in_word;
166512027Sjungma@eit.uni-kl.de
166612027Sjungma@eit.uni-kl.de    int msb_res = msb_lhs - msb_rhs;
166712027Sjungma@eit.uni-kl.de    int to_shift = -msb_res % bits_in_word;
166812027Sjungma@eit.uni-kl.de    int result_index;
166912027Sjungma@eit.uni-kl.de
167012027Sjungma@eit.uni-kl.de    int c = ( msb_res % bits_in_word >= 0 ) ? 1 : 0;
167112027Sjungma@eit.uni-kl.de
167212027Sjungma@eit.uni-kl.de    result_index = (result.size() - c) * bits_in_word + msb_res % bits_in_word;
167312027Sjungma@eit.uni-kl.de    result.m_wp   = (result.size() - c) - msb_res / bits_in_word;
167412027Sjungma@eit.uni-kl.de
167512027Sjungma@eit.uni-kl.de    scfx_rep remainder = lhs;
167612027Sjungma@eit.uni-kl.de
167712027Sjungma@eit.uni-kl.de    // align msb from remainder to msb from rhs
167812027Sjungma@eit.uni-kl.de    remainder.lshift( to_shift );
167912027Sjungma@eit.uni-kl.de
168012027Sjungma@eit.uni-kl.de    // make sure msw( remainder ) < size - 1
168112027Sjungma@eit.uni-kl.de    if( remainder.m_msw == remainder.size() - 1 )
168212027Sjungma@eit.uni-kl.de	remainder.resize_to( remainder.size() + 1, 1 );
168312027Sjungma@eit.uni-kl.de
168412027Sjungma@eit.uni-kl.de    // make sure msw( remainder ) >= msw( rhs )!
168512027Sjungma@eit.uni-kl.de    int msw_diff = rhs.m_msw - remainder.m_msw;
168612027Sjungma@eit.uni-kl.de    if (msw_diff > 0)
168712027Sjungma@eit.uni-kl.de	remainder.resize_to( remainder.size() + msw_diff, -1 );
168812027Sjungma@eit.uni-kl.de
168912027Sjungma@eit.uni-kl.de    int counter;
169012027Sjungma@eit.uni-kl.de
169112027Sjungma@eit.uni-kl.de    for( counter = div_wl; counter && ! remainder.is_zero(); counter -- )
169212027Sjungma@eit.uni-kl.de    {
169312027Sjungma@eit.uni-kl.de	if( compare_msw_ff( rhs, remainder ) <= 0 )
169412027Sjungma@eit.uni-kl.de	{
169512027Sjungma@eit.uni-kl.de	    result.set_bin( result_index );
169612027Sjungma@eit.uni-kl.de	    sub_with_index( remainder.m_mant, remainder.m_msw, remainder.m_lsw,
169712027Sjungma@eit.uni-kl.de			    rhs.m_mant, rhs.m_msw, rhs.m_lsw );
169812027Sjungma@eit.uni-kl.de	}
169912027Sjungma@eit.uni-kl.de	result_index --;
170012027Sjungma@eit.uni-kl.de	remainder.shift_left( 1 );
170112027Sjungma@eit.uni-kl.de        remainder.m_lsw = remainder.find_lsw();
170212027Sjungma@eit.uni-kl.de    }
170312027Sjungma@eit.uni-kl.de
170412027Sjungma@eit.uni-kl.de    // perform convergent rounding, if needed
170512027Sjungma@eit.uni-kl.de    if( counter == 0 )
170612027Sjungma@eit.uni-kl.de    {
170712027Sjungma@eit.uni-kl.de	int index = result_index + 1 - result.m_wp * bits_in_word;
170812027Sjungma@eit.uni-kl.de
170912027Sjungma@eit.uni-kl.de	scfx_index x = result.calc_indices( index );
171012027Sjungma@eit.uni-kl.de	scfx_index x1 = result.calc_indices( index + 1 );
171112027Sjungma@eit.uni-kl.de
171212027Sjungma@eit.uni-kl.de	if( result.o_bit_at( x ) && result.o_bit_at( x1 ) )
171312027Sjungma@eit.uni-kl.de	    result.q_incr( x );
171412027Sjungma@eit.uni-kl.de
171512027Sjungma@eit.uni-kl.de	result.m_r_flag = true;
171612027Sjungma@eit.uni-kl.de    }
171712027Sjungma@eit.uni-kl.de
171812027Sjungma@eit.uni-kl.de    result.find_sw();
171912027Sjungma@eit.uni-kl.de
172012027Sjungma@eit.uni-kl.de    return &result;
172112027Sjungma@eit.uni-kl.de}
172212027Sjungma@eit.uni-kl.de
172312027Sjungma@eit.uni-kl.de
172412027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
172512027Sjungma@eit.uni-kl.de//  destructive shift mantissa to the left
172612027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
172712027Sjungma@eit.uni-kl.de
172812027Sjungma@eit.uni-kl.devoid
172912027Sjungma@eit.uni-kl.descfx_rep::lshift( int n )
173012027Sjungma@eit.uni-kl.de{
173112027Sjungma@eit.uni-kl.de    if( n == 0 )
173212027Sjungma@eit.uni-kl.de        return;
173312027Sjungma@eit.uni-kl.de
173412027Sjungma@eit.uni-kl.de    if( n < 0 )
173512027Sjungma@eit.uni-kl.de    {
173612027Sjungma@eit.uni-kl.de        rshift( -n );
173712027Sjungma@eit.uni-kl.de	return;
173812027Sjungma@eit.uni-kl.de    }
173912027Sjungma@eit.uni-kl.de
174012027Sjungma@eit.uni-kl.de    if( is_normal() )
174112027Sjungma@eit.uni-kl.de    {
174212027Sjungma@eit.uni-kl.de        int shift_bits  = n % bits_in_word;
174312027Sjungma@eit.uni-kl.de	int shift_words = n / bits_in_word;
174412027Sjungma@eit.uni-kl.de
174512027Sjungma@eit.uni-kl.de	// resize if needed
174612027Sjungma@eit.uni-kl.de	if( m_msw == size() - 1 &&
174712027Sjungma@eit.uni-kl.de	    scfx_find_msb( m_mant[m_msw] ) >= bits_in_word - shift_bits )
174812027Sjungma@eit.uni-kl.de	    resize_to( size() + 1, 1 );
174912027Sjungma@eit.uni-kl.de
175012027Sjungma@eit.uni-kl.de	// do it
175112027Sjungma@eit.uni-kl.de	m_wp -= shift_words;
175212027Sjungma@eit.uni-kl.de	shift_left( shift_bits );
175312027Sjungma@eit.uni-kl.de	find_sw();
175412027Sjungma@eit.uni-kl.de    }
175512027Sjungma@eit.uni-kl.de}
175612027Sjungma@eit.uni-kl.de
175712027Sjungma@eit.uni-kl.de
175812027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
175912027Sjungma@eit.uni-kl.de//  destructive shift mantissa to the right
176012027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
176112027Sjungma@eit.uni-kl.de
176212027Sjungma@eit.uni-kl.devoid
176312027Sjungma@eit.uni-kl.descfx_rep::rshift( int n )
176412027Sjungma@eit.uni-kl.de{
176512027Sjungma@eit.uni-kl.de    if( n == 0 )
176612027Sjungma@eit.uni-kl.de        return;
176712027Sjungma@eit.uni-kl.de
176812027Sjungma@eit.uni-kl.de    if( n < 0 )
176912027Sjungma@eit.uni-kl.de    {
177012027Sjungma@eit.uni-kl.de        lshift( -n );
177112027Sjungma@eit.uni-kl.de	return;
177212027Sjungma@eit.uni-kl.de    }
177312027Sjungma@eit.uni-kl.de
177412027Sjungma@eit.uni-kl.de    if( is_normal() )
177512027Sjungma@eit.uni-kl.de    {
177612027Sjungma@eit.uni-kl.de        int shift_bits  = n % bits_in_word;
177712027Sjungma@eit.uni-kl.de	int shift_words = n / bits_in_word;
177812027Sjungma@eit.uni-kl.de
177912027Sjungma@eit.uni-kl.de	// resize if needed
178012027Sjungma@eit.uni-kl.de	if( m_lsw == 0 && scfx_find_lsb( m_mant[m_lsw] ) < shift_bits )
178112027Sjungma@eit.uni-kl.de	    resize_to( size() + 1, -1 );
178212027Sjungma@eit.uni-kl.de
178312027Sjungma@eit.uni-kl.de	// do it
178412027Sjungma@eit.uni-kl.de	m_wp += shift_words;
178512027Sjungma@eit.uni-kl.de	shift_right( shift_bits );
178612027Sjungma@eit.uni-kl.de	find_sw();
178712027Sjungma@eit.uni-kl.de    }
178812027Sjungma@eit.uni-kl.de}
178912027Sjungma@eit.uni-kl.de
179012027Sjungma@eit.uni-kl.de
179112027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
179212027Sjungma@eit.uni-kl.de//  FRIEND FUNCTION : compare_abs
179312027Sjungma@eit.uni-kl.de//
179412027Sjungma@eit.uni-kl.de//  Compares the absolute values of two scfx_reps, excluding the special cases.
179512027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
179612027Sjungma@eit.uni-kl.de
179712027Sjungma@eit.uni-kl.deint
179812027Sjungma@eit.uni-kl.decompare_abs( const scfx_rep& a, const scfx_rep& b )
179912027Sjungma@eit.uni-kl.de{
180012027Sjungma@eit.uni-kl.de    // check for zero
180112027Sjungma@eit.uni-kl.de
180212027Sjungma@eit.uni-kl.de    word a_word = a.m_mant[a.m_msw];
180312027Sjungma@eit.uni-kl.de    word b_word = b.m_mant[b.m_msw];
180412027Sjungma@eit.uni-kl.de
180512027Sjungma@eit.uni-kl.de    if( a_word == 0 || b_word == 0 )
180612027Sjungma@eit.uni-kl.de    {
180712027Sjungma@eit.uni-kl.de	if( a_word != 0 )
180812027Sjungma@eit.uni-kl.de	    return 1;
180912027Sjungma@eit.uni-kl.de	if( b_word != 0 )
181012027Sjungma@eit.uni-kl.de	    return -1;
181112027Sjungma@eit.uni-kl.de	return 0;
181212027Sjungma@eit.uni-kl.de    }
181312027Sjungma@eit.uni-kl.de
181412027Sjungma@eit.uni-kl.de    // compare msw index
181512027Sjungma@eit.uni-kl.de
181612027Sjungma@eit.uni-kl.de    int a_msw = a.m_msw - a.m_wp;
181712027Sjungma@eit.uni-kl.de    int b_msw = b.m_msw - b.m_wp;
181812027Sjungma@eit.uni-kl.de
181912027Sjungma@eit.uni-kl.de    if( a_msw > b_msw )
182012027Sjungma@eit.uni-kl.de	return 1;
182112027Sjungma@eit.uni-kl.de
182212027Sjungma@eit.uni-kl.de    if( a_msw < b_msw )
182312027Sjungma@eit.uni-kl.de	return -1;
182412027Sjungma@eit.uni-kl.de
182512027Sjungma@eit.uni-kl.de    // compare content
182612027Sjungma@eit.uni-kl.de
182712027Sjungma@eit.uni-kl.de    int a_i = a.m_msw;
182812027Sjungma@eit.uni-kl.de    int b_i = b.m_msw;
182912027Sjungma@eit.uni-kl.de
183012027Sjungma@eit.uni-kl.de    while( a_i >= a.m_lsw && b_i >= b.m_lsw )
183112027Sjungma@eit.uni-kl.de    {
183212027Sjungma@eit.uni-kl.de	a_word = a.m_mant[a_i];
183312027Sjungma@eit.uni-kl.de	b_word = b.m_mant[b_i];
183412027Sjungma@eit.uni-kl.de	if( a_word > b_word )
183512027Sjungma@eit.uni-kl.de	    return 1;
183612027Sjungma@eit.uni-kl.de	if( a_word < b_word )
183712027Sjungma@eit.uni-kl.de	    return -1;
183812027Sjungma@eit.uni-kl.de	-- a_i;
183912027Sjungma@eit.uni-kl.de	-- b_i;
184012027Sjungma@eit.uni-kl.de    }
184112027Sjungma@eit.uni-kl.de
184212027Sjungma@eit.uni-kl.de    bool a_zero = true;
184312027Sjungma@eit.uni-kl.de    while( a_i >= a.m_lsw )
184412027Sjungma@eit.uni-kl.de    {
184512027Sjungma@eit.uni-kl.de	a_zero = a_zero && ( a.m_mant[a_i] == 0 );
184612027Sjungma@eit.uni-kl.de	-- a_i;
184712027Sjungma@eit.uni-kl.de    }
184812027Sjungma@eit.uni-kl.de
184912027Sjungma@eit.uni-kl.de    bool b_zero = true;
185012027Sjungma@eit.uni-kl.de    while( b_i >= b.m_lsw )
185112027Sjungma@eit.uni-kl.de    {
185212027Sjungma@eit.uni-kl.de	b_zero = b_zero && ( b.m_mant[b_i] == 0 );
185312027Sjungma@eit.uni-kl.de	-- b_i;
185412027Sjungma@eit.uni-kl.de    }
185512027Sjungma@eit.uni-kl.de
185612027Sjungma@eit.uni-kl.de    // assertion: a_zero || b_zero == true
185712027Sjungma@eit.uni-kl.de
185812027Sjungma@eit.uni-kl.de    if( ! a_zero && b_zero )
185912027Sjungma@eit.uni-kl.de	return 1;
186012027Sjungma@eit.uni-kl.de
186112027Sjungma@eit.uni-kl.de    if( a_zero && ! b_zero )
186212027Sjungma@eit.uni-kl.de	return -1;
186312027Sjungma@eit.uni-kl.de
186412027Sjungma@eit.uni-kl.de    return 0;
186512027Sjungma@eit.uni-kl.de}
186612027Sjungma@eit.uni-kl.de
186712027Sjungma@eit.uni-kl.de
186812027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
186912027Sjungma@eit.uni-kl.de//  FRIEND FUNCTION : cmp_scfx_rep
187012027Sjungma@eit.uni-kl.de//
187112027Sjungma@eit.uni-kl.de//  Compares the values of two scfx_reps, including the special cases.
187212027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
187312027Sjungma@eit.uni-kl.de
187412027Sjungma@eit.uni-kl.deint
187512027Sjungma@eit.uni-kl.decmp_scfx_rep( const scfx_rep& a, const scfx_rep& b )
187612027Sjungma@eit.uni-kl.de{
187712027Sjungma@eit.uni-kl.de    // handle special cases
187812027Sjungma@eit.uni-kl.de
187912027Sjungma@eit.uni-kl.de    if( a.is_nan() || b.is_nan() )
188012027Sjungma@eit.uni-kl.de    {
188112027Sjungma@eit.uni-kl.de#if 0
188212027Sjungma@eit.uni-kl.de	if( a.is_nan() && b.is_nan() )
188312027Sjungma@eit.uni-kl.de	{
188412027Sjungma@eit.uni-kl.de	    return 0;
188512027Sjungma@eit.uni-kl.de	}
188612027Sjungma@eit.uni-kl.de#endif
188712027Sjungma@eit.uni-kl.de	return 2;
188812027Sjungma@eit.uni-kl.de    }
188912027Sjungma@eit.uni-kl.de
189012027Sjungma@eit.uni-kl.de    if( a.is_inf() || b.is_inf() )
189112027Sjungma@eit.uni-kl.de    {
189212027Sjungma@eit.uni-kl.de	if( a.is_inf() )
189312027Sjungma@eit.uni-kl.de	{
189412027Sjungma@eit.uni-kl.de	    if( ! a.is_neg() )
189512027Sjungma@eit.uni-kl.de	    {
189612027Sjungma@eit.uni-kl.de		if( b.is_inf() && ! b.is_neg() )
189712027Sjungma@eit.uni-kl.de		{
189812027Sjungma@eit.uni-kl.de		    return 0;
189912027Sjungma@eit.uni-kl.de		}
190012027Sjungma@eit.uni-kl.de		else
190112027Sjungma@eit.uni-kl.de		{
190212027Sjungma@eit.uni-kl.de		    return 1;
190312027Sjungma@eit.uni-kl.de		}
190412027Sjungma@eit.uni-kl.de	    }
190512027Sjungma@eit.uni-kl.de	    else
190612027Sjungma@eit.uni-kl.de	    {
190712027Sjungma@eit.uni-kl.de		if( b.is_inf() && b.is_neg() )
190812027Sjungma@eit.uni-kl.de		{
190912027Sjungma@eit.uni-kl.de		    return 0;
191012027Sjungma@eit.uni-kl.de		}
191112027Sjungma@eit.uni-kl.de		else
191212027Sjungma@eit.uni-kl.de		{
191312027Sjungma@eit.uni-kl.de		    return -1;
191412027Sjungma@eit.uni-kl.de		}
191512027Sjungma@eit.uni-kl.de	    }
191612027Sjungma@eit.uni-kl.de	}
191712027Sjungma@eit.uni-kl.de	if( b.is_inf() )
191812027Sjungma@eit.uni-kl.de	{
191912027Sjungma@eit.uni-kl.de	    if( ! b.is_neg() )
192012027Sjungma@eit.uni-kl.de	    {
192112027Sjungma@eit.uni-kl.de		return -1;
192212027Sjungma@eit.uni-kl.de	    }
192312027Sjungma@eit.uni-kl.de	    else
192412027Sjungma@eit.uni-kl.de	    {
192512027Sjungma@eit.uni-kl.de		return 1;
192612027Sjungma@eit.uni-kl.de	    }
192712027Sjungma@eit.uni-kl.de	}
192812027Sjungma@eit.uni-kl.de    }
192912027Sjungma@eit.uni-kl.de
193012027Sjungma@eit.uni-kl.de    if( a.is_zero() && b.is_zero() )
193112027Sjungma@eit.uni-kl.de    {
193212027Sjungma@eit.uni-kl.de	return 0;
193312027Sjungma@eit.uni-kl.de    }
193412027Sjungma@eit.uni-kl.de
193512027Sjungma@eit.uni-kl.de    // compare sign
193612027Sjungma@eit.uni-kl.de
193712027Sjungma@eit.uni-kl.de    if( a.m_sign != b.m_sign )
193812027Sjungma@eit.uni-kl.de    {
193912027Sjungma@eit.uni-kl.de	return a.m_sign;
194012027Sjungma@eit.uni-kl.de    }
194112027Sjungma@eit.uni-kl.de
194212027Sjungma@eit.uni-kl.de    return ( a.m_sign * compare_abs( a, b ) );
194312027Sjungma@eit.uni-kl.de}
194412027Sjungma@eit.uni-kl.de
194512027Sjungma@eit.uni-kl.de
194612027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
194712027Sjungma@eit.uni-kl.de//  PRIVATE METHOD : quantization
194812027Sjungma@eit.uni-kl.de//
194912027Sjungma@eit.uni-kl.de//  Performs destructive quantization.
195012027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
195112027Sjungma@eit.uni-kl.de
195212027Sjungma@eit.uni-kl.devoid
195312027Sjungma@eit.uni-kl.descfx_rep::quantization( const scfx_params& params, bool& q_flag )
195412027Sjungma@eit.uni-kl.de{
195512027Sjungma@eit.uni-kl.de    scfx_index x = calc_indices( params.iwl() - params.wl() );
195612027Sjungma@eit.uni-kl.de
195712027Sjungma@eit.uni-kl.de    if( x.wi() < 0 )
195812027Sjungma@eit.uni-kl.de        return;
195912027Sjungma@eit.uni-kl.de
196012027Sjungma@eit.uni-kl.de    if( x.wi() >= size() )
196112027Sjungma@eit.uni-kl.de        resize_to( x.wi() + 1, 1 );
196212027Sjungma@eit.uni-kl.de
196312027Sjungma@eit.uni-kl.de    bool qb = q_bit( x );
196412027Sjungma@eit.uni-kl.de    bool qz = q_zero( x );
196512027Sjungma@eit.uni-kl.de
196612027Sjungma@eit.uni-kl.de    q_flag = ( qb || ! qz );
196712027Sjungma@eit.uni-kl.de
196812027Sjungma@eit.uni-kl.de    if( q_flag )
196912027Sjungma@eit.uni-kl.de    {
197012027Sjungma@eit.uni-kl.de        switch( params.q_mode() )
197112027Sjungma@eit.uni-kl.de	{
197212027Sjungma@eit.uni-kl.de            case SC_TRN:			// truncation
197312027Sjungma@eit.uni-kl.de	    {
197412027Sjungma@eit.uni-kl.de	        if( is_neg() )
197512027Sjungma@eit.uni-kl.de		    q_incr( x );
197612027Sjungma@eit.uni-kl.de		break;
197712027Sjungma@eit.uni-kl.de	    }
197812027Sjungma@eit.uni-kl.de            case SC_RND:			// rounding to plus infinity
197912027Sjungma@eit.uni-kl.de	    {
198012027Sjungma@eit.uni-kl.de	        if( ! is_neg() )
198112027Sjungma@eit.uni-kl.de		{
198212027Sjungma@eit.uni-kl.de		    if( qb )
198312027Sjungma@eit.uni-kl.de			q_incr( x );
198412027Sjungma@eit.uni-kl.de		}
198512027Sjungma@eit.uni-kl.de		else
198612027Sjungma@eit.uni-kl.de		{
198712027Sjungma@eit.uni-kl.de		    if( qb && ! qz )
198812027Sjungma@eit.uni-kl.de			q_incr( x );
198912027Sjungma@eit.uni-kl.de		}
199012027Sjungma@eit.uni-kl.de		break;
199112027Sjungma@eit.uni-kl.de	    }
199212027Sjungma@eit.uni-kl.de            case SC_TRN_ZERO:			// truncation to zero
199312027Sjungma@eit.uni-kl.de	    {
199412027Sjungma@eit.uni-kl.de	        break;
199512027Sjungma@eit.uni-kl.de	    }
199612027Sjungma@eit.uni-kl.de            case SC_RND_INF:			// rounding to infinity
199712027Sjungma@eit.uni-kl.de	    {
199812027Sjungma@eit.uni-kl.de	        if( qb )
199912027Sjungma@eit.uni-kl.de		    q_incr( x );
200012027Sjungma@eit.uni-kl.de		break;
200112027Sjungma@eit.uni-kl.de	    }
200212027Sjungma@eit.uni-kl.de            case SC_RND_CONV:			// convergent rounding
200312027Sjungma@eit.uni-kl.de	    {
200412027Sjungma@eit.uni-kl.de		if( (qb && ! qz) || (qb && qz && q_odd( x )) )
200512027Sjungma@eit.uni-kl.de		    q_incr( x );
200612027Sjungma@eit.uni-kl.de		break;
200712027Sjungma@eit.uni-kl.de	    }
200812027Sjungma@eit.uni-kl.de            case SC_RND_ZERO:			// rounding to zero
200912027Sjungma@eit.uni-kl.de	    {
201012027Sjungma@eit.uni-kl.de		if( qb && ! qz )
201112027Sjungma@eit.uni-kl.de		    q_incr( x );
201212027Sjungma@eit.uni-kl.de		break;
201312027Sjungma@eit.uni-kl.de	    }
201412027Sjungma@eit.uni-kl.de            case SC_RND_MIN_INF:		// rounding to minus infinity
201512027Sjungma@eit.uni-kl.de	    {
201612027Sjungma@eit.uni-kl.de		if( ! is_neg() )
201712027Sjungma@eit.uni-kl.de		{
201812027Sjungma@eit.uni-kl.de		    if( qb && ! qz )
201912027Sjungma@eit.uni-kl.de			q_incr( x );
202012027Sjungma@eit.uni-kl.de		}
202112027Sjungma@eit.uni-kl.de		else
202212027Sjungma@eit.uni-kl.de		{
202312027Sjungma@eit.uni-kl.de		    if( qb )
202412027Sjungma@eit.uni-kl.de			q_incr( x );
202512027Sjungma@eit.uni-kl.de		}
202612027Sjungma@eit.uni-kl.de		break;
202712027Sjungma@eit.uni-kl.de	    }
202812027Sjungma@eit.uni-kl.de            default:
202912027Sjungma@eit.uni-kl.de	        ;
203012027Sjungma@eit.uni-kl.de	}
203112027Sjungma@eit.uni-kl.de	q_clear( x );
203212027Sjungma@eit.uni-kl.de
203312027Sjungma@eit.uni-kl.de	find_sw();
203412027Sjungma@eit.uni-kl.de    }
203512027Sjungma@eit.uni-kl.de}
203612027Sjungma@eit.uni-kl.de
203712027Sjungma@eit.uni-kl.de
203812027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
203912027Sjungma@eit.uni-kl.de//  PRIVATE METHOD : overflow
204012027Sjungma@eit.uni-kl.de//
204112027Sjungma@eit.uni-kl.de//  Performs destructive overflow handling.
204212027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
204312027Sjungma@eit.uni-kl.de
204412027Sjungma@eit.uni-kl.devoid
204512027Sjungma@eit.uni-kl.descfx_rep::overflow( const scfx_params& params, bool& o_flag )
204612027Sjungma@eit.uni-kl.de{
204712027Sjungma@eit.uni-kl.de    scfx_index x = calc_indices( params.iwl() - 1 );
204812027Sjungma@eit.uni-kl.de
204912027Sjungma@eit.uni-kl.de    if( x.wi() >= size() )
205012027Sjungma@eit.uni-kl.de        resize_to( x.wi() + 1, 1 );
205112027Sjungma@eit.uni-kl.de
205212027Sjungma@eit.uni-kl.de    if( x.wi() < 0 )
205312027Sjungma@eit.uni-kl.de    {
205412027Sjungma@eit.uni-kl.de        resize_to( size() - x.wi(), -1 );
205512027Sjungma@eit.uni-kl.de        x.wi( 0 );
205612027Sjungma@eit.uni-kl.de    }
205712027Sjungma@eit.uni-kl.de
205812027Sjungma@eit.uni-kl.de    bool zero_left = o_zero_left( x );
205912027Sjungma@eit.uni-kl.de    bool bit_at = o_bit_at( x );
206012027Sjungma@eit.uni-kl.de    bool zero_right = o_zero_right( x );
206112027Sjungma@eit.uni-kl.de
206212027Sjungma@eit.uni-kl.de    bool under = false;
206312027Sjungma@eit.uni-kl.de    bool over = false;
206412027Sjungma@eit.uni-kl.de
206512027Sjungma@eit.uni-kl.de    sc_enc enc = params.enc();
206612027Sjungma@eit.uni-kl.de
206712027Sjungma@eit.uni-kl.de    if( enc == SC_TC_ )
206812027Sjungma@eit.uni-kl.de    {
206912027Sjungma@eit.uni-kl.de	if( is_neg() )
207012027Sjungma@eit.uni-kl.de	{
207112027Sjungma@eit.uni-kl.de	    if( params.o_mode() == SC_SAT_SYM )
207212027Sjungma@eit.uni-kl.de		under = ( ! zero_left || bit_at );
207312027Sjungma@eit.uni-kl.de	    else
207412027Sjungma@eit.uni-kl.de		under = (! zero_left || (zero_left && bit_at && ! zero_right));
207512027Sjungma@eit.uni-kl.de	}
207612027Sjungma@eit.uni-kl.de	else
207712027Sjungma@eit.uni-kl.de	    over = ( ! zero_left || bit_at );
207812027Sjungma@eit.uni-kl.de    }
207912027Sjungma@eit.uni-kl.de    else
208012027Sjungma@eit.uni-kl.de    {
208112027Sjungma@eit.uni-kl.de	if( is_neg() )
208212027Sjungma@eit.uni-kl.de	    under = ( ! is_zero() );
208312027Sjungma@eit.uni-kl.de        else
208412027Sjungma@eit.uni-kl.de	    over = ( ! zero_left );
208512027Sjungma@eit.uni-kl.de    }
208612027Sjungma@eit.uni-kl.de
208712027Sjungma@eit.uni-kl.de    o_flag = ( under || over );
208812027Sjungma@eit.uni-kl.de
208912027Sjungma@eit.uni-kl.de    if( o_flag )
209012027Sjungma@eit.uni-kl.de    {
209112027Sjungma@eit.uni-kl.de	scfx_index x2 = calc_indices( params.iwl() - params.wl() );
209212027Sjungma@eit.uni-kl.de
209312027Sjungma@eit.uni-kl.de	if( x2.wi() < 0 )
209412027Sjungma@eit.uni-kl.de	{
209512027Sjungma@eit.uni-kl.de	    resize_to( size() - x2.wi(), -1 );
209612027Sjungma@eit.uni-kl.de	    x.wi( x.wi() - x2.wi() );
209712027Sjungma@eit.uni-kl.de	    x2.wi( 0 );
209812027Sjungma@eit.uni-kl.de	}
209912027Sjungma@eit.uni-kl.de
210012027Sjungma@eit.uni-kl.de	switch( params.o_mode() )
210112027Sjungma@eit.uni-kl.de	{
210212027Sjungma@eit.uni-kl.de            case SC_WRAP:			// wrap-around
210312027Sjungma@eit.uni-kl.de	    {
210412027Sjungma@eit.uni-kl.de		int n_bits = params.n_bits();
210512027Sjungma@eit.uni-kl.de
210612027Sjungma@eit.uni-kl.de		if( n_bits == 0 )
210712027Sjungma@eit.uni-kl.de		{
210812027Sjungma@eit.uni-kl.de		    // wrap-around all 'wl' bits
210912027Sjungma@eit.uni-kl.de		    toggle_tc();
211012027Sjungma@eit.uni-kl.de		    o_extend( x, enc );
211112027Sjungma@eit.uni-kl.de		    toggle_tc();
211212027Sjungma@eit.uni-kl.de		}
211312027Sjungma@eit.uni-kl.de		else if( n_bits < params.wl() )
211412027Sjungma@eit.uni-kl.de		{
211512027Sjungma@eit.uni-kl.de		    scfx_index x3 = calc_indices( params.iwl() - 1 - n_bits );
211612027Sjungma@eit.uni-kl.de
211712027Sjungma@eit.uni-kl.de		    // wrap-around least significant 'wl - n_bits' bits;
211812027Sjungma@eit.uni-kl.de		    // saturate most significant 'n_bits' bits
211912027Sjungma@eit.uni-kl.de		    toggle_tc();
212012027Sjungma@eit.uni-kl.de		    o_set( x, x3, enc, under );
212112027Sjungma@eit.uni-kl.de		    o_extend( x, enc );
212212027Sjungma@eit.uni-kl.de		    toggle_tc();
212312027Sjungma@eit.uni-kl.de		}
212412027Sjungma@eit.uni-kl.de		else
212512027Sjungma@eit.uni-kl.de		{
212612027Sjungma@eit.uni-kl.de		    // saturate all 'wl' bits
212712027Sjungma@eit.uni-kl.de		    if( under )
212812027Sjungma@eit.uni-kl.de			o_set_low( x, enc );
212912027Sjungma@eit.uni-kl.de		    else
213012027Sjungma@eit.uni-kl.de			o_set_high( x, x2, enc );
213112027Sjungma@eit.uni-kl.de		}
213212027Sjungma@eit.uni-kl.de		break;
213312027Sjungma@eit.uni-kl.de	    }
213412027Sjungma@eit.uni-kl.de            case SC_SAT:			// saturation
213512027Sjungma@eit.uni-kl.de	    {
213612027Sjungma@eit.uni-kl.de		if( under )
213712027Sjungma@eit.uni-kl.de		    o_set_low( x, enc );
213812027Sjungma@eit.uni-kl.de		else
213912027Sjungma@eit.uni-kl.de		    o_set_high( x, x2, enc );
214012027Sjungma@eit.uni-kl.de		break;
214112027Sjungma@eit.uni-kl.de	    }
214212027Sjungma@eit.uni-kl.de            case SC_SAT_SYM:			// symmetrical saturation
214312027Sjungma@eit.uni-kl.de	    {
214412027Sjungma@eit.uni-kl.de		if( under )
214512027Sjungma@eit.uni-kl.de		{
214612027Sjungma@eit.uni-kl.de		    if( enc == SC_TC_ )
214712027Sjungma@eit.uni-kl.de			o_set_high( x, x2, SC_TC_, -1 );
214812027Sjungma@eit.uni-kl.de		    else
214912027Sjungma@eit.uni-kl.de			o_set_low( x, SC_US_ );
215012027Sjungma@eit.uni-kl.de		}
215112027Sjungma@eit.uni-kl.de		else
215212027Sjungma@eit.uni-kl.de		    o_set_high( x, x2, enc );
215312027Sjungma@eit.uni-kl.de		break;
215412027Sjungma@eit.uni-kl.de	    }
215512027Sjungma@eit.uni-kl.de            case SC_SAT_ZERO:			// saturation to zero
215612027Sjungma@eit.uni-kl.de	    {
215712027Sjungma@eit.uni-kl.de		set_zero();
215812027Sjungma@eit.uni-kl.de		break;
215912027Sjungma@eit.uni-kl.de	    }
216012027Sjungma@eit.uni-kl.de            case SC_WRAP_SM:			// sign magnitude wrap-around
216112027Sjungma@eit.uni-kl.de	    {
216212027Sjungma@eit.uni-kl.de		SC_ERROR_IF_( enc == SC_US_,
216312027Sjungma@eit.uni-kl.de			      sc_core::SC_ID_WRAP_SM_NOT_DEFINED_ );
216412027Sjungma@eit.uni-kl.de
216512027Sjungma@eit.uni-kl.de		int n_bits = params.n_bits();
216612027Sjungma@eit.uni-kl.de
216712027Sjungma@eit.uni-kl.de		if( n_bits == 0 )
216812027Sjungma@eit.uni-kl.de		{
216912027Sjungma@eit.uni-kl.de		    scfx_index x4 = calc_indices( params.iwl() );
217012027Sjungma@eit.uni-kl.de
217112027Sjungma@eit.uni-kl.de		    if( x4.wi() >= size() )
217212027Sjungma@eit.uni-kl.de			resize_to( x4.wi() + 1, 1 );
217312027Sjungma@eit.uni-kl.de
217412027Sjungma@eit.uni-kl.de		    toggle_tc();
217512027Sjungma@eit.uni-kl.de		    if( o_bit_at( x4 ) != o_bit_at( x ) )
217612027Sjungma@eit.uni-kl.de			o_invert( x2 );
217712027Sjungma@eit.uni-kl.de		    o_extend( x, SC_TC_ );
217812027Sjungma@eit.uni-kl.de		    toggle_tc();
217912027Sjungma@eit.uni-kl.de		}
218012027Sjungma@eit.uni-kl.de		else if( n_bits == 1 )
218112027Sjungma@eit.uni-kl.de		{
218212027Sjungma@eit.uni-kl.de		    toggle_tc();
218312027Sjungma@eit.uni-kl.de		    if( is_neg() != o_bit_at( x ) )
218412027Sjungma@eit.uni-kl.de			o_invert( x2 );
218512027Sjungma@eit.uni-kl.de		    o_extend( x, SC_TC_ );
218612027Sjungma@eit.uni-kl.de		    toggle_tc();
218712027Sjungma@eit.uni-kl.de		}
218812027Sjungma@eit.uni-kl.de		else if( n_bits < params.wl() )
218912027Sjungma@eit.uni-kl.de		{
219012027Sjungma@eit.uni-kl.de		    scfx_index x3 = calc_indices( params.iwl() - 1 - n_bits );
219112027Sjungma@eit.uni-kl.de		    scfx_index x4 = calc_indices( params.iwl() - n_bits );
219212027Sjungma@eit.uni-kl.de
219312027Sjungma@eit.uni-kl.de		    // wrap-around least significant 'wl - n_bits' bits;
219412027Sjungma@eit.uni-kl.de		    // saturate most significant 'n_bits' bits
219512027Sjungma@eit.uni-kl.de		    toggle_tc();
219612027Sjungma@eit.uni-kl.de		    if( is_neg() == o_bit_at( x4 ) )
219712027Sjungma@eit.uni-kl.de			o_invert( x2 );
219812027Sjungma@eit.uni-kl.de		    o_set( x, x3, SC_TC_, under );
219912027Sjungma@eit.uni-kl.de		    o_extend( x, SC_TC_ );
220012027Sjungma@eit.uni-kl.de		    toggle_tc();
220112027Sjungma@eit.uni-kl.de		}
220212027Sjungma@eit.uni-kl.de		else
220312027Sjungma@eit.uni-kl.de		{
220412027Sjungma@eit.uni-kl.de		    if( under )
220512027Sjungma@eit.uni-kl.de			o_set_low( x, SC_TC_ );
220612027Sjungma@eit.uni-kl.de		    else
220712027Sjungma@eit.uni-kl.de			o_set_high( x, x2, SC_TC_ );
220812027Sjungma@eit.uni-kl.de		}
220912027Sjungma@eit.uni-kl.de		break;
221012027Sjungma@eit.uni-kl.de	    }
221112027Sjungma@eit.uni-kl.de            default:
221212027Sjungma@eit.uni-kl.de	        ;
221312027Sjungma@eit.uni-kl.de	}
221412027Sjungma@eit.uni-kl.de
221512027Sjungma@eit.uni-kl.de	find_sw();
221612027Sjungma@eit.uni-kl.de    }
221712027Sjungma@eit.uni-kl.de}
221812027Sjungma@eit.uni-kl.de
221912027Sjungma@eit.uni-kl.de
222012027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
222112027Sjungma@eit.uni-kl.de//  PUBLIC METHOD : cast
222212027Sjungma@eit.uni-kl.de//
222312027Sjungma@eit.uni-kl.de//  Performs a destructive cast operation on a scfx_rep.
222412027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
222512027Sjungma@eit.uni-kl.de
222612027Sjungma@eit.uni-kl.devoid
222712027Sjungma@eit.uni-kl.descfx_rep::cast( const scfx_params& params, bool& q_flag, bool& o_flag )
222812027Sjungma@eit.uni-kl.de{
222912027Sjungma@eit.uni-kl.de    q_flag = false;
223012027Sjungma@eit.uni-kl.de    o_flag = false;
223112027Sjungma@eit.uni-kl.de
223212027Sjungma@eit.uni-kl.de    // check for special cases
223312027Sjungma@eit.uni-kl.de
223412027Sjungma@eit.uni-kl.de    if( is_zero() )
223512027Sjungma@eit.uni-kl.de    {
223612027Sjungma@eit.uni-kl.de	if( is_neg() )
223712027Sjungma@eit.uni-kl.de	    m_sign = 1;
223812027Sjungma@eit.uni-kl.de	return;
223912027Sjungma@eit.uni-kl.de    }
224012027Sjungma@eit.uni-kl.de
224112027Sjungma@eit.uni-kl.de    // perform casting
224212027Sjungma@eit.uni-kl.de
224312027Sjungma@eit.uni-kl.de    quantization( params, q_flag );
224412027Sjungma@eit.uni-kl.de    overflow( params, o_flag );
224512027Sjungma@eit.uni-kl.de
224612027Sjungma@eit.uni-kl.de    // check for special case: -0
224712027Sjungma@eit.uni-kl.de
224812027Sjungma@eit.uni-kl.de    if( is_zero() && is_neg() )
224912027Sjungma@eit.uni-kl.de	m_sign = 1;
225012027Sjungma@eit.uni-kl.de}
225112027Sjungma@eit.uni-kl.de
225212027Sjungma@eit.uni-kl.de
225312027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
225412027Sjungma@eit.uni-kl.de//  make sure, the two mantissas are aligned
225512027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
225612027Sjungma@eit.uni-kl.de
225712027Sjungma@eit.uni-kl.devoid
225812027Sjungma@eit.uni-kl.dealign( const scfx_rep& lhs, const scfx_rep& rhs, int& new_wp,
225912027Sjungma@eit.uni-kl.de       int& len_mant, scfx_mant_ref& lhs_mant, scfx_mant_ref& rhs_mant )
226012027Sjungma@eit.uni-kl.de{
226112027Sjungma@eit.uni-kl.de    bool need_lhs = true;
226212027Sjungma@eit.uni-kl.de    bool need_rhs = true;
226312027Sjungma@eit.uni-kl.de
226412027Sjungma@eit.uni-kl.de    if( lhs.m_wp != rhs.m_wp || lhs.size() != rhs.size() )
226512027Sjungma@eit.uni-kl.de    {
226612027Sjungma@eit.uni-kl.de	int lower_bound_lhs = lhs.m_lsw - lhs.m_wp;
226712027Sjungma@eit.uni-kl.de	int upper_bound_lhs = lhs.m_msw - lhs.m_wp;
226812027Sjungma@eit.uni-kl.de	int lower_bound_rhs = rhs.m_lsw - rhs.m_wp;
226912027Sjungma@eit.uni-kl.de	int upper_bound_rhs = rhs.m_msw - rhs.m_wp;
227012027Sjungma@eit.uni-kl.de
227112027Sjungma@eit.uni-kl.de	int lower_bound = sc_min( lower_bound_lhs, lower_bound_rhs );
227212027Sjungma@eit.uni-kl.de	int upper_bound = sc_max( upper_bound_lhs, upper_bound_rhs );
227312027Sjungma@eit.uni-kl.de
227412027Sjungma@eit.uni-kl.de	new_wp   = -lower_bound;
227512027Sjungma@eit.uni-kl.de	len_mant = sc_max( min_mant, upper_bound - lower_bound + 1 );
227612027Sjungma@eit.uni-kl.de
227712027Sjungma@eit.uni-kl.de	if( new_wp != lhs.m_wp || len_mant != lhs.size() )
227812027Sjungma@eit.uni-kl.de	{
227912027Sjungma@eit.uni-kl.de	    lhs_mant = lhs.resize( len_mant, new_wp );
228012027Sjungma@eit.uni-kl.de	    need_lhs = false;
228112027Sjungma@eit.uni-kl.de	}
228212027Sjungma@eit.uni-kl.de
228312027Sjungma@eit.uni-kl.de	if( new_wp != rhs.m_wp || len_mant != rhs.size() )
228412027Sjungma@eit.uni-kl.de        {
228512027Sjungma@eit.uni-kl.de	    rhs_mant = rhs.resize( len_mant, new_wp );
228612027Sjungma@eit.uni-kl.de	    need_rhs = false;
228712027Sjungma@eit.uni-kl.de	}
228812027Sjungma@eit.uni-kl.de    }
228912027Sjungma@eit.uni-kl.de
229012027Sjungma@eit.uni-kl.de    if( need_lhs )
229112027Sjungma@eit.uni-kl.de    {
229212027Sjungma@eit.uni-kl.de	lhs_mant = lhs.m_mant;
229312027Sjungma@eit.uni-kl.de    }
229412027Sjungma@eit.uni-kl.de
229512027Sjungma@eit.uni-kl.de    if( need_rhs )
229612027Sjungma@eit.uni-kl.de    {
229712027Sjungma@eit.uni-kl.de	rhs_mant = rhs.m_mant;
229812027Sjungma@eit.uni-kl.de    }
229912027Sjungma@eit.uni-kl.de}
230012027Sjungma@eit.uni-kl.de
230112027Sjungma@eit.uni-kl.de
230212027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
230312027Sjungma@eit.uni-kl.de//  compare two mantissas
230412027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
230512027Sjungma@eit.uni-kl.de
230612027Sjungma@eit.uni-kl.deint
230712027Sjungma@eit.uni-kl.decompare_msw_ff( const scfx_rep& lhs, const scfx_rep& rhs )
230812027Sjungma@eit.uni-kl.de{
230912027Sjungma@eit.uni-kl.de    // special case: rhs.m_mant[rhs.m_msw + 1] == 1
231012027Sjungma@eit.uni-kl.de    if( rhs.m_msw < rhs.size() - 1 && rhs.m_mant[rhs.m_msw + 1 ] != 0 )
231112027Sjungma@eit.uni-kl.de    {
231212027Sjungma@eit.uni-kl.de	return -1;
231312027Sjungma@eit.uni-kl.de    }
231412027Sjungma@eit.uni-kl.de
231512027Sjungma@eit.uni-kl.de    int lhs_size = lhs.m_msw - lhs.m_lsw + 1;
231612027Sjungma@eit.uni-kl.de    int rhs_size = rhs.m_msw - rhs.m_lsw + 1;
231712027Sjungma@eit.uni-kl.de
231812027Sjungma@eit.uni-kl.de    int size = sc_min( lhs_size, rhs_size );
231912027Sjungma@eit.uni-kl.de
232012027Sjungma@eit.uni-kl.de    int lhs_index = lhs.m_msw;
232112027Sjungma@eit.uni-kl.de    int rhs_index = rhs.m_msw;
232212027Sjungma@eit.uni-kl.de
232312027Sjungma@eit.uni-kl.de    int i;
232412027Sjungma@eit.uni-kl.de
232512027Sjungma@eit.uni-kl.de    for( i = 0;
232612027Sjungma@eit.uni-kl.de	 i < size && lhs.m_mant[lhs_index] == rhs.m_mant[rhs_index];
232712027Sjungma@eit.uni-kl.de	 i ++ )
232812027Sjungma@eit.uni-kl.de    {
232912027Sjungma@eit.uni-kl.de	lhs_index --;
233012027Sjungma@eit.uni-kl.de	rhs_index --;
233112027Sjungma@eit.uni-kl.de    }
233212027Sjungma@eit.uni-kl.de
233312027Sjungma@eit.uni-kl.de    if( i == size )
233412027Sjungma@eit.uni-kl.de    {
233512027Sjungma@eit.uni-kl.de	if( lhs_size == rhs_size )
233612027Sjungma@eit.uni-kl.de	{
233712027Sjungma@eit.uni-kl.de	    return 0;
233812027Sjungma@eit.uni-kl.de	}
233912027Sjungma@eit.uni-kl.de
234012027Sjungma@eit.uni-kl.de	if( lhs_size < rhs_size )
234112027Sjungma@eit.uni-kl.de	{
234212027Sjungma@eit.uni-kl.de	    return -1;
234312027Sjungma@eit.uni-kl.de	}
234412027Sjungma@eit.uni-kl.de	else
234512027Sjungma@eit.uni-kl.de	{
234612027Sjungma@eit.uni-kl.de	    return 1;
234712027Sjungma@eit.uni-kl.de	}
234812027Sjungma@eit.uni-kl.de  }
234912027Sjungma@eit.uni-kl.de
235012027Sjungma@eit.uni-kl.de  if( lhs.m_mant[lhs_index] < rhs.m_mant[rhs_index] )
235112027Sjungma@eit.uni-kl.de  {
235212027Sjungma@eit.uni-kl.de      return -1;
235312027Sjungma@eit.uni-kl.de  } else {
235412027Sjungma@eit.uni-kl.de      return 1;
235512027Sjungma@eit.uni-kl.de  }
235612027Sjungma@eit.uni-kl.de}
235712027Sjungma@eit.uni-kl.de
235812027Sjungma@eit.uni-kl.de
235912027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
236012027Sjungma@eit.uni-kl.de//  divide the mantissa by ten
236112027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
236212027Sjungma@eit.uni-kl.de
236312027Sjungma@eit.uni-kl.deunsigned int
236412027Sjungma@eit.uni-kl.descfx_rep::divide_by_ten()
236512027Sjungma@eit.uni-kl.de{
236612027Sjungma@eit.uni-kl.de#if defined( SC_BIG_ENDIAN )
236712027Sjungma@eit.uni-kl.de    half_word* hw = (half_word*) &m_mant[m_msw];
236812027Sjungma@eit.uni-kl.de#elif defined( SC_LITTLE_ENDIAN )
236912027Sjungma@eit.uni-kl.de    half_word* hw = ( (half_word*) &m_mant[m_msw] ) + 1;
237012027Sjungma@eit.uni-kl.de#endif
237112027Sjungma@eit.uni-kl.de
237212027Sjungma@eit.uni-kl.de    unsigned int remainder = 0;
237312027Sjungma@eit.uni-kl.de
237412027Sjungma@eit.uni-kl.de    word_short ls;
237512027Sjungma@eit.uni-kl.de    ls.l = 0;
237612027Sjungma@eit.uni-kl.de
237712027Sjungma@eit.uni-kl.de#if defined( SC_BIG_ENDIAN )
237812027Sjungma@eit.uni-kl.de    for( int i = 0, end = ( m_msw - m_wp + 1 ) * 2; i < end; i ++ )
237912027Sjungma@eit.uni-kl.de#elif defined( SC_LITTLE_ENDIAN )
238012027Sjungma@eit.uni-kl.de    for( int i = 0, end = -( m_msw - m_wp + 1 ) * 2; i > end; i -- )
238112027Sjungma@eit.uni-kl.de#endif
238212027Sjungma@eit.uni-kl.de    {
238312027Sjungma@eit.uni-kl.de	ls.s.u = static_cast<half_word>( remainder );
238412027Sjungma@eit.uni-kl.de	ls.s.l = hw[i];
238512027Sjungma@eit.uni-kl.de	remainder = ls.l % 10;
238612027Sjungma@eit.uni-kl.de	ls.l /= 10;
238712027Sjungma@eit.uni-kl.de	hw[i] = ls.s.l;
238812027Sjungma@eit.uni-kl.de    }
238912027Sjungma@eit.uni-kl.de
239012027Sjungma@eit.uni-kl.de    return remainder;
239112027Sjungma@eit.uni-kl.de}
239212027Sjungma@eit.uni-kl.de
239312027Sjungma@eit.uni-kl.de
239412027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
239512027Sjungma@eit.uni-kl.de//  multiply the mantissa by ten
239612027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
239712027Sjungma@eit.uni-kl.de
239812027Sjungma@eit.uni-kl.devoid
239912027Sjungma@eit.uni-kl.descfx_rep::multiply_by_ten()
240012027Sjungma@eit.uni-kl.de{
240112027Sjungma@eit.uni-kl.de    int size = m_mant.size() + 1;
240212027Sjungma@eit.uni-kl.de
240312027Sjungma@eit.uni-kl.de    scfx_mant mant8( size );
240412027Sjungma@eit.uni-kl.de    scfx_mant mant2( size );
240512027Sjungma@eit.uni-kl.de
240612027Sjungma@eit.uni-kl.de    size --;
240712027Sjungma@eit.uni-kl.de
240812027Sjungma@eit.uni-kl.de    mant8[size] = (m_mant[size - 1] >> (bits_in_word - 3));
240912027Sjungma@eit.uni-kl.de    mant2[size] = (m_mant[size - 1] >> (bits_in_word - 1));
241012027Sjungma@eit.uni-kl.de
241112027Sjungma@eit.uni-kl.de    while( -- size )
241212027Sjungma@eit.uni-kl.de    {
241312027Sjungma@eit.uni-kl.de	mant8[size] = ( m_mant[size] << 3 ) |
241412027Sjungma@eit.uni-kl.de	              ( m_mant[size - 1] >> ( bits_in_word - 3 ) );
241512027Sjungma@eit.uni-kl.de	mant2[size] = ( m_mant[size] << 1 ) |
241612027Sjungma@eit.uni-kl.de	              ( m_mant[size - 1] >> ( bits_in_word - 1 ) );
241712027Sjungma@eit.uni-kl.de    }
241812027Sjungma@eit.uni-kl.de
241912027Sjungma@eit.uni-kl.de    mant8[0] = ( m_mant[0] << 3 );
242012027Sjungma@eit.uni-kl.de    mant2[0] = ( m_mant[0] << 1 );
242112027Sjungma@eit.uni-kl.de
242212027Sjungma@eit.uni-kl.de    add_mants( m_mant.size(), m_mant, mant8, mant2 );
242312027Sjungma@eit.uni-kl.de
242412027Sjungma@eit.uni-kl.de#if 0
242512027Sjungma@eit.uni-kl.de    for( int i = size() - 1; i > 0; i -- )
242612027Sjungma@eit.uni-kl.de    {
242712027Sjungma@eit.uni-kl.de	m_mant[i] = ( m_mant[i] << 3 ) |
242812027Sjungma@eit.uni-kl.de                    ( m_mant[i-1] >> ( bits_in_word - 3 ) )
242912027Sjungma@eit.uni-kl.de	          + ( m_mant[i] << 1 ) |
243012027Sjungma@eit.uni-kl.de                    ( m_mant[i-1] >> ( bits_in_word - 1 ) );
243112027Sjungma@eit.uni-kl.de    }
243212027Sjungma@eit.uni-kl.de    m_mant[0] = ( m_mant[0] << 3 ) + ( m_mant[0] << 1 );
243312027Sjungma@eit.uni-kl.de#endif
243412027Sjungma@eit.uni-kl.de}
243512027Sjungma@eit.uni-kl.de
243612027Sjungma@eit.uni-kl.de
243712027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
243812027Sjungma@eit.uni-kl.de//  normalize
243912027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
244012027Sjungma@eit.uni-kl.de
244112027Sjungma@eit.uni-kl.devoid
244212027Sjungma@eit.uni-kl.descfx_rep::normalize( int exponent )
244312027Sjungma@eit.uni-kl.de{
244412027Sjungma@eit.uni-kl.de    int shift = exponent % bits_in_word;
244512027Sjungma@eit.uni-kl.de    if( shift < 0 )
244612027Sjungma@eit.uni-kl.de    {
244712027Sjungma@eit.uni-kl.de	shift += bits_in_word;
244812027Sjungma@eit.uni-kl.de    }
244912027Sjungma@eit.uni-kl.de
245012027Sjungma@eit.uni-kl.de    if( shift )
245112027Sjungma@eit.uni-kl.de    {
245212027Sjungma@eit.uni-kl.de	shift_left( shift );
245312027Sjungma@eit.uni-kl.de    }
245412027Sjungma@eit.uni-kl.de
245512027Sjungma@eit.uni-kl.de    find_sw();
245612027Sjungma@eit.uni-kl.de
245712027Sjungma@eit.uni-kl.de    m_wp = (shift - exponent) / bits_in_word;
245812027Sjungma@eit.uni-kl.de}
245912027Sjungma@eit.uni-kl.de
246012027Sjungma@eit.uni-kl.de
246112027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
246212027Sjungma@eit.uni-kl.de//  return a new mantissa that is aligned and resized
246312027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
246412027Sjungma@eit.uni-kl.de
246512027Sjungma@eit.uni-kl.descfx_mant*
246612027Sjungma@eit.uni-kl.descfx_rep::resize( int new_size, int new_wp ) const
246712027Sjungma@eit.uni-kl.de{
246812027Sjungma@eit.uni-kl.de    scfx_mant *result = new scfx_mant( new_size );
246912027Sjungma@eit.uni-kl.de
247012027Sjungma@eit.uni-kl.de    result->clear();
247112027Sjungma@eit.uni-kl.de
247212027Sjungma@eit.uni-kl.de    int shift = new_wp - m_wp;
247312027Sjungma@eit.uni-kl.de
247412027Sjungma@eit.uni-kl.de    for( int j = m_lsw; j <= m_msw; j ++ )
247512027Sjungma@eit.uni-kl.de    {
247612027Sjungma@eit.uni-kl.de	(*result)[j+shift] = m_mant[j];
247712027Sjungma@eit.uni-kl.de    }
247812027Sjungma@eit.uni-kl.de
247912027Sjungma@eit.uni-kl.de    return result;
248012027Sjungma@eit.uni-kl.de}
248112027Sjungma@eit.uni-kl.de
248212027Sjungma@eit.uni-kl.de
248312027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
248412027Sjungma@eit.uni-kl.de//  set a single bit
248512027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
248612027Sjungma@eit.uni-kl.de
248712027Sjungma@eit.uni-kl.devoid
248812027Sjungma@eit.uni-kl.descfx_rep::set_bin( int i )
248912027Sjungma@eit.uni-kl.de{
249012027Sjungma@eit.uni-kl.de    m_mant[i >> 5] |= 1 << ( i & 31 );
249112027Sjungma@eit.uni-kl.de}
249212027Sjungma@eit.uni-kl.de
249312027Sjungma@eit.uni-kl.de
249412027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
249512027Sjungma@eit.uni-kl.de//  set three bits
249612027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
249712027Sjungma@eit.uni-kl.de
249812027Sjungma@eit.uni-kl.devoid
249912027Sjungma@eit.uni-kl.descfx_rep::set_oct( int i, int n )
250012027Sjungma@eit.uni-kl.de{
250112027Sjungma@eit.uni-kl.de    if( n & 1 )
250212027Sjungma@eit.uni-kl.de    {
250312027Sjungma@eit.uni-kl.de	m_mant[i >> 5] |= 1 << ( i & 31 );
250412027Sjungma@eit.uni-kl.de    }
250512027Sjungma@eit.uni-kl.de    i ++;
250612027Sjungma@eit.uni-kl.de    if( n & 2 )
250712027Sjungma@eit.uni-kl.de    {
250812027Sjungma@eit.uni-kl.de	m_mant[i >> 5] |= 1 << ( i & 31 );
250912027Sjungma@eit.uni-kl.de    }
251012027Sjungma@eit.uni-kl.de    i ++;
251112027Sjungma@eit.uni-kl.de    if( n & 4 )
251212027Sjungma@eit.uni-kl.de    {
251312027Sjungma@eit.uni-kl.de	m_mant[i >> 5] |= 1 << ( i & 31 );
251412027Sjungma@eit.uni-kl.de    }
251512027Sjungma@eit.uni-kl.de}
251612027Sjungma@eit.uni-kl.de
251712027Sjungma@eit.uni-kl.de
251812027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
251912027Sjungma@eit.uni-kl.de//  set four bits
252012027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
252112027Sjungma@eit.uni-kl.de
252212027Sjungma@eit.uni-kl.devoid
252312027Sjungma@eit.uni-kl.descfx_rep::set_hex( int i, int n )
252412027Sjungma@eit.uni-kl.de{
252512027Sjungma@eit.uni-kl.de    if( n & 1 )
252612027Sjungma@eit.uni-kl.de    {
252712027Sjungma@eit.uni-kl.de	m_mant[i >> 5] |= 1 << ( i & 31 );
252812027Sjungma@eit.uni-kl.de    }
252912027Sjungma@eit.uni-kl.de    i ++;
253012027Sjungma@eit.uni-kl.de    if( n & 2 )
253112027Sjungma@eit.uni-kl.de    {
253212027Sjungma@eit.uni-kl.de	m_mant[i >> 5] |= 1 << ( i & 31 );
253312027Sjungma@eit.uni-kl.de    }
253412027Sjungma@eit.uni-kl.de    i ++;
253512027Sjungma@eit.uni-kl.de    if( n & 4 )
253612027Sjungma@eit.uni-kl.de    {
253712027Sjungma@eit.uni-kl.de	m_mant[i >> 5] |= 1 << ( i & 31 );
253812027Sjungma@eit.uni-kl.de    }
253912027Sjungma@eit.uni-kl.de    i ++;
254012027Sjungma@eit.uni-kl.de    if( n & 8 )
254112027Sjungma@eit.uni-kl.de    {
254212027Sjungma@eit.uni-kl.de	m_mant[i >> 5] |= 1 << ( i & 31 );
254312027Sjungma@eit.uni-kl.de    }
254412027Sjungma@eit.uni-kl.de}
254512027Sjungma@eit.uni-kl.de
254612027Sjungma@eit.uni-kl.de
254712027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
254812027Sjungma@eit.uni-kl.de//  PRIVATE METHOD : shift_left
254912027Sjungma@eit.uni-kl.de//
255012027Sjungma@eit.uni-kl.de//  Shifts a scfx_rep to the left by a MAXIMUM of bits_in_word - 1 bits.
255112027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
255212027Sjungma@eit.uni-kl.de
255312027Sjungma@eit.uni-kl.devoid
255412027Sjungma@eit.uni-kl.descfx_rep::shift_left( int n )
255512027Sjungma@eit.uni-kl.de{
255612027Sjungma@eit.uni-kl.de    if( n != 0 )
255712027Sjungma@eit.uni-kl.de    {
255812027Sjungma@eit.uni-kl.de	int shift_left  = n;
255912027Sjungma@eit.uni-kl.de	int shift_right = bits_in_word - n;
256012027Sjungma@eit.uni-kl.de
256112027Sjungma@eit.uni-kl.de	SC_ASSERT_( !(m_mant[size()-1] >> shift_right),
256212027Sjungma@eit.uni-kl.de		    "shift_left overflow" );
256312027Sjungma@eit.uni-kl.de
256412027Sjungma@eit.uni-kl.de	for( int i = size() - 1; i > 0; i -- )
256512027Sjungma@eit.uni-kl.de	{
256612027Sjungma@eit.uni-kl.de	    m_mant[i] = ( m_mant[i] << shift_left ) |
256712027Sjungma@eit.uni-kl.de		       ( m_mant[i-1] >> shift_right );
256812027Sjungma@eit.uni-kl.de	}
256912027Sjungma@eit.uni-kl.de	m_mant[0] <<= shift_left;
257012027Sjungma@eit.uni-kl.de    }
257112027Sjungma@eit.uni-kl.de}
257212027Sjungma@eit.uni-kl.de
257312027Sjungma@eit.uni-kl.de
257412027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
257512027Sjungma@eit.uni-kl.de//  PRIVATE METHOD : shift_right
257612027Sjungma@eit.uni-kl.de//
257712027Sjungma@eit.uni-kl.de//  Shifts a scfx_rep to the right by a MAXIMUM of bits_in_word - 1 bits.
257812027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
257912027Sjungma@eit.uni-kl.de
258012027Sjungma@eit.uni-kl.devoid
258112027Sjungma@eit.uni-kl.descfx_rep::shift_right( int n )
258212027Sjungma@eit.uni-kl.de{
258312027Sjungma@eit.uni-kl.de    if( n != 0 )
258412027Sjungma@eit.uni-kl.de    {
258512027Sjungma@eit.uni-kl.de	int shift_left  = bits_in_word - n;
258612027Sjungma@eit.uni-kl.de	int shift_right = n;
258712027Sjungma@eit.uni-kl.de
258812027Sjungma@eit.uni-kl.de	SC_ASSERT_( !(m_mant[0] << shift_left), "shift_right overflow" );
258912027Sjungma@eit.uni-kl.de
259012027Sjungma@eit.uni-kl.de	for( int i = 0; i < size() - 1; i ++ )
259112027Sjungma@eit.uni-kl.de	{
259212027Sjungma@eit.uni-kl.de	    m_mant[i] = ( m_mant[i] >> shift_right ) |
259312027Sjungma@eit.uni-kl.de		       ( m_mant[i+1] << shift_left );
259412027Sjungma@eit.uni-kl.de	}
259512027Sjungma@eit.uni-kl.de	m_mant[size()-1] >>= shift_right;
259612027Sjungma@eit.uni-kl.de    }
259712027Sjungma@eit.uni-kl.de}
259812027Sjungma@eit.uni-kl.de
259912027Sjungma@eit.uni-kl.de
260012027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
260112027Sjungma@eit.uni-kl.de//  METHOD : get_bit
260212027Sjungma@eit.uni-kl.de//
260312027Sjungma@eit.uni-kl.de//  Tests a bit, in two's complement.
260412027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
260512027Sjungma@eit.uni-kl.de
260612027Sjungma@eit.uni-kl.debool
260712027Sjungma@eit.uni-kl.descfx_rep::get_bit( int i ) const
260812027Sjungma@eit.uni-kl.de{
260912027Sjungma@eit.uni-kl.de    if( ! is_normal() )
261012027Sjungma@eit.uni-kl.de	return false;
261112027Sjungma@eit.uni-kl.de
261212027Sjungma@eit.uni-kl.de    scfx_index x = calc_indices( i );
261312027Sjungma@eit.uni-kl.de
261412027Sjungma@eit.uni-kl.de    if( x.wi() >= size() )
261512027Sjungma@eit.uni-kl.de	return is_neg();
261612027Sjungma@eit.uni-kl.de
261712027Sjungma@eit.uni-kl.de    if( x.wi() < 0 )
261812027Sjungma@eit.uni-kl.de	return false;
261912027Sjungma@eit.uni-kl.de
262012027Sjungma@eit.uni-kl.de    const_cast<scfx_rep*>( this )->toggle_tc();
262112027Sjungma@eit.uni-kl.de
262212027Sjungma@eit.uni-kl.de    bool result = ( m_mant[x.wi()] & ( 1 << x.bi() ) ) != 0;
262312027Sjungma@eit.uni-kl.de
262412027Sjungma@eit.uni-kl.de    const_cast<scfx_rep*>( this )->toggle_tc();
262512027Sjungma@eit.uni-kl.de
262612027Sjungma@eit.uni-kl.de    return result;
262712027Sjungma@eit.uni-kl.de}
262812027Sjungma@eit.uni-kl.de
262912027Sjungma@eit.uni-kl.de
263012027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
263112027Sjungma@eit.uni-kl.de//  METHOD : set
263212027Sjungma@eit.uni-kl.de//
263312027Sjungma@eit.uni-kl.de//  Sets a bit, in two's complement, between iwl-1 and -fwl.
263412027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
263512027Sjungma@eit.uni-kl.de
263612027Sjungma@eit.uni-kl.debool
263712027Sjungma@eit.uni-kl.descfx_rep::set( int i, const scfx_params& params )
263812027Sjungma@eit.uni-kl.de{
263912027Sjungma@eit.uni-kl.de    if( ! is_normal() )
264012027Sjungma@eit.uni-kl.de	return false;
264112027Sjungma@eit.uni-kl.de
264212027Sjungma@eit.uni-kl.de    scfx_index x = calc_indices( i );
264312027Sjungma@eit.uni-kl.de
264412027Sjungma@eit.uni-kl.de    if( x.wi() >= size() )
264512027Sjungma@eit.uni-kl.de    {
264612027Sjungma@eit.uni-kl.de	if( is_neg() )
264712027Sjungma@eit.uni-kl.de	    return true;
264812027Sjungma@eit.uni-kl.de	else
264912027Sjungma@eit.uni-kl.de	    resize_to( x.wi() + 1, 1 );
265012027Sjungma@eit.uni-kl.de    }
265112027Sjungma@eit.uni-kl.de    else if( x.wi() < 0 )
265212027Sjungma@eit.uni-kl.de    {
265312027Sjungma@eit.uni-kl.de	resize_to( size() - x.wi(), -1 );
265412027Sjungma@eit.uni-kl.de	x.wi( 0 );
265512027Sjungma@eit.uni-kl.de    }
265612027Sjungma@eit.uni-kl.de
265712027Sjungma@eit.uni-kl.de    toggle_tc();
265812027Sjungma@eit.uni-kl.de
265912027Sjungma@eit.uni-kl.de    m_mant[x.wi()] |= 1 << x.bi();
266012027Sjungma@eit.uni-kl.de
266112027Sjungma@eit.uni-kl.de    if( i == params.iwl() - 1 )
266212027Sjungma@eit.uni-kl.de        o_extend( x, params.enc() );  // sign extension
266312027Sjungma@eit.uni-kl.de
266412027Sjungma@eit.uni-kl.de    toggle_tc();
266512027Sjungma@eit.uni-kl.de
266612027Sjungma@eit.uni-kl.de    find_sw();
266712027Sjungma@eit.uni-kl.de
266812027Sjungma@eit.uni-kl.de    return true;
266912027Sjungma@eit.uni-kl.de}
267012027Sjungma@eit.uni-kl.de
267112027Sjungma@eit.uni-kl.de
267212027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
267312027Sjungma@eit.uni-kl.de//  METHOD : clear
267412027Sjungma@eit.uni-kl.de//
267512027Sjungma@eit.uni-kl.de//  Clears a bit, in two's complement, between iwl-1 and -fwl.
267612027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
267712027Sjungma@eit.uni-kl.de
267812027Sjungma@eit.uni-kl.debool
267912027Sjungma@eit.uni-kl.descfx_rep::clear( int i, const scfx_params& params )
268012027Sjungma@eit.uni-kl.de{
268112027Sjungma@eit.uni-kl.de    if( ! is_normal() )
268212027Sjungma@eit.uni-kl.de	return false;
268312027Sjungma@eit.uni-kl.de
268412027Sjungma@eit.uni-kl.de    scfx_index x = calc_indices( i );
268512027Sjungma@eit.uni-kl.de
268612027Sjungma@eit.uni-kl.de    if( x.wi() >= size() )
268712027Sjungma@eit.uni-kl.de    {
268812027Sjungma@eit.uni-kl.de	if( ! is_neg() )
268912027Sjungma@eit.uni-kl.de	    return true;
269012027Sjungma@eit.uni-kl.de	else
269112027Sjungma@eit.uni-kl.de	    resize_to( x.wi() + 1, 1 );
269212027Sjungma@eit.uni-kl.de    }
269312027Sjungma@eit.uni-kl.de    else if( x.wi() < 0 )
269412027Sjungma@eit.uni-kl.de	return true;
269512027Sjungma@eit.uni-kl.de
269612027Sjungma@eit.uni-kl.de    toggle_tc();
269712027Sjungma@eit.uni-kl.de
269812027Sjungma@eit.uni-kl.de    m_mant[x.wi()] &= ~( 1 << x.bi() );
269912027Sjungma@eit.uni-kl.de
270012027Sjungma@eit.uni-kl.de    if( i == params.iwl() - 1 )
270112027Sjungma@eit.uni-kl.de        o_extend( x, params.enc() );  // sign extension
270212027Sjungma@eit.uni-kl.de
270312027Sjungma@eit.uni-kl.de    toggle_tc();
270412027Sjungma@eit.uni-kl.de
270512027Sjungma@eit.uni-kl.de    find_sw();
270612027Sjungma@eit.uni-kl.de
270712027Sjungma@eit.uni-kl.de    return true;
270812027Sjungma@eit.uni-kl.de}
270912027Sjungma@eit.uni-kl.de
271012027Sjungma@eit.uni-kl.de
271112027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
271212027Sjungma@eit.uni-kl.de//  METHOD : get_slice
271312027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
271412027Sjungma@eit.uni-kl.de
271512027Sjungma@eit.uni-kl.debool
271612027Sjungma@eit.uni-kl.descfx_rep::get_slice( int i, int j, const scfx_params&,
271712027Sjungma@eit.uni-kl.de		     sc_bv_base& bv ) const
271812027Sjungma@eit.uni-kl.de{
271912027Sjungma@eit.uni-kl.de    if( is_nan() || is_inf() )
272012027Sjungma@eit.uni-kl.de	return false;
272112027Sjungma@eit.uni-kl.de
272212027Sjungma@eit.uni-kl.de    // get the bits
272312027Sjungma@eit.uni-kl.de
272412027Sjungma@eit.uni-kl.de    int l = j;
272512027Sjungma@eit.uni-kl.de    for( int k = 0; k < bv.length(); ++ k )
272612027Sjungma@eit.uni-kl.de    {
272712027Sjungma@eit.uni-kl.de	bv[k] = get_bit( l );
272812027Sjungma@eit.uni-kl.de
272912027Sjungma@eit.uni-kl.de	if( i >= j )
273012027Sjungma@eit.uni-kl.de	    ++ l;
273112027Sjungma@eit.uni-kl.de	else
273212027Sjungma@eit.uni-kl.de	    -- l;
273312027Sjungma@eit.uni-kl.de    }
273412027Sjungma@eit.uni-kl.de
273512027Sjungma@eit.uni-kl.de    return true;
273612027Sjungma@eit.uni-kl.de}
273712027Sjungma@eit.uni-kl.de
273812027Sjungma@eit.uni-kl.debool
273912027Sjungma@eit.uni-kl.descfx_rep::set_slice( int i, int j, const scfx_params& params,
274012027Sjungma@eit.uni-kl.de		     const sc_bv_base& bv )
274112027Sjungma@eit.uni-kl.de{
274212027Sjungma@eit.uni-kl.de    if( is_nan() || is_inf() )
274312027Sjungma@eit.uni-kl.de        return false;
274412027Sjungma@eit.uni-kl.de
274512027Sjungma@eit.uni-kl.de    // set the bits
274612027Sjungma@eit.uni-kl.de
274712027Sjungma@eit.uni-kl.de    int l = j;
274812027Sjungma@eit.uni-kl.de    for( int k = 0; k < bv.length(); ++ k )
274912027Sjungma@eit.uni-kl.de    {
275012027Sjungma@eit.uni-kl.de	if( bv[k].to_bool() )
275112027Sjungma@eit.uni-kl.de	    set( l, params );
275212027Sjungma@eit.uni-kl.de	else
275312027Sjungma@eit.uni-kl.de	    clear( l, params );
275412027Sjungma@eit.uni-kl.de
275512027Sjungma@eit.uni-kl.de	if( i >= j )
275612027Sjungma@eit.uni-kl.de	    ++ l;
275712027Sjungma@eit.uni-kl.de	else
275812027Sjungma@eit.uni-kl.de	    -- l;
275912027Sjungma@eit.uni-kl.de    }
276012027Sjungma@eit.uni-kl.de
276112027Sjungma@eit.uni-kl.de    return true;
276212027Sjungma@eit.uni-kl.de}
276312027Sjungma@eit.uni-kl.de
276412027Sjungma@eit.uni-kl.de
276512027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
276612027Sjungma@eit.uni-kl.de//  METHOD : print
276712027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
276812027Sjungma@eit.uni-kl.de
276912027Sjungma@eit.uni-kl.devoid
277012027Sjungma@eit.uni-kl.descfx_rep::print( ::std::ostream& os ) const
277112027Sjungma@eit.uni-kl.de{
277212027Sjungma@eit.uni-kl.de    os << to_string( SC_DEC, -1, SC_E );
277312027Sjungma@eit.uni-kl.de}
277412027Sjungma@eit.uni-kl.de
277512027Sjungma@eit.uni-kl.de
277612027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
277712027Sjungma@eit.uni-kl.de//  METHOD : dump
277812027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
277912027Sjungma@eit.uni-kl.de
278012027Sjungma@eit.uni-kl.devoid
278112027Sjungma@eit.uni-kl.descfx_rep::dump( ::std::ostream& os ) const
278212027Sjungma@eit.uni-kl.de{
278312027Sjungma@eit.uni-kl.de    os << "scfx_rep" << ::std::endl;
278412027Sjungma@eit.uni-kl.de    os << "(" << ::std::endl;
278512027Sjungma@eit.uni-kl.de
278612027Sjungma@eit.uni-kl.de    os << "mant  =" << ::std::endl;
278712027Sjungma@eit.uni-kl.de    for( int i = size() - 1; i >= 0; i -- )
278812027Sjungma@eit.uni-kl.de    {
278912027Sjungma@eit.uni-kl.de	char buf[BUFSIZ];
279012027Sjungma@eit.uni-kl.de	std::sprintf( buf, " %d: %10u (%8x)", i, (int) m_mant[i], (int) m_mant[i] );
279112027Sjungma@eit.uni-kl.de	os << buf << ::std::endl;
279212027Sjungma@eit.uni-kl.de    }
279312027Sjungma@eit.uni-kl.de
279412027Sjungma@eit.uni-kl.de    os << "wp    = " << m_wp << ::std::endl;
279512027Sjungma@eit.uni-kl.de    os << "sign  = " << m_sign << ::std::endl;
279612027Sjungma@eit.uni-kl.de
279712027Sjungma@eit.uni-kl.de    os << "state = ";
279812027Sjungma@eit.uni-kl.de    switch( m_state )
279912027Sjungma@eit.uni-kl.de    {
280012027Sjungma@eit.uni-kl.de        case normal:
280112027Sjungma@eit.uni-kl.de	    os << "normal";
280212027Sjungma@eit.uni-kl.de	    break;
280312027Sjungma@eit.uni-kl.de        case infinity:
280412027Sjungma@eit.uni-kl.de	    os << "infinity";
280512027Sjungma@eit.uni-kl.de	    break;
280612027Sjungma@eit.uni-kl.de        case not_a_number:
280712027Sjungma@eit.uni-kl.de	    os << "not_a_number";
280812027Sjungma@eit.uni-kl.de	    break;
280912027Sjungma@eit.uni-kl.de        default:
281012027Sjungma@eit.uni-kl.de	    os << "unknown";
281112027Sjungma@eit.uni-kl.de    }
281212027Sjungma@eit.uni-kl.de    os << ::std::endl;
281312027Sjungma@eit.uni-kl.de
281412027Sjungma@eit.uni-kl.de    os << "msw   = " << m_msw << ::std::endl;
281512027Sjungma@eit.uni-kl.de    os << "lsw   = " << m_lsw << ::std::endl;
281612027Sjungma@eit.uni-kl.de
281712027Sjungma@eit.uni-kl.de    os << ")" << ::std::endl;
281812027Sjungma@eit.uni-kl.de}
281912027Sjungma@eit.uni-kl.de
282012027Sjungma@eit.uni-kl.de
282112027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
282212027Sjungma@eit.uni-kl.de//  METHOD : get_type
282312027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
282412027Sjungma@eit.uni-kl.de
282512027Sjungma@eit.uni-kl.devoid
282612027Sjungma@eit.uni-kl.descfx_rep::get_type( int& wl, int& iwl, sc_enc& enc ) const
282712027Sjungma@eit.uni-kl.de{
282812027Sjungma@eit.uni-kl.de    if( is_nan() || is_inf() )
282912027Sjungma@eit.uni-kl.de    {
283012027Sjungma@eit.uni-kl.de        wl  = 0;
283112027Sjungma@eit.uni-kl.de        iwl = 0;
283212027Sjungma@eit.uni-kl.de        enc = SC_TC_;
283312027Sjungma@eit.uni-kl.de        return;
283412027Sjungma@eit.uni-kl.de    }
283512027Sjungma@eit.uni-kl.de
283612027Sjungma@eit.uni-kl.de    if( is_zero() )
283712027Sjungma@eit.uni-kl.de    {
283812027Sjungma@eit.uni-kl.de        wl  = 1;
283912027Sjungma@eit.uni-kl.de        iwl = 1;
284012027Sjungma@eit.uni-kl.de        enc = SC_US_;
284112027Sjungma@eit.uni-kl.de        return;
284212027Sjungma@eit.uni-kl.de    }
284312027Sjungma@eit.uni-kl.de
284412027Sjungma@eit.uni-kl.de    int msb = ( m_msw - m_wp ) * bits_in_word
284512027Sjungma@eit.uni-kl.de            + scfx_find_msb( m_mant[ m_msw ] ) + 1;
284612027Sjungma@eit.uni-kl.de    while( get_bit( msb ) == get_bit( msb - 1 ) )
284712027Sjungma@eit.uni-kl.de    {
284812027Sjungma@eit.uni-kl.de        -- msb;
284912027Sjungma@eit.uni-kl.de    }
285012027Sjungma@eit.uni-kl.de
285112027Sjungma@eit.uni-kl.de    int lsb = ( m_lsw - m_wp ) * bits_in_word
285212027Sjungma@eit.uni-kl.de            + scfx_find_lsb( m_mant[ m_lsw ] );
285312027Sjungma@eit.uni-kl.de
285412027Sjungma@eit.uni-kl.de    if( is_neg() )
285512027Sjungma@eit.uni-kl.de    {
285612027Sjungma@eit.uni-kl.de        wl  = msb - lsb + 1;
285712027Sjungma@eit.uni-kl.de        iwl = msb + 1;
285812027Sjungma@eit.uni-kl.de        enc = SC_TC_;
285912027Sjungma@eit.uni-kl.de    }
286012027Sjungma@eit.uni-kl.de    else
286112027Sjungma@eit.uni-kl.de    {
286212027Sjungma@eit.uni-kl.de        wl  = msb - lsb;
286312027Sjungma@eit.uni-kl.de        iwl = msb;
286412027Sjungma@eit.uni-kl.de        enc = SC_US_;
286512027Sjungma@eit.uni-kl.de    }
286612027Sjungma@eit.uni-kl.de}
286712027Sjungma@eit.uni-kl.de
286812027Sjungma@eit.uni-kl.de
286912027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
287012027Sjungma@eit.uni-kl.de//  PRIVATE METHOD : round
287112027Sjungma@eit.uni-kl.de//
287212027Sjungma@eit.uni-kl.de//  Performs convergent rounding (rounding to even) as in floating-point.
287312027Sjungma@eit.uni-kl.de// ----------------------------------------------------------------------------
287412027Sjungma@eit.uni-kl.de
287512027Sjungma@eit.uni-kl.devoid
287612027Sjungma@eit.uni-kl.descfx_rep::round( int wl )
287712027Sjungma@eit.uni-kl.de{
287812027Sjungma@eit.uni-kl.de    // check for special cases
287912027Sjungma@eit.uni-kl.de
288012027Sjungma@eit.uni-kl.de    if( is_nan() || is_inf() || is_zero() )
288112027Sjungma@eit.uni-kl.de	return;
288212027Sjungma@eit.uni-kl.de
288312027Sjungma@eit.uni-kl.de    // estimate effective wordlength and compare
288412027Sjungma@eit.uni-kl.de
288512027Sjungma@eit.uni-kl.de    int wl_effective;
288612027Sjungma@eit.uni-kl.de
288712027Sjungma@eit.uni-kl.de    wl_effective = ( m_msw - m_lsw + 1 ) * bits_in_word;
288812027Sjungma@eit.uni-kl.de    if( wl_effective <= wl )
288912027Sjungma@eit.uni-kl.de	return;
289012027Sjungma@eit.uni-kl.de
289112027Sjungma@eit.uni-kl.de    // calculate effective wordlength and compare
289212027Sjungma@eit.uni-kl.de
289312027Sjungma@eit.uni-kl.de    int msb = scfx_find_msb( m_mant[m_msw] );
289412027Sjungma@eit.uni-kl.de    int lsb = scfx_find_lsb( m_mant[m_lsw] );
289512027Sjungma@eit.uni-kl.de
289612027Sjungma@eit.uni-kl.de    wl_effective = ( m_msw * bits_in_word + msb ) -
289712027Sjungma@eit.uni-kl.de	           ( m_lsw * bits_in_word + lsb ) + 1;
289812027Sjungma@eit.uni-kl.de    if( wl_effective <= wl )
289912027Sjungma@eit.uni-kl.de	return;
290012027Sjungma@eit.uni-kl.de
290112027Sjungma@eit.uni-kl.de    // perform rounding
290212027Sjungma@eit.uni-kl.de
290312027Sjungma@eit.uni-kl.de    int wi = m_msw - ( wl - 1 ) / bits_in_word;
290412027Sjungma@eit.uni-kl.de    int bi =  msb - ( wl - 1 ) % bits_in_word;
290512027Sjungma@eit.uni-kl.de    if( bi < 0 )
290612027Sjungma@eit.uni-kl.de    {
290712027Sjungma@eit.uni-kl.de	-- wi;
290812027Sjungma@eit.uni-kl.de	bi += bits_in_word;
290912027Sjungma@eit.uni-kl.de    }
291012027Sjungma@eit.uni-kl.de
291112027Sjungma@eit.uni-kl.de    scfx_index x( wi, bi );
291212027Sjungma@eit.uni-kl.de
291312027Sjungma@eit.uni-kl.de    if( (q_bit( x ) && ! q_zero( x )) ||
291412027Sjungma@eit.uni-kl.de	(q_bit( x ) && q_zero( x ) && q_odd( x )) )
291512027Sjungma@eit.uni-kl.de	q_incr( x );
291612027Sjungma@eit.uni-kl.de    q_clear( x );
291712027Sjungma@eit.uni-kl.de
291812027Sjungma@eit.uni-kl.de    find_sw();
291912027Sjungma@eit.uni-kl.de
292012027Sjungma@eit.uni-kl.de    m_r_flag = true;
292112027Sjungma@eit.uni-kl.de}
292212027Sjungma@eit.uni-kl.de
292312027Sjungma@eit.uni-kl.de} // namespace sc_dt
292412027Sjungma@eit.uni-kl.de
292512027Sjungma@eit.uni-kl.de
292612027Sjungma@eit.uni-kl.de// Taf!
2927