C# 为什么我会变傻?

C# 为什么我会变傻?,c#,C#,我在检查代码,每次D1都是NaN。代码在我看来很好,我完全被难住了 double D1; Data Data = new Data(); PriceSpot = 40; Data.PriceStrike = 40; Data.RateInterest = .03; Data.Volatility = .3; Data.ExpriationDays = 300; D1 = ( Math.Log(PriceSpot/Data.PriceStrike) +

我在检查代码,每次D1都是NaN。代码在我看来很好,我完全被难住了

double D1;
Data Data = new Data();

PriceSpot = 40;
Data.PriceStrike = 40;
Data.RateInterest = .03;
Data.Volatility = .3;
Data.ExpriationDays = 300;

D1 = 
    (
        Math.Log(PriceSpot/Data.PriceStrike) +
        (
            (Data.RateInterest + (Math.Pow(Data.Volatility,2)/2)) *
            (Data.ExpirationDays/365)
        )
    ) /
    (
        Data.Volatility *
        Math.Pow(Data.ExpirationDays/365,.5)
    );

Data.Volatility*Math.Pow(Data.ExpirationDays/365.5)
自300/365起为0,int等于0

假设
ExpriationDays
属性的类型确实是
int
,它将使整个表达式为0

例如:

[Test]
public void Test()
{
    var val = 300 / 365;

    Assert.That(val, Is.EqualTo(0));
}
关于除以0的一些注释:

除以两个0整数时,将在运行时引发异常:

[Test]
public void TestIntDiv()
{
    int zero = 0;
    int val;

    Assert.Throws<DivideByZeroException>(() => val = 0 / zero);
}

检查
数据的类型。ExpirationDays
,如果类型为整数,则可能是
数据。ExpirationDays/365
的计算结果为0。这意味着分母将为零(零的平方根为零,零乘以数据。波动率仍然为零),这将导致一个问题

事实上,在您的例子中,分子也变成了零,因为logn1始终为零,您要将其加在零上(另一个值乘以
Data.ExpirationDays/365

您可能需要考虑整个过程中使用浮点类型。

UL>
  • 数据。ExpirationDays/365
    等于零
  • 0^0.5也等于零
  • 数据。波动率*0=0
  • D1=某物/0

  • 所以NaN是意料之中的事。

    是因为您将Data.ExpirationDays拼写错误为Data.ExpirationDays,所以Data.ExpirationDays默认为0吗?这将得到0/0即NaN(分子为0 b/c,恰好有strike=spot)


    (我从未使用过C#所以我不确定这是否只是你的帖子或代码中的一个错误(我希望编译器能够捕捉到))

    考虑到你的代码中既有ExpirationDays也有ExpirationDays,我认为这不是你真正的代码。你能把实际的代码贴出来吗?另外,您是否可以发布数据结构/类的定义,以便我们可以看到这些字段/属性的类型?与您在这里犯的错误完全相同:但这不会引发异常,而不是返回NaN?这取决于IEEE754具有信令(如在异常中)和非信令(如在返回NaN中)NaN。我不知道C使用了什么,也不知道它是否可配置。你不是在执行
    n/0
    ,而是在执行
    0/0
    。你的对数结果是0,你把同样的
    ExpirationDays/365
    加进去。哇,我真傻。好的,谢谢。我认为我用int表示ExpirationDays而不是double是正确的。谢谢,如果你愿意的话,你可以把它保持在int,但是请注意int/int是一个整数除法,而int/double是一个浮点除法,所以你可以在365上加上.0,让它按照你想要的方式工作,也就是说。
    Data.ExpirationDays/365.0
    Lasse,这是一个很好的建议,但我并不知道。我将实现您的建议。您还可以将值强制转换为double。只有当他在其类型中同时具有两个字段/属性(即拼写正确的字段/属性和没有拼写的字段/属性)时,这才有效。我觉得这不太可能(但并非不可能),所以我怀疑这是真的。您假设ExpirationDays是int(或其他整数类型)。虽然这是一个安全的假设,因为这将产生NaN,但这仍然是一个假设。你是对的。查看代码,我假设
    ExpirationDays
    是一个整数,因为
    Data.ExpirationDays=300(我总是用自己的代码编写
    双A=…;A=300.0
    )。但当然,因为它是一个类属性,所以它可以是
    double ExpirationDays[…]=300
    [Test]
    public void TestDoubleDiv()
    {
        double zero = 0;
        double val = 0 / zero;
    
        Assert.That(val, Is.NaN);
    }