⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 corbafixed.cc

📁 编译工具
💻 CC
📖 第 1 页 / 共 2 页
字号:
// -*- Mode: C++; -*-//                            Package   : omniORB// corbaFixed.cc              Created on: 07/02/2001//                            Author    : Duncan Grisby (dpg1)////    Copyright (C) 2001 AT&T Laboratories Cambridge////    This file is part of the omniORB library////    The omniORB library is free software; you can redistribute it and/or//    modify it under the terms of the GNU Library General Public//    License as published by the Free Software Foundation; either//    version 2 of the License, or (at your option) any later version.////    This library is distributed in the hope that it will be useful,//    but WITHOUT ANY WARRANTY; without even the implied warranty of//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU//    Library General Public License for more details.////    You should have received a copy of the GNU Library General Public//    License along with this library; if not, write to the Free//    Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA//    02111-1307, USA////// Description:////    Implementation of the fixed point type// $Log: corbaFixed.cc,v $// Revision 1.1.2.18  2005/03/29 16:09:48  dgrisby// Copying too many digits if truncating a fixed point value.//// Revision 1.1.2.17  2005/03/03 12:45:56  dgrisby// Bug in fixed point multiplication. Thanks Simone Viani.//// Revision 1.1.2.16  2004/10/17 20:14:32  dgrisby// Updated support for OpenVMS. Many thanks to Bruce Visscher.//// Revision 1.1.2.15  2004/07/23 13:22:53  dgrisby// Fixed point rounding was still broken.//// Revision 1.1.2.14  2004/07/01 19:15:17  dgrisby// Fix fixed point. It was broken point. Thanks Simone Viani.//// Revision 1.1.2.13  2003/06/02 13:26:14  dgrisby// Silly bug in fixed division when result has leading zeros.//// Revision 1.1.2.12  2003/02/25 12:35:20  dgrisby// Typo in assertion.//// Revision 1.1.2.11  2002/11/25 21:07:25  dgrisby// Add new to_string() function to Fixed.//// Revision 1.1.2.10  2002/07/12 10:17:30  dgrisby// Bug in fixed point unmarshal.//// Revision 1.1.2.9  2002/01/21 17:40:05  dpg1// Lost sign in Fixed->double conversion. (Thanks Slava Garelin)//// Revision 1.1.2.8  2001/11/14 17:13:43  dpg1// Long double support.//// Revision 1.1.2.7  2001/11/08 16:33:51  dpg1// Local servant POA shortcut policy.//// Revision 1.1.2.6  2001/10/17 16:44:06  dpg1// Update DynAny to CORBA 2.5 spec, const Any exception extraction.//// Revision 1.1.2.5  2001/08/17 13:47:32  dpg1// Small bug fixes.//// Revision 1.1.2.4  2001/08/03 17:41:18  sll// System exception minor code overhaul. When a system exeception is raised,// a meaning minor code is provided.//// Revision 1.1.2.3  2001/06/13 20:12:32  sll// Minor updates to make the ORB compiles with MSVC++.//// Revision 1.1.2.2  2001/04/09 15:18:46  dpg1// Tweak fixed point to make life easier for omniORBpy.//// Revision 1.1.2.1  2001/03/13 10:32:10  dpg1// Fixed point support.//#include <omniORB4/CORBA.h>#include <exceptiondefs.h>#include <stdio.h>#include <string.h>#include <ctype.h>OMNI_USING_NAMESPACE(omni)CORBA::Fixed::Fixed(int val) :  pd_digits(0), pd_scale(0), pd_negative(0), pd_idl_digits(0), pd_idl_scale(0){  if (val < 0) {    pd_negative = 1;    val = - val;  }  while (val) {    pd_val[pd_digits++] = val % 10;    val /= 10;  }  memset(pd_val + pd_digits, 0, OMNI_FIXED_DIGITS - pd_digits);}CORBA::Fixed::Fixed(unsigned val) :  pd_digits(0), pd_scale(0), pd_negative(0), pd_idl_digits(0), pd_idl_scale(0){  while (val) {    pd_val[pd_digits++] = val % 10;    val /= 10;  }  memset(pd_val + pd_digits, 0, OMNI_FIXED_DIGITS - pd_digits);}#ifndef OMNI_LONG_IS_INTCORBA::Fixed::Fixed(CORBA::Long val) :  pd_digits(0), pd_scale(0), pd_negative(0), pd_idl_digits(0), pd_idl_scale(0){  if (val < 0) {    pd_negative = 1;    val = - val;  }  while (val) {    pd_val[pd_digits++] = val % 10;    val /= 10;  }  memset(pd_val + pd_digits, 0, OMNI_FIXED_DIGITS - pd_digits);}CORBA::Fixed::Fixed(CORBA::ULong val) :  pd_digits(0), pd_scale(0), pd_negative(0), pd_idl_digits(0), pd_idl_scale(0){  while (val) {    pd_val[pd_digits++] = val % 10;    val /= 10;  }  memset(pd_val + pd_digits, 0, OMNI_FIXED_DIGITS - pd_digits);}#endif#ifdef HAS_LongLongCORBA::Fixed::Fixed(CORBA::LongLong val) :  pd_digits(0), pd_scale(0), pd_negative(0), pd_idl_digits(0), pd_idl_scale(0){  if (val < 0) {    pd_negative = 1;    val = - val;  }  while (val) {    pd_val[pd_digits++] = val % 10;    val /= 10;  }  memset(pd_val + pd_digits, 0, OMNI_FIXED_DIGITS - pd_digits);}CORBA::Fixed::Fixed(CORBA::ULongLong val) :  pd_digits(0), pd_scale(0), pd_negative(0), pd_idl_digits(0), pd_idl_scale(0){  while (val) {    pd_val[pd_digits++] = val % 10;    val /= 10;  }  memset(pd_val + pd_digits, 0, OMNI_FIXED_DIGITS - pd_digits);}#endif#ifndef NO_FLOATCORBA::Fixed::Fixed(CORBA::Double val) :  pd_idl_digits(0), pd_idl_scale(0){  if ((double)val > 1e32 || (double)val < -1e32) {    // Too big    OMNIORB_THROW(DATA_CONVERSION, DATA_CONVERSION_RangeError,		  CORBA::COMPLETED_NO);  }  char buffer[80];  int len = sprintf(buffer, "%.31f", val);  OMNIORB_ASSERT(len < 79);  NP_fromString(buffer);}#endif#ifdef HAS_LongDoubleCORBA::Fixed::Fixed(CORBA::LongDouble val) :  pd_idl_digits(0), pd_idl_scale(0){  if (val > 1e32 || val < -1e32) {    // Too big / small    OMNIORB_THROW(DATA_CONVERSION, DATA_CONVERSION_RangeError,		  CORBA::COMPLETED_NO);  }  char buffer[80];  int len = sprintf(buffer, "%.31f", (double)val);  OMNIORB_ASSERT(len < 79);  NP_fromString(buffer);}#endifCORBA::Fixed::Fixed(const Fixed& val) :  pd_digits    (val.pd_digits),  pd_scale     (val.pd_scale),  pd_negative  (val.pd_negative),  pd_idl_digits(0),  pd_idl_scale (0){  memcpy(pd_val, val.pd_val, OMNI_FIXED_DIGITS);}CORBA::Fixed::Fixed(const char* val) :  pd_idl_digits(0), pd_idl_scale(0){  NP_fromString(val);}CORBA::Fixed::Fixed(const CORBA::Octet* val,		    CORBA::UShort       digits,		    CORBA::UShort       scale,		    CORBA::Boolean      negative)  : pd_digits(digits), pd_scale(scale), pd_negative(negative),    pd_idl_digits(0), pd_idl_scale(0){  OMNIORB_ASSERT(digits <= OMNI_FIXED_DIGITS);  OMNIORB_ASSERT(scale  <= digits);  while (pd_digits > 0 && pd_scale > 0 && val[0] == 0) {    pd_digits--;    pd_scale--;    val++;  }  if (pd_digits == 0) pd_negative = 0;  memcpy(pd_val, val, pd_digits);  memset(pd_val + pd_digits, 0, OMNI_FIXED_DIGITS - pd_digits);}CORBA::Fixed::~Fixed(){}#ifdef HAS_LongLongCORBA::Fixed::operator CORBA::LongLong() const{  CORBA::LongLong r = 0, s;  for (int i = pd_digits - 1; i >= pd_scale; --i) {    s = r * 10 + pd_val[i];    if (s < r) {      // Overflow      OMNIORB_THROW(DATA_CONVERSION, DATA_CONVERSION_RangeError, 		    CORBA::COMPLETED_NO);    }    r = s;  }  if (pd_negative)    r = -r;  return r;}#elseCORBA::Fixed::operator CORBA::Long() const{  CORBA::Long r = 0, s;  for (int i = pd_digits - 1; i >= pd_scale; --i) {    s = r * 10 + pd_val[i];    if (s < r) {      // Overflow      OMNIORB_THROW(DATA_CONVERSION, DATA_CONVERSION_RangeError,		    CORBA::COMPLETED_NO);    }    r = s;  }  if (pd_negative)    r = -r;  return r;}#endif#ifndef NO_FLOAT#  ifdef HAS_LongDoubleCORBA::Fixed::operator CORBA::LongDouble() const{  CORBA::LongDouble r = 0, s = 0;  int i;  // Digits before decimal point  for (i = pd_digits - 1; i >= pd_scale; --i) {    r = r * 10 + pd_val[i];  }  // Digits after decimal point  for (i=0; i < pd_scale; ++i) {    s = (s + pd_val[i]) / 10;  }  if (pd_negative)    return -(r + s);  else    return r + s;}#  elseCORBA::Fixed::operator CORBA::Double() const{#ifdef __VMS  double r = 0, s = 0;#else  CORBA::Double r = 0, s = 0;#endif  int i;  // Digits before decimal point  for (i = pd_digits - 1; i >= pd_scale; --i) {    r = r * 10 + pd_val[i];  }  // Digits after decimal point  for (i=0; i < pd_scale; ++i) {    s = (s + pd_val[i]) / 10;  }  if (pd_negative)    return -(r + s);  else    return r + s;}#  endif#endifCORBA::FixedCORBA::Fixed::round(CORBA::UShort scale) const{  if (scale >= pd_scale)    return *this;  int cut = pd_scale - scale;  if (pd_val[cut - 1] >= 5) {    // Round up    CORBA::Octet work[OMNI_FIXED_DIGITS + 1];    memcpy(work, pd_val, OMNI_FIXED_DIGITS);    work[OMNI_FIXED_DIGITS] = 0;    int i = cut;    for (i = cut; i <= OMNI_FIXED_DIGITS; ++i) {      if (++work[i] <= 9) break;      work[i] = 0;    }    int new_digits = pd_digits - cut;    if (i >= pd_digits)      new_digits++;    return CORBA::Fixed(work + cut, new_digits, scale, pd_negative);  }  else    return CORBA::Fixed(pd_val + cut, pd_digits - cut, scale, pd_negative);}CORBA::FixedCORBA::Fixed::truncate(CORBA::UShort scale) const{  if (scale >= pd_scale)    return *this;  int cut      = pd_scale - scale;  int newscale = scale;  while (pd_val[cut] == 0 && newscale > 0) {    ++cut;    --newscale;  }  return CORBA::Fixed(pd_val + cut, pd_digits - cut, newscale, pd_negative);}CORBA::Fixed&CORBA::Fixed::operator=(const Fixed& val){  pd_digits   = val.pd_digits;  pd_scale    = val.pd_scale;  pd_negative = val.pd_negative;  memcpy(pd_val, val.pd_val, OMNI_FIXED_DIGITS);  PR_checkLimits();  return *this;}CORBA::Fixed&CORBA::Fixed::operator+=(const Fixed& val){  *this = *this + val;  return *this;}CORBA::Fixed&CORBA::Fixed::operator-=(const Fixed& val){  *this = *this - val;  return *this;}CORBA::Fixed&CORBA::Fixed::operator*=(const Fixed& val){  *this = *this * val;  return *this;}CORBA::Fixed&CORBA::Fixed::operator/=(const Fixed& val){  *this = *this / val;  return *this;}CORBA::Fixed&CORBA::Fixed::operator++(){  *this = *this + CORBA::Fixed(1);  return *this;}CORBA::FixedCORBA::Fixed::operator++(int){  CORBA::Fixed r(*this);  *this = *this + CORBA::Fixed(1);  return r;}CORBA::Fixed&CORBA::Fixed::operator--(){  *this = *this - CORBA::Fixed(1);  return *this;}CORBA::FixedCORBA::Fixed::operator--(int){  CORBA::Fixed r(*this);  *this = *this - CORBA::Fixed(1);  return r;}CORBA::FixedCORBA::Fixed::operator+() const{  return *this;}CORBA::FixedCORBA::Fixed::operator-() const{  if (pd_digits == 0)    return *this;  CORBA::Fixed r(*this);  r.pd_negative = !pd_negative;  return r;}CORBA::BooleanCORBA::Fixed::operator!() const{  return pd_digits == 0;}char*CORBA::Fixed::to_string() const{  int len = pd_digits + 1;  if (pd_negative)                      ++len; // for '-'  if (pd_digits == pd_scale)            ++len; // for '0'  if (pd_scale > 0 || pd_idl_scale > 0) ++len; // for '.'  if (pd_idl_scale > pd_scale)          len += pd_idl_scale - pd_scale;  char* r = CORBA::string_alloc(len);  int i = 0, j;  if (pd_negative)           r[i++] = '-';  if (pd_digits == pd_scale) r[i++] = '0';  for (j=pd_digits; j; ) {    if (j-- == pd_scale)      r[i++] = '.';    r[i++] = pd_val[j] + '0';  }  if (pd_idl_scale > pd_scale) {    if (pd_scale == 0)      r[i++] = '.';    for (j = pd_idl_scale - pd_scale; j; j--)      r[i++] = '0';  }  r[i] = '\0';  return r;}char*CORBA::Fixed::NP_asString() const{  int len = pd_digits + 1;  if (pd_negative)           ++len; // for '-'  if (pd_digits == pd_scale) ++len; // for '0'  if (pd_scale > 0)          ++len; // for '.'  char* r = CORBA::string_alloc(len);  int i = 0, j;  if (pd_negative)           r[i++] = '-';  if (pd_digits == pd_scale) r[i++] = '0';  for (j=pd_digits; j; ) {    if (j-- == pd_scale)      r[i++] = '.';    r[i++] = pd_val[j] + '0';  }  r[i] = '\0';  return r;}CORBA::BooleanCORBA::Fixed::NP_fromString(const char* s, CORBA::Boolean ignore_end){  CORBA::Boolean precise = 1;  // Skip leading white space  while (isspace(*s)) ++s;  // Sign  if (*s == '-') {    pd_negative = 1;    ++s;  }  else if (*s == '+') {    pd_negative = 0;    ++s;  }  else    pd_negative = 0;  // Check there are some digits  if (!((*s >= '0' && *s <= '9') || *s == '.')) {    OMNIORB_THROW(DATA_CONVERSION,		  DATA_CONVERSION_BadInput, CORBA::COMPLETED_NO);  }  // Skip leading zeros:  while (*s == '0') ++s;  int i, j, unscale = -1;  // Count digits  for (i=0, pd_digits=0; (s[i] >= '0' && s[i] <= '9') || s[i] == '.'; ++i) {    if (s[i] == '.') {      if (unscale != -1) {	// Already seen a decimal point	OMNIORB_THROW(DATA_CONVERSION,		      DATA_CONVERSION_BadInput, CORBA::COMPLETED_NO);      }      unscale = pd_digits;    }    else      ++pd_digits;  }  if (unscale == -1)    unscale = pd_digits;  pd_scale = pd_digits - unscale;  // Check there is no trailing garbage  if (!ignore_end) {    j = i;    if (s[i] == 'd' || s[i] == 'D') ++j;    while (s[j]) {      if (!isspace(s[j])) {	OMNIORB_THROW(DATA_CONVERSION,		      DATA_CONVERSION_BadInput, CORBA::COMPLETED_NO);      }      ++j;    }  }  --i; // i is now the index of the last digit  // Truncate if too many digits  while (pd_digits > OMNI_FIXED_DIGITS && pd_scale > 0) {    precise = 0;    --i; --pd_digits; --pd_scale;  }  // Back-up over trailing zeros  if (pd_scale > 0) {    while (s[i] == '0') {      --i; --pd_digits; --pd_scale;    }  }  if (pd_digits > OMNI_FIXED_DIGITS) {    OMNIORB_THROW(DATA_CONVERSION,		  DATA_CONVERSION_RangeError, CORBA::COMPLETED_NO);  }  // Scan back through the string, setting the value least  // siginificant digit first.  for (j=0; j < pd_digits; ++j, --i) {    if (s[i] == '.') --i;    pd_val[j] = s[i] - '0';  }  // Clear any remaining digits  memset(pd_val + j, 0, OMNI_FIXED_DIGITS - j);  // Make sure zero is always positive  if (pd_digits == 0) pd_negative = 0;  return precise && PR_checkLimits();}voidCORBA::Fixed::PR_setLimits(UShort idl_digits, UShort idl_scale){  OMNIORB_ASSERT(idl_digits <= 31);  OMNIORB_ASSERT(idl_scale  <= idl_digits);  pd_idl_digits = idl_digits;  pd_idl_scale  = idl_scale;  PR_checkLimits();}CORBA::BooleanCORBA::Fixed::PR_checkLimits(){  if (pd_idl_digits == 0) return 1;  if (pd_scale > pd_idl_scale) {    *this = truncate(pd_idl_scale);    return 0;  }  if (pd_digits - pd_scale > pd_idl_digits - pd_idl_scale)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -