如何在C ++中计算非常大的数字

时间:2011-11-03 04:59:25

标签: c++

我有2个双打,我想添加它们,划分它们等但是一切都返回inf

double num1 = 1.999999999999999999e+320 

double num_2 =1.999999999999999e+320 

它们是否超出double的范围?我该如何扩展或解决问题?

5 个答案:

答案 0 :(得分:2)

双打(双精度IEEE754)只能让你达到约10+/-308(来自内存)。

如果您的实现支持更广泛的long double类型,则可以使用它。现在请记住,允许C99实现将long double视为与double相同,因此这可能不会必然帮助您。来自C99:

  

C浮动类型符合IEC 60559格式,如下所示:
   - 浮动类型符合IEC 60559单一格式    - 双重型符合IEC 60559双重格式    - long double类型符合IEC 60559扩展格式,否则a   非IEC 60559扩展格式,否则为IEC 60559双格式。

     

用于long double类型的任何非IEC 60559扩展格式应具有更多   精度高于IEC 60559的两倍且至少IEC 60559的范围是双倍的。

     

'Extended'是IEC 60559的双扩展数据格式。扩展指的是常见的80位和四倍128位IEC 60559格式。

     

需要非IEC 60559 long double类型来提供无穷大和NaN,因为它的值包括所有双精度值。

但是,如果它使用扩展格式(例如,80或128位格式),那么这将使您的64位双倍范围大幅增加。 IEEE754二进制128格式将为您提供大约34个十进制数字的精度(从您从双重获得的15个)和一个约10+/-4932的范围(从10+/-308开始)。

如果没有,或者仍然没有足够的范围或精度,你可以查看其中一个任意精度库,如MPIR,尽管它的名字,它完全能够处理真正的浮动点数(不仅仅是整数和有理数)。

答案 1 :(得分:1)

使用任意精度数学库。请查看Arbitrary Precision Arithmetic以获取指向其中一些链接的链接。

答案 2 :(得分:1)

long double数据类型确实具有更大的范围。例如,在我的机器(64位Linux)上,我得到以下信息:

Maximum value for double: 1.79769e+308
Maximum value for long double: 1.18973e+4932

注意较大的指数。

使用C ++ STL中的限制库找到此信息。可以找到一个示例here

答案 3 :(得分:0)

你尝试过双倍还是漂浮?为什么你需要这么长的数字

答案 4 :(得分:0)

如果你只是做加法,乘法,推导等简单操作,就不需要使用第三方库。您可以创建自己的类来处理这些数字和所需的操作。

来自维基百科关于scientific notation的文章:

科学记数法是一种编写数字的方法,可以容纳太大或太小的值,以便用标准十进制表示法方便地编写。科学记数法具有许多有用的特性,通常用于计算器,科学家,数学家,医生和工程师。

  

在科学记数法中,所有数字都是这样写的:

a \times 10^b
     

(“十倍于b的幂”),其中指数b为a   整数,系数a是任意实数

因此,对于您的类,您需要一个对应于系数a的double和一个表示指数b的int或long int(对于更大的数字)。

科学记数法中的算术运算

设两个数字N1 = a1E + b1,N2 = a2E + b2

然后我们可以处理以下四种经典算术运算:

乘法

N1 * N2 = a1 * a2E +(b1 + b2)

N1 / N2 = a1 / a2E +(b1-b2)

当然你应该按零处理。

加成

你需要一些基本的代数来概括它

if(bi> = b2)

N1 + N2 = a1E + b1 + a2E + b2 = a1E + b1 + a2E +(b1 + b2-b1)=(a1 + a2E +(b2-b1))E + b1

否则

N1 + N2 = a1E + b1 + a2E + b2 = a1E +(b2 + b1-b2)+ a2E + b2 =(a1E +(b1-b2)+ a2E)E + b2

修改

你应该将上面等式的左边部分变换为double,然后再将其转换为科学记数法并应用乘法规则,例如

a1 + a2E +(b2-b1)= a3E + b3,所以

N1 + N2 = a3E + b3E + b1 = a3E +(B3 + b1)

减法

与添加类似,我们有b1> = b2

N1-N2 =(a1-a2E +(b2-b1))E + b1

实施骨架

您需要以下内容:

  • 一个构造函数,其参数为double,并计算指数和系数。
  • 具有指数b和系数a
  • 作为参数的构造方法
  • 您要支持的算术运算的运算符
  • 帮助打印号码或将其转换为科学记数法的功能

随后是骨架,实际实现非常简单:

class MyLargeNumber{
public:
   MyLargeNumber(double d); // from d find a,b and initialize your object
   MyLargeNumber(double a, long int B); // initialize directly

   double a() const; // get the coefficient
   long int b() const; // get the exponent

   // Operators overloading
   MyLargeNumber operator+(const MyLargeNumber &m) const;
   MyLargeNumber operator-(const MyLargeNumber &m) const;
   MyLargeNumber operator*(const MyLargeNumber &m) const;
   MyLargeNumber operator/(const MyLargeNumber &m) const;

   // Helper function
   std::string toString() const;
private:
   double a; // the coefficient
   long int b; // the exponent
}