c# - 带浮点算术检查的下流

标签 c# underflow

我正在编写一个包含长数学公式的多个实例的库,这些公式在使用 double 时有时会下溢。一个例子可能是:

(Exp(-a*a) - Exp(-b*b))*Exp(c)*Exp(d) 

而a,b,c,d也涉及一些类似类型的计算。 我可以处理 double 错误(并返回适当的错误消息或一些分析界限),但如果我没有检测到下溢(例如,在指数的差异上),它会导致我无法承受的行为。 (当这种差异为零而其他指数非常大时,绝对误差和相对误差都可能很大)。

是否有类似于 checked 关键字的东西适用于 double ? 有什么方法可以辅助实现检查吗?

任何确保其正确的解决方案,即使是提出比必要更多的标志的解决方案对我来说都是好的。


This question被建议为重复但“在每次乘法之前手动检查”对我来说不是一个特别有用的解决方案。

最佳答案

Is there something similar to checked keyword that works for doubles?

没有。

Is there some way I can implement checks in an assisted way?

一个糟糕的解决方案:根据您使用的硬件,浮点运算芯片可能会设置一个标志,指示操作是否下溢。我不建议调用非托管代码来读取浮点芯片上的标志。 (我在原始的 Microsoft 版本的 Javascript 中编写了代码来执行此操作,并且很难正确地实现该逻辑。)

更好的解决方案:您可以考虑编写一个符号逻辑库。例如,考虑如果您创建自己的数字类型会发生什么:

struct ExpNumber 
{
  public double Exponent { get; }
  public ExpNumber(double e) => Exponent = e;
  public static ExpNumber operator *(ExpNumber x1, ExpNumber x2) => 
    new ExpNumber(x1.Exponent + x2.Exponent);

等等。您可以使用已知的幂恒等式定义自己的加法、减法、幂、对数等。然后,当需要将事情变回 double 值时,您可以使用任何稳定的算法来实现它,避免您喜欢的下溢。

问题在于, double 有意以降低表现力和准确性来换取速度的大幅提高。如果您需要准确表示小于 10e-200 的数字, double 不适合您;它们旨在解决物理计算中的问题,并且没有这么小的物理量。

关于c# - 带浮点算术检查的下流,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56744649/

相关文章:

c# - 当我运行 WPF MVVM 应用程序时,显示主窗口的两个实例

java - 我如何评估这个等式?

c++ - double 可以溢出到负值吗?

c# - 默认数据上下文

c# - 为 SqlCipher 数据库存储加密 key 的正确方法

c# - 将对象转换为它的类

java - Java 如何处理整数下溢和上溢?

objective-c - 如何避免GC环境中自定义NSURLProtocol中_NSCFURLProtocolBridge中的引用计数下溢

c# - 为什么我们需要 "out"参数?