2010-07-30 6 views
4

Je passe mon code et chaque fois que D1 finit par être NaN. Le code semble bien pour moi, et je suis complètement déconcerté ...Pourquoi je reçois 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) 
    ); 
+0

Considérant que vous avez ExpirationDays et ExpriationDays dans votre code, je dirais que ce n'est pas votre code actuel. Pouvez-vous poster le code réel à la place? En outre, pouvez-vous publier la définition de la structure/classe de données afin que nous puissions voir les types de ces champs/propriétés? –

+0

Exact même erreur que vous avez fait ici: http://stackoverflow.com/questions/3344994/progress-bar-only-appears-after-work-is-complete/3345141#3345141 –

Répondre

10

Data.Volatility * Math.Pow(Data.ExpirationDays/365,.5) est 0 depuis 300/365 int équivaut à 0

Si l'on suppose ExpriationDays la propriété est de type int en effet, il est ll faire toute l'expression 0.

Par exemple:

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

    Assert.That(val, Is.EqualTo(0)); 
} 

Quelques commentaires à propos de la division b y 0:

Lors de la division deux 0 entiers une exception sera levée lors de l'exécution:

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

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

Lors de la division deux 0 doubles le résultat NaN et aucune exception ne sera levée:

[Test] 
public void TestDoubleDiv() 
{ 
    double zero = 0; 
    double val = 0/zero; 

    Assert.That(val, Is.NaN); 
} 
+0

Wow, je suis stupide. OK merci. Et je pensais que je faisais la bonne chose en utilisant int pour ExpirationDays plutôt que de doubler. Merci – sooprise

+3

Vous pouvez le garder à int si vous le souhaitez, mais notez que int/int est une division entière, mais int/double est une division en virgule flottante, donc vous pouvez simplement tapper sur .0 sur 365 pour le faire fonctionner comme vous le voulez, c'est à dire. 'Data.ExpirationDays/365.0' –

+0

Lasse, c'est une excellente suggestion et quelque chose dont je n'étais pas au courant. Je vais mettre en œuvre ce que vous suggérez. – sooprise

3

Vérifiez le type de Data.ExpirationDays, il se peut que Data.ExpirationDays/365 évalue à 0 si le type est intégral. Cela signifierait que le dénominateur serait zéro (la racine carrée de zéro est zéro et zéro multiplié par Data.Volatility est encore zéro) ce qui conduirait à un problème.

En fait, le numérateur se révèle être nul dans votre cas et depuis log n 1 est toujours égale à zéro et vous ajoutez que à zéro (une autre valeur qui est multipliée par Data.ExpirationDays/365).

Vous pouvez envisager d'utiliser des types à virgule flottante tout au long du processus.

+0

mais ne serait-ce pas jeter une exception, au lieu de retourner NaN? – AllenG

+0

Cela dépendrait - IEEE754 a signalisation (comme en exception) et non-signalisation (comme en retour un NaN) NaNs. Je ne sais pas du haut de ma tête ce que C# utilise ou si c'est configurable. – paxdiablo

+0

Vous n'effectuez pas 'n/0', vous effectuez' 0/0'. Votre logarithme aboutit à 0, et vous y ajoutez le même 'ExpirationDays/365'. –

1
  • Data.ExpirationDays/365 est égal à zéro.
  • 0^0,5 est égal à zéro aussi.
  • Data.Volatility * 0 = 0.
  • D1 = Quelque chose/0.

donc NaN est très attendue.

+0

Vous supposez que ExpirationDays est un int (ou un autre type entier). C'est une supposition sûre mais puisque cela produira le NaN, mais c'est * une * hypothèse néanmoins. –

+0

Vous avez raison. En regardant le code, j'ai supposé que 'ExpirationDays' est un nombre entier à cause de' Data.ExpriationDays = 300; '(et j'écris toujours' A double = =; A = 300.0' dans mon propre code). Mais bien sûr, puisque c'est une propriété de classe, cela peut être 'double ExpirationDays [...] = 300'. –

0

Est-ce parce que vous avez épelé Data.ExpirationDays comme Data.ExpriationDays de sorte que Data.ExpirationDays a la valeur par défaut 0? Cela donnerait 0/0 soit NaN (le numérateur est 0 b/c vous avez un strike = spot)

(Je n'ai jamais utilisé C# donc je ne sais pas si c'est seulement une erreur dans votre message ou dans votre code (que j'aurais attendu le compilateur à attraper))

+0

Cela ne fonctionnerait que s'il a deux champs/propriétés dans son type, à savoir. l'un avec l'orthographe correcte et l'autre sans. Je trouve cela peu probable (mais pas impossible) alors je doute que ce soit ça. –

Questions connexes