我有2个双打,我想添加它们,划分它们等但是一切都返回inf
double num1 = 1.999999999999999999e+320
double num_2 =1.999999999999999e+320
它们是否超出double
的范围?我该如何扩展或解决问题?
答案 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
您需要以下内容:
随后是骨架,实际实现非常简单:
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
}