sc_fxval.cc revision 13322:7391057615bd
110263Satgutier@umich.edu/***************************************************************************** 212566Snikos.nikoleris@arm.com 310263Satgutier@umich.edu Licensed to Accellera Systems Initiative Inc. (Accellera) under one or 410263Satgutier@umich.edu more contributor license agreements. See the NOTICE file distributed 510263Satgutier@umich.edu with this work for additional information regarding copyright ownership. 610263Satgutier@umich.edu Accellera licenses this file to you under the Apache License, Version 2.0 710263Satgutier@umich.edu (the "License"); you may not use this file except in compliance with the 810263Satgutier@umich.edu License. You may obtain a copy of the License at 910263Satgutier@umich.edu 1010263Satgutier@umich.edu http://www.apache.org/licenses/LICENSE-2.0 1110263Satgutier@umich.edu 1210263Satgutier@umich.edu Unless required by applicable law or agreed to in writing, software 1310263Satgutier@umich.edu distributed under the License is distributed on an "AS IS" BASIS, 1410263Satgutier@umich.edu WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 1510263Satgutier@umich.edu implied. See the License for the specific language governing 1610263Satgutier@umich.edu permissions and limitations under the License. 1710263Satgutier@umich.edu 1810263Satgutier@umich.edu *****************************************************************************/ 1910263Satgutier@umich.edu 2010263Satgutier@umich.edu/***************************************************************************** 2110263Satgutier@umich.edu 2210263Satgutier@umich.edu sc_fxval.cpp - 2310263Satgutier@umich.edu 2410263Satgutier@umich.edu Original Author: Martin Janssen, Synopsys, Inc. 2510263Satgutier@umich.edu 2610263Satgutier@umich.edu *****************************************************************************/ 2710263Satgutier@umich.edu 2810263Satgutier@umich.edu/***************************************************************************** 2910263Satgutier@umich.edu 3010263Satgutier@umich.edu MODIFICATION LOG - modifiers, enter your name, affiliation, date and 3110263Satgutier@umich.edu changes you are making here. 3210263Satgutier@umich.edu 3310263Satgutier@umich.edu Name, Affiliation, Date: 3410263Satgutier@umich.edu Description of Modification: 3510263Satgutier@umich.edu 3610263Satgutier@umich.edu *****************************************************************************/ 3710263Satgutier@umich.edu 3810263Satgutier@umich.edu 3910263Satgutier@umich.edu// $Log: sc_fxval.cpp,v $ 4010263Satgutier@umich.edu// Revision 1.1.1.1 2006/12/15 20:20:04 acg 4110263Satgutier@umich.edu// SystemC 2.3 4210263Satgutier@umich.edu// 4310263Satgutier@umich.edu// Revision 1.3 2006/01/13 18:53:58 acg 4410263Satgutier@umich.edu// Andy Goodrich: added $Log command so that CVS comments are reproduced in 4510263Satgutier@umich.edu// the source. 4610263Satgutier@umich.edu// 4710263Satgutier@umich.edu 4812492Sodanrc@yahoo.com.br#include <cctype> 4912492Sodanrc@yahoo.com.br#include <cfloat> 5010263Satgutier@umich.edu#include <cmath> 5110263Satgutier@umich.edu#include <cstdlib> 5210263Satgutier@umich.edu 5312548Sodanrc@yahoo.com.br#include "systemc/ext/dt/fx/sc_fxval.hh" 5412548Sodanrc@yahoo.com.br#include "systemc/ext/utils/messages.hh" 5510263Satgutier@umich.edu 5611486Snikos.nikoleris@arm.comnamespace sc_dt 5711486Snikos.nikoleris@arm.com{ 5810263Satgutier@umich.edu 5910263Satgutier@umich.edu// ---------------------------------------------------------------------------- 6010263Satgutier@umich.edu// CLASS : sc_fxval 6110263Satgutier@umich.edu// 6210263Satgutier@umich.edu// Fixed-point value type; arbitrary precision. 6310263Satgutier@umich.edu// ---------------------------------------------------------------------------- 6410263Satgutier@umich.edu 6510263Satgutier@umich.edu// explicit conversion to character string 6610263Satgutier@umich.edu 6710263Satgutier@umich.educonst std::string 6810263Satgutier@umich.edusc_fxval::to_string() const 6910263Satgutier@umich.edu{ 7010263Satgutier@umich.edu return std::string(m_rep->to_string(SC_DEC, -1, SC_E)); 7110263Satgutier@umich.edu} 7210263Satgutier@umich.edu 7310263Satgutier@umich.educonst std::string 7410263Satgutier@umich.edusc_fxval::to_string(sc_numrep numrep) const 7510263Satgutier@umich.edu{ 7610263Satgutier@umich.edu return std::string(m_rep->to_string(numrep, -1, SC_E)); 7710263Satgutier@umich.edu} 7810263Satgutier@umich.edu 7910263Satgutier@umich.educonst std::string 8010263Satgutier@umich.edusc_fxval::to_string(sc_numrep numrep, bool w_prefix) const 8110263Satgutier@umich.edu{ 8210263Satgutier@umich.edu return std::string(m_rep->to_string(numrep, (w_prefix ? 1 : 0), SC_E)); 8310263Satgutier@umich.edu} 8410263Satgutier@umich.edu 8510263Satgutier@umich.educonst std::string 8610263Satgutier@umich.edusc_fxval::to_string(sc_fmt fmt) const 8710263Satgutier@umich.edu{ 8810941Sdavid.guillen@arm.com return std::string(m_rep->to_string(SC_DEC, -1, fmt)); 8910941Sdavid.guillen@arm.com} 9012548Sodanrc@yahoo.com.br 9112548Sodanrc@yahoo.com.brconst std::string 9212548Sodanrc@yahoo.com.brsc_fxval::to_string(sc_numrep numrep, sc_fmt fmt) const 9312548Sodanrc@yahoo.com.br{ 9412548Sodanrc@yahoo.com.br return std::string(m_rep->to_string(numrep, -1, fmt)); 9512548Sodanrc@yahoo.com.br} 9610263Satgutier@umich.edu 9710263Satgutier@umich.educonst std::string 9812548Sodanrc@yahoo.com.brsc_fxval::to_string(sc_numrep numrep, bool w_prefix, sc_fmt fmt) const 9910263Satgutier@umich.edu{ 10010263Satgutier@umich.edu return std::string(m_rep->to_string(numrep, (w_prefix ? 1 : 0), fmt)); 10110263Satgutier@umich.edu} 10210263Satgutier@umich.edu 10312548Sodanrc@yahoo.com.br 10410263Satgutier@umich.educonst std::string 10510263Satgutier@umich.edusc_fxval::to_dec() const 10610263Satgutier@umich.edu{ 10710263Satgutier@umich.edu return std::string(m_rep->to_string(SC_DEC, -1, SC_E)); 10810263Satgutier@umich.edu} 10910263Satgutier@umich.edu 11010263Satgutier@umich.educonst std::string 11110263Satgutier@umich.edusc_fxval::to_bin() const 11210263Satgutier@umich.edu{ 11310263Satgutier@umich.edu return std::string(m_rep->to_string(SC_BIN, -1, SC_E)); 11410263Satgutier@umich.edu} 11510263Satgutier@umich.edu 11610263Satgutier@umich.educonst std::string 11710263Satgutier@umich.edusc_fxval::to_oct() const 11810263Satgutier@umich.edu{ 11910263Satgutier@umich.edu return std::string(m_rep->to_string(SC_OCT, -1, SC_E)); 12010263Satgutier@umich.edu} 12110263Satgutier@umich.edu 12210263Satgutier@umich.educonst std::string 12310263Satgutier@umich.edusc_fxval::to_hex() const 12410263Satgutier@umich.edu{ 12512548Sodanrc@yahoo.com.br return std::string(m_rep->to_string(SC_HEX, -1, SC_E)); 12610263Satgutier@umich.edu} 12710263Satgutier@umich.edu 12810941Sdavid.guillen@arm.com 12910941Sdavid.guillen@arm.com// print or dump content 13010941Sdavid.guillen@arm.com 13110941Sdavid.guillen@arm.comvoid sc_fxval::print(::std::ostream &os) const { m_rep->print(os); } 13210941Sdavid.guillen@arm.com 13311169Sandreas.hansson@arm.comvoid 13410941Sdavid.guillen@arm.comsc_fxval::scan(::std::istream &is) 13510941Sdavid.guillen@arm.com{ 13610263Satgutier@umich.edu std::string s; 13711484Snikos.nikoleris@arm.com is >> s; 13810263Satgutier@umich.edu *this = s.c_str(); 13910263Satgutier@umich.edu} 14010263Satgutier@umich.edu 14110263Satgutier@umich.eduvoid 14210263Satgutier@umich.edusc_fxval::dump(::std::ostream &os) const 14310263Satgutier@umich.edu{ 14410263Satgutier@umich.edu os << "sc_fxval" << ::std::endl; 14511870Snikos.nikoleris@arm.com os << "(" << ::std::endl; 14610263Satgutier@umich.edu os << "rep = "; 14712555Sodanrc@yahoo.com.br m_rep->dump(os); 14810263Satgutier@umich.edu // TO BE COMPLETED 14910263Satgutier@umich.edu // os << "r_flag = " << m_r_flag << ::std::endl; 15010263Satgutier@umich.edu // os << "observer = "; 15110263Satgutier@umich.edu // if (m_observer != 0) 15210941Sdavid.guillen@arm.com // m_observer->dump(os); 15310263Satgutier@umich.edu // else 15411484Snikos.nikoleris@arm.com // os << "0" << ::std::endl; 15510263Satgutier@umich.edu os << ")" << ::std::endl; 15610263Satgutier@umich.edu} 15710263Satgutier@umich.edu 15810941Sdavid.guillen@arm.com// protected methods and friend functions 15910263Satgutier@umich.edusc_fxval_observer * 16010263Satgutier@umich.edusc_fxval::lock_observer() const 16111484Snikos.nikoleris@arm.com{ 16211722Ssophiane.senni@gmail.com SC_ASSERT_(m_observer != 0, "lock observer failed"); 16311722Ssophiane.senni@gmail.com sc_fxval_observer *tmp = m_observer; 16411722Ssophiane.senni@gmail.com m_observer = 0; 16511722Ssophiane.senni@gmail.com return tmp; 16611722Ssophiane.senni@gmail.com} 16711722Ssophiane.senni@gmail.com 16811722Ssophiane.senni@gmail.comvoid 16911722Ssophiane.senni@gmail.comsc_fxval::unlock_observer(sc_fxval_observer *observer_) const 17011722Ssophiane.senni@gmail.com{ 17110263Satgutier@umich.edu SC_ASSERT_(observer_ != 0, "unlock observer failed"); 17210263Satgutier@umich.edu m_observer = observer_; 17311722Ssophiane.senni@gmail.com} 17411722Ssophiane.senni@gmail.com 17511722Ssophiane.senni@gmail.com 17610263Satgutier@umich.edu// ---------------------------------------------------------------------------- 17710263Satgutier@umich.edu// CLASS : sc_fxval_fast 17810263Satgutier@umich.edu// 17910263Satgutier@umich.edu// Fixed-point value types; limited precision. 18010263Satgutier@umich.edu// ---------------------------------------------------------------------------- 18110263Satgutier@umich.edu 18210263Satgutier@umich.edustatic void 18310263Satgutier@umich.eduprint_dec(scfx_string &s, scfx_ieee_double id, int w_prefix, sc_fmt fmt) 18410263Satgutier@umich.edu{ 18510263Satgutier@umich.edu if (id.negative() != 0) { 18610263Satgutier@umich.edu id.negative(0); 18710263Satgutier@umich.edu s += '-'; 18810263Satgutier@umich.edu } 18911169Sandreas.hansson@arm.com 19010263Satgutier@umich.edu if (w_prefix == 1) { 19110263Satgutier@umich.edu scfx_print_prefix(s, SC_DEC); 19210263Satgutier@umich.edu } 19310263Satgutier@umich.edu 19410263Satgutier@umich.edu if (id.is_zero()) { 19510263Satgutier@umich.edu s += '0'; 19610263Satgutier@umich.edu return; 19710263Satgutier@umich.edu } 19811169Sandreas.hansson@arm.com 19910263Satgutier@umich.edu // split 'id' into its integer and fractional part 20011484Snikos.nikoleris@arm.com double int_part; 20110263Satgutier@umich.edu double frac_part = std::modf(static_cast<double>(id), &int_part); 20210263Satgutier@umich.edu 20310263Satgutier@umich.edu int i; 20410941Sdavid.guillen@arm.com 20510263Satgutier@umich.edu // print integer part 20610941Sdavid.guillen@arm.com int int_digits = 0; 20710263Satgutier@umich.edu int int_zeros = 0; 20810263Satgutier@umich.edu 20910263Satgutier@umich.edu if (int_part != 0.0) { 21010263Satgutier@umich.edu int_digits = (int)std::ceil(std::log10(int_part + 1.0)); 21110263Satgutier@umich.edu 21210263Satgutier@umich.edu int len = s.length(); 21310263Satgutier@umich.edu s.append(int_digits); 21410263Satgutier@umich.edu 21510263Satgutier@umich.edu bool zero_digits = (frac_part == 0.0 && fmt != SC_F); 21610263Satgutier@umich.edu 21710263Satgutier@umich.edu for (i = int_digits + len - 1; i >= len; i--) { 21811169Sandreas.hansson@arm.com unsigned int remainder = (unsigned int)std::fmod(int_part, 10.0); 21910263Satgutier@umich.edu s[i] = static_cast<char>('0' + remainder); 22010263Satgutier@umich.edu 22110263Satgutier@umich.edu if (zero_digits) { 22210263Satgutier@umich.edu if (remainder == 0) 22310274Smitch.hayenga@arm.com int_zeros++; 22410263Satgutier@umich.edu else 22510263Satgutier@umich.edu zero_digits = false; 22610263Satgutier@umich.edu } 22710263Satgutier@umich.edu 22810263Satgutier@umich.edu int_part /= 10.0; 22910263Satgutier@umich.edu } 23010263Satgutier@umich.edu 23110263Satgutier@umich.edu // discard trailing zeros from int_part 23210263Satgutier@umich.edu s.discard(int_zeros); 23310263Satgutier@umich.edu 23410263Satgutier@umich.edu if (s[len] == '0') { 23510263Satgutier@umich.edu // int_digits was overestimated by one 23610263Satgutier@umich.edu s.remove(len); 23710263Satgutier@umich.edu --int_digits; 23810263Satgutier@umich.edu } 23910263Satgutier@umich.edu } 24012554Snikos.nikoleris@arm.com 24110263Satgutier@umich.edu // print fractional part 24210263Satgutier@umich.edu int frac_digits = 0; 24310263Satgutier@umich.edu int frac_zeros = 0; 24412557Sodanrc@yahoo.com.br 24512557Sodanrc@yahoo.com.br if (frac_part != 0.0) { 24612557Sodanrc@yahoo.com.br s += '.'; 24710263Satgutier@umich.edu 24810274Smitch.hayenga@arm.com bool zero_digits = (int_digits == 0 && fmt != SC_F); 24910263Satgutier@umich.edu 25010263Satgutier@umich.edu frac_zeros = (int)std::floor(-std::log10(frac_part + DBL_EPSILON)); 25110263Satgutier@umich.edu 25210263Satgutier@umich.edu frac_part *= std::pow(10.0, frac_zeros); 25310263Satgutier@umich.edu 25410263Satgutier@umich.edu frac_digits = frac_zeros; 25510263Satgutier@umich.edu if (!zero_digits) { 25610263Satgutier@umich.edu for (i = 0; i < frac_zeros; i++) 25710263Satgutier@umich.edu s += '0'; 25810263Satgutier@umich.edu frac_zeros = 0; 25910263Satgutier@umich.edu } 26010263Satgutier@umich.edu 26110263Satgutier@umich.edu while (frac_part != 0.0) { 26210263Satgutier@umich.edu frac_part *= 10.0; 26310263Satgutier@umich.edu int n = static_cast<int>(frac_part); 26410263Satgutier@umich.edu 26510941Sdavid.guillen@arm.com if (zero_digits) { 26610941Sdavid.guillen@arm.com if (n == 0) 26710941Sdavid.guillen@arm.com frac_zeros++; 26811169Sandreas.hansson@arm.com else 26910941Sdavid.guillen@arm.com zero_digits = false; 27010941Sdavid.guillen@arm.com } 27110941Sdavid.guillen@arm.com 27210941Sdavid.guillen@arm.com if (!zero_digits) 27310941Sdavid.guillen@arm.com s += static_cast<char>('0' + n); 27410941Sdavid.guillen@arm.com 27510941Sdavid.guillen@arm.com frac_part -= n; 27610941Sdavid.guillen@arm.com frac_digits++; 27710941Sdavid.guillen@arm.com } 27811169Sandreas.hansson@arm.com } 27910941Sdavid.guillen@arm.com 28010941Sdavid.guillen@arm.com // print exponent 28110941Sdavid.guillen@arm.com if (fmt != SC_F) { 28210941Sdavid.guillen@arm.com if (frac_digits == 0) 28310941Sdavid.guillen@arm.com scfx_print_exp(s, int_zeros); 28410263Satgutier@umich.edu else if (int_digits == 0) 28510263Satgutier@umich.edu scfx_print_exp(s, -frac_zeros); 28610263Satgutier@umich.edu } 28710263Satgutier@umich.edu} 28811169Sandreas.hansson@arm.com 28910263Satgutier@umich.edustatic void 29010263Satgutier@umich.eduprint_other(scfx_string &s, const scfx_ieee_double &id, sc_numrep numrep, 29110263Satgutier@umich.edu int w_prefix, sc_fmt fmt, const scfx_params *params) 29210263Satgutier@umich.edu{ 29310263Satgutier@umich.edu scfx_ieee_double id2 = id; 29410263Satgutier@umich.edu 29510263Satgutier@umich.edu sc_numrep numrep2 = numrep; 29610263Satgutier@umich.edu 29710263Satgutier@umich.edu bool numrep_is_sm = (numrep == SC_BIN_SM || 29811169Sandreas.hansson@arm.com numrep == SC_OCT_SM || 29910263Satgutier@umich.edu numrep == SC_HEX_SM); 30010263Satgutier@umich.edu 30110263Satgutier@umich.edu if (numrep_is_sm) { 30210263Satgutier@umich.edu if (id2.negative() != 0) { 30310263Satgutier@umich.edu s += '-'; 30412574Sodanrc@yahoo.com.br id2.negative(0); 30512574Sodanrc@yahoo.com.br } 30612574Sodanrc@yahoo.com.br switch (numrep) { 30712574Sodanrc@yahoo.com.br case SC_BIN_SM: 30810263Satgutier@umich.edu numrep2 = SC_BIN_US; 30912574Sodanrc@yahoo.com.br break; 31010263Satgutier@umich.edu case SC_OCT_SM: 31112574Sodanrc@yahoo.com.br numrep2 = SC_OCT_US; 31210263Satgutier@umich.edu break; 31310263Satgutier@umich.edu case SC_HEX_SM: 31410263Satgutier@umich.edu numrep2 = SC_HEX_US; 31510263Satgutier@umich.edu break; 31610263Satgutier@umich.edu default: 31711169Sandreas.hansson@arm.com ; 31810263Satgutier@umich.edu } 31910263Satgutier@umich.edu } 32010263Satgutier@umich.edu 32110263Satgutier@umich.edu if (w_prefix != 0) { 32211169Sandreas.hansson@arm.com scfx_print_prefix(s, numrep); 32310263Satgutier@umich.edu } 32410263Satgutier@umich.edu 32510263Satgutier@umich.edu numrep = numrep2; 32610263Satgutier@umich.edu 32711169Sandreas.hansson@arm.com sc_fxval_fast a(id2); 32810263Satgutier@umich.edu 32910263Satgutier@umich.edu int msb, lsb; 33010263Satgutier@umich.edu 33110263Satgutier@umich.edu if (params != 0) { 33210263Satgutier@umich.edu msb = params->iwl() - 1; 33310263Satgutier@umich.edu lsb = params->iwl() - params->wl(); 33410263Satgutier@umich.edu 33510263Satgutier@umich.edu if (params->enc() == SC_TC_ && 33610263Satgutier@umich.edu (numrep == SC_BIN_US || 33710263Satgutier@umich.edu numrep == SC_OCT_US || 33810263Satgutier@umich.edu numrep == SC_HEX_US) && 33910263Satgutier@umich.edu !numrep_is_sm && 34010263Satgutier@umich.edu params->wl() > 1) { 34111168Sandreas.hansson@arm.com --msb; 34210263Satgutier@umich.edu } else if (params->enc() == SC_US_ && 34310263Satgutier@umich.edu (numrep == SC_BIN || 34410263Satgutier@umich.edu numrep == SC_OCT || 34510263Satgutier@umich.edu numrep == SC_HEX || 34610263Satgutier@umich.edu numrep == SC_CSD)) { 34710263Satgutier@umich.edu ++msb; 34810263Satgutier@umich.edu } 34912492Sodanrc@yahoo.com.br } else { 350 if (a.is_zero()) { 351 msb = 0; 352 lsb = 0; 353 } else { 354 msb = id2.exponent() + 1; 355 while (a.get_bit(msb) == a.get_bit(msb - 1)) 356 --msb; 357 358 if (numrep == SC_BIN_US || 359 numrep == SC_OCT_US || 360 numrep == SC_HEX_US) { 361 --msb; 362 } 363 364 lsb = id2.exponent() - 52; 365 while (!a.get_bit(lsb)) 366 ++lsb; 367 } 368 } 369 370 int step; 371 372 switch (numrep) { 373 case SC_BIN: 374 case SC_BIN_US: 375 case SC_CSD: 376 step = 1; 377 break; 378 case SC_OCT: 379 case SC_OCT_US: 380 step = 3; 381 break; 382 case SC_HEX: 383 case SC_HEX_US: 384 step = 4; 385 break; 386 default: 387 SC_REPORT_FATAL(sc_core::SC_ID_ASSERTION_FAILED_, 388 "unexpected sc_numrep"); 389 sc_core::sc_abort(); 390 } 391 392 msb = (int)std::ceil(double(msb + 1) / step) * step - 1; 393 394 lsb = (int)std::floor(double(lsb) / step) * step; 395 396 if (msb < 0) { 397 s += '.'; 398 if (fmt == SC_F) { 399 int sign = (id2.negative() != 0) ? (1 << step) - 1 : 0; 400 for (int i = (msb + 1) / step; i < 0; i++) { 401 if (sign < 10) 402 s += static_cast<char>(sign + '0'); 403 else 404 s += static_cast<char>(sign + 'a' - 10); 405 } 406 } 407 } 408 409 int i = msb; 410 while (i >= lsb) { 411 int value = 0; 412 for (int j = step - 1; j >= 0; --j) { 413 value += static_cast<int>(a.get_bit(i)) << j; 414 --i; 415 } 416 if (value < 10) 417 s += static_cast<char>(value + '0'); 418 else 419 s += static_cast<char>(value + 'a' - 10); 420 if (i == -1) 421 s += '.'; 422 } 423 424 if (lsb > 0 && fmt == SC_F) { 425 for (int i = lsb / step; i > 0; i--) 426 s += '0'; 427 } 428 429 if (s[s.length() - 1] == '.') 430 s.discard(1); 431 432 if (fmt != SC_F) { 433 if (msb < 0) 434 scfx_print_exp(s, (msb + 1) / step); 435 else if (lsb > 0) 436 scfx_print_exp(s, lsb / step); 437 } 438 439 if (numrep == SC_CSD) 440 scfx_tc2csd(s, w_prefix); 441} 442 443const char * 444to_string(const scfx_ieee_double &id, sc_numrep numrep, int w_prefix, 445 sc_fmt fmt, const scfx_params *params=0) 446{ 447 static scfx_string s; 448 449 s.clear(); 450 451 if (id.is_nan()) { 452 scfx_print_nan(s); 453 } else if (id.is_inf()) { 454 scfx_print_inf(s, static_cast<bool>(id.negative())); 455 } else if (id.negative() && !id.is_zero() && 456 (numrep == SC_BIN_US || 457 numrep == SC_OCT_US || 458 numrep == SC_HEX_US)) { 459 s += "negative"; 460 } else if (numrep == SC_DEC) { 461 sc_dt::print_dec(s, id, w_prefix, fmt); 462 } else { 463 sc_dt::print_other(s, id, numrep, w_prefix, fmt, params); 464 } 465 466 return s; 467} 468 469 470// explicit conversion to character string 471const std::string 472sc_fxval_fast::to_string() const 473{ 474 return std::string(sc_dt::to_string(m_val, SC_DEC, -1, SC_E)); 475} 476 477const std::string 478sc_fxval_fast::to_string(sc_numrep numrep) const 479{ 480 return std::string(sc_dt::to_string(m_val, numrep, -1, SC_E)); 481} 482 483const std::string 484sc_fxval_fast::to_string(sc_numrep numrep, bool w_prefix) const 485{ 486 return std::string(sc_dt::to_string(m_val, numrep, (w_prefix ? 1 : 0), 487 SC_E)); 488} 489 490const std::string 491sc_fxval_fast::to_string(sc_fmt fmt) const 492{ 493 return std::string(sc_dt::to_string(m_val, SC_DEC, -1, fmt)); 494} 495 496const std::string 497sc_fxval_fast::to_string(sc_numrep numrep, sc_fmt fmt) const 498{ 499 return std::string(sc_dt::to_string(m_val, numrep, -1, fmt)); 500} 501 502const std::string 503sc_fxval_fast::to_string(sc_numrep numrep, bool w_prefix, sc_fmt fmt) const 504{ 505 return std::string(sc_dt::to_string(m_val, numrep, (w_prefix ? 1 : 0), 506 fmt)); 507} 508 509const std::string 510sc_fxval_fast::to_dec() const 511{ 512 return std::string(sc_dt::to_string(m_val, SC_DEC, -1, SC_E)); 513} 514 515const std::string 516sc_fxval_fast::to_bin() const 517{ 518 return std::string(sc_dt::to_string(m_val, SC_BIN, -1, SC_E)); 519} 520 521const std::string 522sc_fxval_fast::to_oct() const 523{ 524 return std::string(sc_dt::to_string(m_val, SC_OCT, -1, SC_E)); 525} 526 527const std::string 528sc_fxval_fast::to_hex() const 529{ 530 return std::string(sc_dt::to_string(m_val, SC_HEX, -1, SC_E)); 531} 532 533 534// print or dump content 535 536void 537sc_fxval_fast::print(::std::ostream &os) const 538{ 539 os << sc_dt::to_string(m_val, SC_DEC, -1, SC_E); 540} 541 542void 543sc_fxval_fast::scan(::std::istream &is) 544{ 545 std::string s; 546 is >> s; 547 *this = s.c_str(); 548} 549 550void 551sc_fxval_fast::dump(::std::ostream &os) const 552{ 553 os << "sc_fxval_fast" << ::std::endl; 554 os << "(" << ::std::endl; 555 os << "val = " << m_val << ::std::endl; 556 // TO BE COMPLETED 557 // os << "r_flag = " << m_r_flag << ::std::endl; 558 // os << "observer = "; 559 // if (m_observer != 0) 560 // m_observer->dump(os); 561 // else 562 // os << "0" << ::std::endl; 563 os << ")" << ::std::endl; 564} 565 566 567// internal use only; 568bool 569sc_fxval_fast::get_bit(int i) const 570{ 571 scfx_ieee_double id(m_val); 572 if (id.is_zero() || id.is_nan() || id.is_inf()) 573 return false; 574 575 // convert to two's complement 576 unsigned int m0 = id.mantissa0(); 577 unsigned int m1 = id.mantissa1(); 578 579 if (id.is_normal()) 580 m0 += 1U << 20; 581 582 if (id.negative() != 0) { 583 m0 = ~ m0; 584 m1 = ~ m1; 585 unsigned int tmp = m1; 586 m1 += 1U; 587 if (m1 <= tmp) 588 m0 += 1U; 589 } 590 591 // get the right bit 592 int j = i - id.exponent(); 593 if ((j += 20) >= 32) 594 return ((m0 & 1U << 31) != 0); 595 else if (j >= 0) 596 return ((m0 & 1U << j) != 0); 597 else if ((j += 32) >= 0) 598 return ((m1 & 1U << j) != 0); 599 else 600 return false; 601} 602 603 604// protected methods and friend functions 605sc_fxval_fast_observer * 606sc_fxval_fast::lock_observer() const 607{ 608 SC_ASSERT_(m_observer != 0, "lock observer failed"); 609 sc_fxval_fast_observer *tmp = m_observer; 610 m_observer = 0; 611 return tmp; 612} 613 614void 615sc_fxval_fast::unlock_observer(sc_fxval_fast_observer *observer_) const 616{ 617 SC_ASSERT_(observer_ != 0, "unlock observer failed"); 618 m_observer = observer_; 619} 620 621#define SCFX_FAIL_IF_(cnd) \ 622{ \ 623 if ((cnd)) \ 624 return static_cast<double>(scfx_ieee_double::nan()); \ 625} 626 627double 628sc_fxval_fast::from_string(const char *s) 629{ 630 SCFX_FAIL_IF_(s == 0 || *s == 0); 631 632 scfx_string s2; 633 s2 += s; 634 s2 += '\0'; 635 636 bool sign_char; 637 int sign = scfx_parse_sign(s, sign_char); 638 639 sc_numrep numrep = scfx_parse_prefix(s); 640 641 int base = 0; 642 643 switch (numrep) { 644 case SC_DEC: 645 { 646 base = 10; 647 if (scfx_is_nan(s)) // special case: NaN 648 return static_cast<double>(scfx_ieee_double::nan()); 649 if (scfx_is_inf(s)) // special case: Infinity 650 return static_cast<double>(scfx_ieee_double::inf(sign)); 651 break; 652 } 653 case SC_BIN: 654 case SC_BIN_US: 655 { 656 SCFX_FAIL_IF_(sign_char); 657 base = 2; 658 break; 659 } 660 661 case SC_BIN_SM: 662 { 663 base = 2; 664 break; 665 } 666 case SC_OCT: 667 case SC_OCT_US: 668 { 669 SCFX_FAIL_IF_(sign_char); 670 base = 8; 671 break; 672 } 673 case SC_OCT_SM: 674 { 675 base = 8; 676 break; 677 } 678 case SC_HEX: 679 case SC_HEX_US: 680 { 681 SCFX_FAIL_IF_(sign_char); 682 base = 16; 683 break; 684 } 685 case SC_HEX_SM: 686 { 687 base = 16; 688 break; 689 } 690 case SC_CSD: 691 { 692 SCFX_FAIL_IF_(sign_char); 693 base = 2; 694 scfx_csd2tc(s2); 695 s = (const char*) s2 + 4; 696 numrep = SC_BIN; 697 break; 698 } 699 default:;// Martin, what is default??? 700 } 701 702 // 703 // find end of mantissa and count the digits and points 704 // 705 706 const char *end = s; 707 bool based_point = false; 708 int int_digits = 0; 709 int frac_digits = 0; 710 711 while (*end) { 712 if (scfx_exp_start(end)) 713 break; 714 715 if (*end == '.') { 716 SCFX_FAIL_IF_(based_point); 717 based_point = true; 718 } else { 719 SCFX_FAIL_IF_(!scfx_is_digit(*end, numrep)); 720 if (based_point) 721 frac_digits++; 722 else 723 int_digits++; 724 } 725 726 end++; 727 } 728 729 SCFX_FAIL_IF_(int_digits == 0 && frac_digits == 0); 730 731 // [ exponent ] 732 int exponent = 0; 733 if (*end) { 734 for (const char *e = end + 2; *e; e++) 735 SCFX_FAIL_IF_(!scfx_is_digit(*e, SC_DEC)); 736 exponent = std::atoi(end + 1); 737 } 738 739 // 740 // convert the mantissa 741 // 742 double integer = 0.0; 743 if (int_digits != 0) { 744 bool first_digit = true; 745 746 for (; s < end; s++) { 747 if (*s == '.') 748 break; 749 750 if (first_digit) { 751 integer = scfx_to_digit(*s, numrep); 752 switch (numrep) { 753 case SC_BIN: 754 case SC_OCT: 755 case SC_HEX: 756 { 757 if (integer >= (base >> 1)) 758 integer -= base; // two's complement 759 break; 760 } 761 default: 762 ; 763 } 764 first_digit = false; 765 } else { 766 integer *= base; 767 integer += scfx_to_digit(*s, numrep); 768 } 769 } 770 } 771 772 // [ . fraction ] 773 double fraction = 0.0; 774 if (frac_digits != 0) { 775 s++; // skip '.' 776 777 bool first_digit = (int_digits == 0); 778 double scale = 1.0; 779 for (; s < end; s++) { 780 scale /= base; 781 782 if (first_digit) { 783 fraction = scfx_to_digit(*s, numrep); 784 switch (numrep) { 785 case SC_BIN: 786 case SC_OCT: 787 case SC_HEX: 788 { 789 if (fraction >= (base >> 1)) 790 fraction -= base; // two's complement 791 break; 792 } 793 default: 794 ; 795 } 796 fraction *= scale; 797 first_digit = false; 798 } else { 799 fraction += scfx_to_digit(*s, numrep) * scale; 800 } 801 } 802 } 803 804 double exp = 805 (exponent != 0) ? std::pow((double) base, (double) exponent) : 1; 806 807 return (sign * (integer + fraction) * exp); 808} 809 810#undef SCFX_FAIL_IF_ 811 812} // namespace sc_dt 813