如何开发一种在C/C ++中接受无限范围值的数据类型? [英] How to develop a data type which accept unlimited range of values in C/C++?

查看:73
本文介绍了如何开发一种在C/C ++中接受无限范围值的数据类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在c ++或c语言中,有什么方法可以编写可以接受无限范围值的数据类型?
如果是
请告诉我详细信息吗?
例如UnlimitedType a;
a =(1024 * 1024 * 1024 * 1024 *(Factorial(100000));

Is there any way in c++ or c to write a data type which accepts unlimited range of value?
if yes
please tell me how in detail?
e.g a UnlimitedType a;
a=(1024*1024*1024*1024*(Factorial(100000));

推荐答案


答案是肯定的,可以构建.一种方法是将整数签名存储在位的链表中,从而随着数量的增加而动态添加新的位.这种类型的运算是使用位数学执行的,因此,您将必须实现原始加法,减法,乘法,除法,以及在汇编级别上如何完成此操作(请参阅实现前瞻性进位加法器-
Hi,
The answer is yes, it can be built. One of the ways is storing the integer signature in a linked-list of bits, thus adding dynamically new bit as the number increases. Operation on this types are performed using bit math, thus you''ll have to implement primitive addition, subtraction, multiplication, division, pretty much how it is done on assembly level (see implementing look ahead carry adder - http://cppgm.blogspot.com/2008/01/c-program-look-ahead-carry-adder.html[^]. Of course simple math on big numbers will increase processing time greatly, so I would really think of reviewing this kind of specifications.
Regards


基本上,您需要做的是定义一个包含用于数字的某种表示形式的类,然后定义一组数学运算符,让您使用该操作数进行实际计算类,或此类的标准类型和操作数之间的混合计算.

对于您的表示,上述建议使用某种位数组似乎无效IMHO.使用std::vector<unsigned int>可能会获得更快的代码.

这是一个快速的技巧,可以显示我的想法-缺少很多内容,但希望您能明白:
Basically, what you need to do is define a class that contains some kind of representation for your number, and then a set of math operators that let you do actual calculations with operands of this class, or mixed calculations between standard types and operands of this class.

For your representation, the above suggestion to use some kind of bit-array seems inefficient IMHO. You''ll probably get faster code using std::vector<unsigned int>.

Here''s a quick hack showing what I have in mind - there''s a lot missing, but I hope you get the idea:
class CBigInt {
private:
   int sign;
   std::vector<unsigned int> mantisse;
   void expand(std::size_t size) { // expand mantisse to new size
      if (size > mantisse.size()) {
         std::size_t old_size = mantisse.size();
         mantisse.resize(size);
         for (std::size_t i = old_size; i < size; ++i)
            mantisse[i] = 0;
      }
   }
public:
   CBigInt(int i) : mantisse(1) { // initialize mantisse at length 1
      mantisse[0] = iabs(i);
      sign = (i>0 ? 1 : (i<0 ? -1 : 0)); // added redundand braces for sake of readability
   }
   CBigInt(const CBigInt& other) : mantisse(other.mantisse), sign(other.sign) {
      // copy constructor
   }
   CBigInt& operator+=(const CBigInt& other) {
      // initialize temporary to hold result
      CBigInt newValue(0);

      // estimate required size for result
      std::size_t size(mantisse.size());
      if (other.mantisse.size() > size) {
         size = other.mantisse.size();
      }
      if (other.sign == sign)
      newValue.expand(size);

      // calculate new value, using carryover temporary
      unsigned int carry(0);
      if (sign == other.sign) {
         newValue.sign = sign;
         ++size; // carryover may require to increase the size by 1 digit
         for (std::size_t i = 0; i < size-1; ++i) {
            // add carryover
            if (UINT_MAX-mantisse[i] < carry) { // does carry+mantisse[i] exceed UINT_MAX?
               // new digit = carry + mantisse - (UINT_MAX + 1)
               newValue.mantisse[i] = (carry - (UINT_MAX - mantisse)) - 1; // stay within the bounds of UINT
               carry = 1;
            }
            else {
               newValue.mantisse[i] = mantisse[i] + carry;
               carry = 0;
            }
            // add digit from second number
            if (UINT_MAX-newValue.mantisse < other.mantisse[i]) { // does addition exceed UINT_MAX?
               newValue.mantisse[i] = (other.mantisse[i] - (UINT_MAX - newValue.mantisse[i])) - 1;
               ++carry;
            }
            else {
               newValue.mantisse[i] += other.mantisse[i];
            }
         }
         if (carry > 0) {
            newValue.mantisse[size] = carry;
         }
         else {
            --size; // highest order digit not required
         }
      }
      else {
         // different signs
         // TODO: subtract values
         // ...
      }

      // copy results
      sign = newValue.sign;
      mantisse.resize(size);
      for (std::size_t i = 0; i < size; ++i) {
         mantisse[i] = newValue.mantisse[i];
      }
   }
};
CBigInt operator+(const CBigInt& op1, const CBigInt& op2) {
   return CBigInt(op1) += op2;
}


如您所见,即使是简单的运算符也难以实现,特别是当您处理的位数不止一个位时.而且我甚至不确定我是否涵盖了所有情况-我没有尝试编译它,更不用说测试此代码了.


As you can see, even a simple operator can be tricky to implement, especially when you deal with digits containing more than just a single bit. And I''m not even sure I covered all cases - I didn''t try to compile this, much less test this code.


已经尝试了这些答案
如何开发自己的存储方法大价值 [ ^ ]

在c + +中找到10000阶乘的程序 [ ^ ]
Have tried these answers
How to develop some own method to store large value[^]
and
A program to find factorial of 10000 in c++[^]


这篇关于如何开发一种在C/C ++中接受无限范围值的数据类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆