2022-10-25 c++-将整数按指定进位做转换

该博客主要围绕C++开发语言,介绍将整数按指定进位进行转换。包含代码实现部分,有原始的拙劣实现和优化后的实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

摘要:

将整数按指定进位做转换

代码实现:

原始的拙劣的实现:


#include <string.h>
#include <stdint.h>
#include <stdio.h>

#include <string>
#include <cstring>
#include <iostream>
#include <memory>

typedef unsigned long long int ulonglong; /* ulong or unsigned long long */
typedef long long int	longlong;
typedef longlong int64;
typedef ulonglong uint64;

extern char *llstr(longlong value,char *buff);
extern char *ullstr(longlong value,char *buff);

extern char *int2str(long val, char *dst, int radix, int upcase);
extern char *int10_to_str(long val,char *dst,int radix);
extern char *str2int(const char *src,int radix,long lower,long upper,
			 long *val);
longlong my_strtoll10(const char *nptr, char **endptr, int *error);
#if SIZEOF_LONG == SIZEOF_LONG_LONG
#define ll2str(A,B,C,D) int2str((A),(B),(C),(D))
#define longlong10_to_str(A,B,C) int10_to_str((A),(B),(C))
#undef strtoll
#define strtoll(A,B,C) strtol((A),(B),(C))
#define strtoull(A,B,C) strtoul((A),(B),(C))
#else
extern char *ll2str(longlong val,char *dst,int radix, int upcase);
extern char *longlong10_to_str(longlong val,char *dst,int radix);
#endif
#define longlong2str(A,B,C) ll2str((A),(B),(C),1)


#define NullS		(char *) 0
typedef unsigned char	uchar;	/* Short for unsigned char */


char _dig_vec_upper[] =
  "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char _dig_vec_lower[] =
  "0123456789abcdefghijklmnopqrstuvwxyz";


char *
int2str(long int val, char *dst, int radix, 
        int upcase)
{
  char buffer[65];
  char *p;
  long int new_val;
  char *dig_vec= upcase ? _dig_vec_upper : _dig_vec_lower;
  ulong uval= (ulong) val;

  if (radix < 0)
  {
    if (radix < -36 || radix > -2)
      return NullS;
    if (val < 0)
    {
      *dst++ = '-';
      /* Avoid integer overflow in (-val) for LLONG_MIN (BUG#31799). */
      uval = (ulong)0 - uval;
    }
    radix = -radix;
  }
  else if (radix > 36 || radix < 2)
    return NullS;

  /*
    The slightly contorted code which follows is due to the fact that
    few machines directly support unsigned long / and %.  Certainly
    the VAX C compiler generates a subroutine call.  In the interests
    of efficiency (hollow laugh) I let this happen for the first digit
    only; after that "val" will be in range so that signed integer
    division will do.  Sorry 'bout that.  CHECK THE CODE PRODUCED BY
    YOUR C COMPILER.  The first % and / should be unsigned, the second
    % and / signed, but C compilers tend to be extraordinarily
    sensitive to minor details of style.  This works on a VAX, that's
    all I claim for it.
  */
  p = &buffer[sizeof(buffer)-1];
  *p = '\0';
  new_val= uval / (ulong) radix;
  *--p = dig_vec[(uchar) (uval- (ulong) new_val*(ulong) radix)];
  val = new_val;
  while (val != 0)
  {
    ldiv_t res;
    res=ldiv(val,radix);
    *--p = dig_vec[res.rem];
    val= res.quot;
  }
  while ((*dst++ = *p++) != 0) ;
  return dst-1;
}


static char *Text(int64_t value_, char buf[], int scale) {
  bool sign = true;
  if (value_ < 0) {
    sign = false;
    value_ *= -1;
  }
  longlong2str(value_, buf, 10);
  int l = (int)std::strlen(buf);
  std::memset(buf + l + 1, ' ', 21 - l);
  int pos = 21;
  int i = 0;
  for (i = l; i >= 0; i--) {
    if (scale != 0 && pos + scale == 20) {
      buf[pos--] = '.';
      i++;
    } else {
      buf[pos--] = buf[i];
      buf[i] = ' ';
    }
  }

  if (scale >= l) {
    buf[20 - scale] = '.';
    buf[20 - scale - 1] = '0';
    i = 20 - scale + 1;
    while (buf[i] == ' ') buf[i++] = '0';
  }
  pos = 0;
  while (buf[pos] == ' ') pos++;
  if (!sign) buf[--pos] = '-';
  return buf + pos;
}


int main()
{
    int64_t value = -12345;
    char buf[1024] = {0};
    int scale = 3;

    Text(value, buf, scale);

    printf("buf: %s\n", buf);

    return 0;
}

优化后的实现:

#include <string.h>
#include <stdint.h>
#include <stdio.h>

#include <string>
#include <cstring>
#include <iostream>
#include <memory>


typedef unsigned long long int ulonglong; /* ulong or unsigned long long */
typedef long long int	longlong;
typedef longlong int64;
typedef ulonglong uint64;

extern char *llstr(longlong value,char *buff);
extern char *ullstr(longlong value,char *buff);


#define NullS		(char *) 0
typedef unsigned char	uchar;	/* Short for unsigned char */


static char *Text(int64_t value_, char buf[], int scale) {
    bool sign = value_ >= 0;

    int index = 0;
    int left_dec = 0;
    if (!sign) {
        buf[index++] = '-';
        ++left_dec;
        value_ = - value_;
    }

    int64_t value_div = value_;
    int loc = 0;
    while (value_div) {
        ++loc;
        value_div /= 10;
    }

    if (scale > loc) {
        return NULL;
    }

    left_dec += loc - scale;

    value_div = value_;
    while (value_div) {
        int pos = index + loc - 1;
        if (pos >= left_dec) {
            ++pos;
        }

        buf[pos] = (value_div % 10) + '0';
        if (pos == (left_dec+1)) {
            --pos;
            buf[pos] = '.';
        }

        value_div /= 10;
        --loc;
    }

    return buf;
}


int main()
{
    int64_t value = -12345;
    char buf[1024] = {0};
    int scale = 3;

    Text(value, buf, scale);

    printf("buf: %s\n", buf);

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

悟世者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值