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

📄 corbafixed.cc

📁 编译工具
💻 CC
📖 第 1 页 / 共 2 页
字号:
    OMNIORB_THROW(DATA_CONVERSION,		  DATA_CONVERSION_RangeError, CORBA::COMPLETED_NO);  return 1;}voidCORBA::Fixed::PR_changeScale(CORBA::UShort new_scale){  if (new_scale > pd_digits)    pd_digits = new_scale;  pd_scale = new_scale;}//// Arithmetic//static intabsCmp(const CORBA::Fixed& a, const CORBA::Fixed& b){  int c;  c = (a.fixed_digits()-a.fixed_scale()) - (b.fixed_digits()-b.fixed_scale());  if (c) return c;  int ai, bi;  ai = a.fixed_digits() - 1;  bi = b.fixed_digits() - 1;  while (ai >= 0 && bi >= 0) {    c = a.PR_val()[ai] - b.PR_val()[bi];    if (c) return c;    --ai; --bi;  }  if (ai >= 0) return  1;  if (bi >= 0) return -1;  return 0;}static CORBA::FixedrealAdd(const CORBA::Fixed& a, const CORBA::Fixed& b, CORBA::Boolean negative){  int scale, v, carry = 0, ai = 0, bi = 0, wi = 0;  CORBA::Octet work[OMNI_FIXED_DIGITS * 2];  if (a.fixed_scale() > b.fixed_scale()) {    scale = a.fixed_scale();    while (ai < a.fixed_scale() - b.fixed_scale())      work[wi++] = a.PR_val()[ai++];  }  else if (b.fixed_scale() > a.fixed_scale()) {    scale = b.fixed_scale();    while (bi < b.fixed_scale() - a.fixed_scale())      work[wi++] = b.PR_val()[bi++];  }  else    scale = a.fixed_scale();  while (ai < a.fixed_digits() && bi < b.fixed_digits()) {    v = a.PR_val()[ai++] + b.PR_val()[bi++] + carry;    if (v > 9) {      carry = 1; v -= 10;    }    else carry = 0;    work[wi++] = v;  }  while (ai < a.fixed_digits()) {    v = a.PR_val()[ai++] + carry;    if (v > 9) {      carry = 1; v -= 10;    }    else carry = 0;    work[wi++] = v;  }  while (bi < b.fixed_digits()) {    v = b.PR_val()[bi++] + carry;    if (v > 9) {      carry = 1; v -= 10;    }    else carry = 0;    work[wi++] = v;  }  if (carry) {    work[wi++] = carry;  }  CORBA::Octet* wp = work;  int digits = wi;  // Truncate or complain if too many digits  if (digits > OMNI_FIXED_DIGITS) {    if (digits - scale <= OMNI_FIXED_DIGITS) {      int chop  = digits - OMNI_FIXED_DIGITS;      wp       += chop;      scale    -= chop;      digits    = OMNI_FIXED_DIGITS;    }    else {      OMNIORB_THROW(DATA_CONVERSION,		    DATA_CONVERSION_RangeError, CORBA::COMPLETED_NO);    }  }  // Strip trailing zeros  while (scale > 0 && *wp == 0) {    ++wp; --scale; --digits;  }  return CORBA::Fixed(wp, digits, scale, negative);}static CORBA::FixedrealSub(const CORBA::Fixed& a, const CORBA::Fixed& b, CORBA::Boolean negative){  int scale, v, carry = 0, ai = 0, bi = 0, wi = 0;  CORBA::Octet work[OMNI_FIXED_DIGITS * 2];  if (a.fixed_scale() > b.fixed_scale()) {    scale = a.fixed_scale();    while (ai < a.fixed_scale() - b.fixed_scale())      work[wi++] = a.PR_val()[ai++];  }  else if (b.fixed_scale() > a.fixed_scale()) {    scale = b.fixed_scale();    while (bi < b.fixed_scale() - a.fixed_scale()) {      work[wi++] = 10 - b.PR_val()[bi++] + carry;      carry = -1;    }  }  else    scale = a.fixed_scale();  while (ai < a.fixed_digits() && bi < b.fixed_digits()) {    v = a.PR_val()[ai++] - b.PR_val()[bi++] + carry;    if (v < 0) {      carry = -1; v += 10;    }    else carry = 0;    work[wi++] = v;  }  while (ai < a.fixed_digits()) {    v = a.PR_val()[ai++] + carry;    if (v < 0) {      carry = -1; v += 10;    }    else carry = 0;    work[wi++] = v;  }  OMNIORB_ASSERT(bi == b.fixed_digits());  OMNIORB_ASSERT(carry == 0);  int digits = wi;  CORBA::Octet* wp = work;  // Strip leading zeros  while (work[digits-1] == 0 && digits > scale)    --digits;  // Truncate or complain if too many digits  if (digits > OMNI_FIXED_DIGITS) {    OMNIORB_ASSERT(digits - scale <= OMNI_FIXED_DIGITS);    int chop  = digits - OMNI_FIXED_DIGITS;    wp       += chop;    scale    -= chop;    digits    = OMNI_FIXED_DIGITS;  }  // Strip trailing zeros  while (scale > 0 && *wp == 0) {    ++wp; --scale; --digits;  }  return CORBA::Fixed(wp, digits, scale, negative);}static CORBA::FixedrealMul(const CORBA::Fixed& a, const CORBA::Fixed& b, CORBA::Boolean negative){  int ai, bi, wi, digits, scale, v, ad, bd, carry = 0;  CORBA::Octet work[OMNI_FIXED_DIGITS * 2];  memset(work, 0, OMNI_FIXED_DIGITS * 2);  scale = a.fixed_scale() + b.fixed_scale();  for (ai=0, wi=0; ai < a.fixed_digits(); ++ai) {    ad = a.PR_val()[ai];    if (ad == 0) continue;    for (bi=0; bi < b.fixed_digits(); ++bi) {      bd = b.PR_val()[bi];      if (bd == 0 && carry == 0) continue;      wi       = ai + bi;      v        = work[wi] + ad * bd + carry;      carry    = v / 10;      work[wi] = v % 10;    }    while (carry) {      ++wi;      v        = work[wi] + carry;      carry    = v / 10;      work[wi] = v % 10;    }  }  digits = wi+1;  if (scale > digits) digits = scale;  // Truncate or complain if too many digits  CORBA::Octet* wp = work;  if (digits > OMNI_FIXED_DIGITS) {    if (digits - scale <= OMNI_FIXED_DIGITS) {      int chop  = digits - OMNI_FIXED_DIGITS;      wp       += chop;      scale    -= chop;      digits    = OMNI_FIXED_DIGITS;    }    else {      OMNIORB_THROW(DATA_CONVERSION,		    DATA_CONVERSION_RangeError, CORBA::COMPLETED_NO);    }  }  // Strip trailing zeros  while (scale > 0 && *wp == 0) {    ++wp; --scale; --digits;  }  return CORBA::Fixed(wp, digits, scale, negative);}static intdivCmp(const CORBA::Octet* av, int ad, const CORBA::Octet* bv, int bd, int pos){  int c, ai, bi;  for (ai = ad-1; ai > pos; --ai) {    if (av[ai])      return 1;  }  ai = pos;  bi = bd - 1;  OMNIORB_ASSERT(ai >= bi);  while (bi >= 0) {    c = av[ai] - bv[bi];    if (c) return c;    --ai; --bi;  }  return 0;}static intdivDigit(CORBA::Octet* av, int ad, const CORBA::Octet* bv, int bd, int pos){  int ai, bi, carry, v, count = 0;  while (divCmp(av, ad, bv, bd, pos) >= 0) {    ++count;    carry = 0;    ai = pos - bd + 1;    bi = 0;    while (bi < bd) {      v = av[ai] - bv[bi] + carry;      if (v < 0) {	carry = -1;	v += 10;      }      else	carry = 0;      av[ai] = v;      ++ai;      ++bi;    }    while (ai < ad) {      v = av[ai] + carry;      if (v < 0) {	carry = -1;	v += 10;      }      else	carry = 0;      av[ai] = v;      ++ai;    }  }  OMNIORB_ASSERT(count < 10);  return count;}static CORBA::FixedrealDiv(const CORBA::Fixed& a, const CORBA::Fixed& b, CORBA::Boolean negative){  int i, ai, bi, wi, ri, digits, scale, unscale, v, ad, bd, carry = 0;  // This division algorithm basically does classic long division. The  // numerator, a, is loaded into the top digits of "running". The  // divisor, b, is then repeatedly subtracted from the top digits of  // "running" until it can no longer be subtracted without becoming  // negative. The count of subtractions forms the top digit of the  // result. Then the next digit is found by shifting the divisor down  // one digit, and repeating, and so on.  //  // The ugliness all comes because we need to figure out where to put  // the decimal point. It would be easy if it wasn't for the fact  // that values with scale > digits are not permitted. This means  // that if the result is going to be of that form, some initial zero  // digits have to be included.  CORBA::Octet work   [OMNI_FIXED_DIGITS * 2];  CORBA::Octet running[OMNI_FIXED_DIGITS * 2];  memset(work,    0, OMNI_FIXED_DIGITS * 2);  memset(running, 0, OMNI_FIXED_DIGITS * 2);  // Skip all leading zeros in a  ad = a.fixed_digits();  while (a.PR_val()[ad - 1] == 0) --ad;  // Set most siginificant digits of running to a's digits  ri = OMNI_FIXED_DIGITS * 2 - 1;  ai = ad - 1;  while (ai >= 0) {    running[ri] = a.PR_val()[ai];    --ri;    --ai;  }  // Skip all leading zeros in b  bd = b.fixed_digits();  while (b.PR_val()[bd - 1] == 0) --bd;  // unscale = number of digits to left of decimal point in answer  unscale = (ad - a.fixed_scale()) - (bd - b.fixed_scale()) + 1;  digits  = 0;  // Set some initial zero digits to prevent scale > digits  if (unscale < 0)    digits  = -unscale;  ri = OMNI_FIXED_DIGITS * 2 - 1;  wi = ri - digits;  // Iterate to work out the result digits  while (digits < OMNI_FIXED_DIGITS) {    // Finish if running is zero    for (i=0; i < OMNI_FIXED_DIGITS*2 && running[i] == 0; ++i);    if (i == OMNI_FIXED_DIGITS * 2)      break;    work[wi] = divDigit(running, OMNI_FIXED_DIGITS * 2, b.PR_val(), bd, ri);    if (digits || work[wi])      ++digits;    --wi; --ri;  }  wi = OMNI_FIXED_DIGITS * 2 - 1;  // Skip an initial zero if we weren't expecting one  if (unscale >= 0) {    while (work[wi] == 0 && unscale > 0) {      --wi; --unscale;    }  }  else    unscale = 0;  // Complain if too many digits before decimal point  if (unscale > OMNI_FIXED_DIGITS) {    OMNIORB_THROW(DATA_CONVERSION,		  DATA_CONVERSION_RangeError, CORBA::COMPLETED_NO);  }  // Deal with numbers with trailing zeros before the decimal point  if (digits < unscale)    digits = unscale;  CORBA::Octet* wp = &work[wi - digits + 1];  // Figure out scale  scale = digits - unscale;  if (digits < scale)    digits = scale;  // Strip trailing zeros  while (scale > 0 && *wp == 0) {    ++wp; --scale; --digits;  }  return CORBA::Fixed(wp, digits, scale, negative);}//// Arithmetic operators//CORBA::Fixedoperator+(const CORBA::Fixed& a, const CORBA::Fixed& b){  if (a.PR_negative() == b.PR_negative())    return realAdd(a, b, a.PR_negative());  int cmp = absCmp(a, b);  if (cmp == 0)     // a == b    return CORBA::Fixed();  else if (cmp > 0) // a > b    return realSub(a, b, a.PR_negative());  else    return realSub(b, a, b.PR_negative());}CORBA::Fixedoperator-(const CORBA::Fixed& a, const CORBA::Fixed& b){  if (a.PR_negative() != b.PR_negative())    return realAdd(a, b, a.PR_negative());  int cmp = absCmp(a, b);  if (cmp == 0)     // a == b    return CORBA::Fixed();  else if (cmp > 0) // a > b    return realSub(a, b, a.PR_negative());  else    return realSub(b, a, !a.PR_negative());}CORBA::Fixedoperator*(const CORBA::Fixed& a, const CORBA::Fixed& b){  if (a.fixed_digits() == 0 || b.fixed_digits() == 0)    return CORBA::Fixed();  if (a.PR_negative() == b.PR_negative())    return realMul(a, b, 0);  else    return realMul(a, b, 1);}CORBA::Fixedoperator/(const CORBA::Fixed& a, const CORBA::Fixed& b){  if (b.fixed_digits() == 0) {    int fixed_point_divide_by_zero = 0;    OMNIORB_USER_CHECK(fixed_point_divide_by_zero);  }  if (a.fixed_digits() == 0)    return CORBA::Fixed();  if (a.PR_negative() == b.PR_negative())    return realDiv(a, b, 0);  else    return realDiv(a, b, 1);}//// Comparison operators//intCORBA::Fixed::NP_cmp(const Fixed& a, const Fixed& b){  int c;  if (a.PR_negative()) {    if (b.PR_negative())      c = absCmp(b, a);    else      return -1;  }  else {    if (b.PR_negative())      return 1;    else      c = absCmp(a, b);  }  if (c < 0) return -1;  if (c > 0) return  1;  return 0;}CORBA::Booleanoperator>(const CORBA::Fixed& a, const CORBA::Fixed& b){  return CORBA::Fixed::NP_cmp(a, b) > 0;}CORBA::Booleanoperator<(const CORBA::Fixed& a, const CORBA::Fixed& b){  return CORBA::Fixed::NP_cmp(a, b) < 0;}CORBA::Booleanoperator>=(const CORBA::Fixed& a, const CORBA::Fixed& b){  return CORBA::Fixed::NP_cmp(a, b) >= 0;}CORBA::Booleanoperator<=(const CORBA::Fixed& a, const CORBA::Fixed& b){  return CORBA::Fixed::NP_cmp(a, b) <= 0;}CORBA::Booleanoperator==(const CORBA::Fixed& a, const CORBA::Fixed& b){  return CORBA::Fixed::NP_cmp(a, b) == 0;}CORBA::Booleanoperator!=(const CORBA::Fixed& a, const CORBA::Fixed& b){  return CORBA::Fixed::NP_cmp(a, b) != 0;}//// Marshalling operators//voidCORBA::Fixed::operator>>=(cdrStream& s) const{  OMNIORB_ASSERT(pd_idl_digits);  OMNIORB_ASSERT(pd_digits <= pd_idl_digits);  OMNIORB_ASSERT(pd_scale  <= pd_idl_scale);  CORBA::Octet buffer[16];  int digits_to_write = pd_idl_digits;  // Pad with extra zero digit if even no. of digits  if ((digits_to_write % 2) == 0) ++digits_to_write;  int unscale_to_write = digits_to_write - pd_idl_scale;  int unscale          = pd_digits       - pd_scale;  int bi, vi;  // Write any leading zeros  for (bi=0; bi < unscale_to_write - unscale; bi+=2) {    buffer[bi/2] = 0;  }  bi = unscale_to_write - unscale;  vi = pd_digits - 1;  // Write digits  for (; vi >= 0; --vi, ++bi) {    if (bi % 2)      buffer[bi/2] |= pd_val[vi];    else      buffer[bi/2]  = pd_val[vi] << 4;  }  // Write trailing zeros  if (bi % 2) ++bi;  for (; bi < digits_to_write; bi+=2) {    buffer[bi/2] = 0;  }  // Sign indicator  buffer[digits_to_write / 2] |= pd_negative ? 0xD : 0xC;  // Marshal the buffer  s.put_octet_array(buffer, digits_to_write / 2 + 1);}voidCORBA::Fixed::operator<<=(cdrStream& s){  OMNIORB_ASSERT(pd_idl_digits);  CORBA::Octet buffer[16];  int digits_to_read = pd_idl_digits;  if ((digits_to_read % 2) == 0) ++digits_to_read;  pd_digits = digits_to_read;  pd_scale  = pd_idl_scale;  // Read the data  s.get_octet_array(buffer, digits_to_read / 2 + 1);  CORBA::Octet d;  // Sign indicator  int vi;                   // Index into pd_val  int di;                   // Digit index  int bi = digits_to_read;  // Buffer index  d = buffer[bi/2] & 0xF;  if (d == 0xC)    pd_negative = 0;  else if (d == 0xD)    pd_negative = 1;  else    OMNIORB_THROW(MARSHAL, MARSHAL_InvalidFixedValue, 		  (CORBA::CompletionStatus)s.completion());  --bi;  di = vi = 0;  // Skip trailing zeros  while (di < pd_idl_scale) {    if (bi % 2)      d = buffer[bi/2] & 0xF;    else      d = buffer[bi/2] >> 4;    if (d != 0) break;    --bi;    ++di;    --pd_digits;    --pd_scale;  }  // Read and check the digits  for (vi = 0; di < digits_to_read; ++di, ++vi, --bi) {    if (bi % 2)      d = buffer[bi/2] & 0xF;    else      d = buffer[bi/2] >> 4;    if (d > 0x9)      OMNIORB_THROW(MARSHAL, MARSHAL_InvalidFixedValue, 		    (CORBA::CompletionStatus)s.completion());    pd_val[vi] = d;  }  OMNIORB_ASSERT(vi == pd_digits);  // Strip off leading zeros. Stop when we hit the decimal point.  --vi;  while (vi >= pd_scale && pd_val[vi] == 0) --vi;  pd_digits = vi + 1;  // Fill rest of val with zeros  memset(pd_val + pd_digits, 0, OMNI_FIXED_DIGITS - pd_digits);  // Sanity check  if (pd_digits - pd_scale == pd_idl_digits - pd_idl_scale + 1) {    // This happens if idl_digits is even, and the sending ORB put a    // non-zero half-octet as the most-siginificant digit.    OMNIORB_THROW(MARSHAL, MARSHAL_InvalidFixedValue, 		  (CORBA::CompletionStatus)s.completion());  }  OMNIORB_ASSERT(pd_digits <= pd_idl_digits);  OMNIORB_ASSERT(pd_scale  <= pd_idl_scale);  OMNIORB_ASSERT(pd_scale  <= pd_digits);}

⌨️ 快捷键说明

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