【问题标题】:Handling large digit number variables in object-oriented C++在面向对象的 C++ 中处理大数字变量
【发布时间】:2016-02-29 06:50:09
【问题描述】:

我正在使用双精度编译的求解器(编程基于面向对象的 C++)进行数值分析,我的单位是 64 位。我的问题是,当求解器计算一个大数时——比如说 -1.45 的 21 次方,举一个实际的例子——并通过将此值传递给现有变量将其堆叠在分配的内存中,它被转换为 0。所以当然,当我后来在一个部门中使用这个变量时,我得到了一个分段错误。我不明白这个过程是如何工作的,而且因为我使用的是 DP,所以我不知道如何解决这个问题。有人可以帮我解决这个问题吗?

如果有帮助:我刚刚运行了一个测试,我声明 a=-1.45e+21,并“打印”求解器正确返回的值。但是当我不使用“e”指数并输入完整值(有 19 个零)时,我得到 0 作为回报。所以我想问题/限制来自位数,有什么想法吗?谢谢 !

编辑:我发布了我为计算造成问题的变量之一所经历的步骤的摘要。其他类似定义。 首先我初始化字段指针列表:

PtrList<volScalarField> fInvFluids(fluidRegions.size());

volScalarField 类只是一个双精度数组。然后我填充字段指针列表:

fInvFluids.set
    (
        i,
        new volScalarField
        (
            IOobject
            (
                "fInv",
                runTime.timeName(),
                fluidRegions[i],
                IOobject::NO_READ,
                IOobject::AUTO_WRITE
            ),
            fluidRegions[i],
            dimensionedScalar
            (
                "fInv",
                dimensionSet(3,1,-9,-1,0,0,0),
                scalar(0)
            )
        )
    );

在此之后,我设置了字段区域:

volScalarField& fInv = fInvFluids[i];

最后我计算了值:

   //   Info<< " ** Calculating fInv            **\n";
    fInv = gT*pow(pow(T/Tlambda, 5.7)*(1 - pow(T/Tlambda, 5.7)), 3);

其中 T 是字段变量,Tlambda 是在运行时定义的标量值。

【问题讨论】:

  • 请将代码贴在您正在使用的电源并将其保存在堆栈中。
  • 考虑将GMP library 用于大数字。
  • 我编辑我的评论。我检查了用该软件编译的库并安装了 GMP-5.1.2,所以我猜这个问题出现在其他地方。
  • 您发布的代码均不相关。如果您对pov(x,y) 有疑问,请发布xy 的实际值。
  • “完整值”是(溢出的)int-1.45e+21double。你需要一个不会溢出的类型;试试-1450000000000000000000LL

标签: c++ digits largenumber


【解决方案1】:

double 变量可能也不能容纳 19 个零。一个(十进制)数字占用超过 3 位,因此 19 个零将占用至少 57 位。 double 的尾数通常只有 53 位。

但是,这听起来不像您遇到的问题。在 C++ 代码 中,表达式也有类型。 11.0 不同。第一个是int,第二个是double。虽然您可以将int 转换为double,但它们并不相同。 int 很可能可以容纳高达 20 亿的值,但正式它可能有一个低至 32767 的限制。解决您的问题可能就像添加一个 第二十 个零一样简单:@987654330 @使它成为double

【讨论】:

  • 我终于发现错误来自使用 pow() 将负基数提高到幂指数。如果底数是有限负数并且指数是有限数但不是整数值,则会导致域错误。我整理了一些使用符号功能的工作。但是,您的解决方案很有帮助,因为它确实解决了我在输入大整数值时在代码中遇到的另一个错误。所以谢谢你!
  • @SimoMJ 这是意料之中的。 pow(-1, 0,.5) 应该是 0+1ipow 不会返回复数。
  • 是的,也是如此。我的一个边界条件设置不正确,迫使值在某些时候发散,这使得功率基数变为负值,我现在解决了这个问题,但非常感谢大家的建议。
猜你喜欢
  • 1970-01-01
  • 2010-09-12
  • 2023-03-29
  • 1970-01-01
  • 1970-01-01
  • 2021-11-15
  • 2017-10-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多