Why Am I Getting NaN? - c#

I'm going through my code and each time D1 ends up being NaN. The code looks fine to me, and I'm completely stumped...
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) is 0 since 300/365 as int equals to 0
Assuming ExpriationDays property is of type int indeed, it'll make the whole expression be 0.
For example:
[Test]
public void Test()
{
var val = 300 / 365;
Assert.That(val, Is.EqualTo(0));
}
Some comment about dividing by 0:
When dividing two 0 integers an exception will be thrown at runtime:
[Test]
public void TestIntDiv()
{
int zero = 0;
int val;
Assert.Throws<DivideByZeroException>(() => val = 0 / zero);
}
When dividing two 0 doubles the result will be NaN and no exception will be thrown:
[Test]
public void TestDoubleDiv()
{
double zero = 0;
double val = 0 / zero;
Assert.That(val, Is.NaN);
}

Check the type of Data.ExpirationDays, it may be that Data.ExpirationDays/365 is evaluating as 0 if the type is integral. That would mean the denominator would be zero (the square root of zero is zero and zero multiplied by Data.Volatility is still zero) which would lead to a problem.
In fact the numerator turns out to be zero in your case as well since logn1 is always zero and you're adding that to zero (another value which is multiplied by Data.ExpirationDays/365).
You may want to consider using floating point types throughout the process.

Data.ExpirationDays/365 is equal to zero.
0 ^ 0.5 is equal to zero too.
Data.Volatility * 0 = 0.
D1 = Something / 0.
So NaN is quite expected.

Is it because you've mis-spelled Data.ExpirationDays as Data.ExpriationDays so Data.ExpirationDays is defaulted to 0? This would give 0/0 ie NaN (numerator is 0 b/c you happen to have strike=spot)
( I've never used C# so am not sure whether this is only an error in your posting or in your code (which I would have expected the compiler to catch) )

Related

Check if a string is percentage value

I'm trying to write this in C#. The requirement is very straightforward - check if a string input is a value within the range from 0 to 100.
I want to make sure the string is either an integer value in the range of 0 to 100 or
a double that's within the same range as well.
So for example, these are the accepted values:
0
50
100
0.1
50.7
100.0
I checked the double.parse method here but not sure if it's the one I'm looking for: https://learn.microsoft.com/en-us/dotnet/api/system.double.tryparse?view=net-7.0#system-double-tryparse(system-string-system-iformatprovider-system-double#)
The reason is that it can also parse string like this one: 0.64e2 (which is 64)
Is this something that can be achieved with built-in library already?
Wrote you a little snippet:
// C# function to check if string is a percentage between 0 and 100
public static bool IsPercentage(string s)
{
// regex check if s is a string with only numbers or decimal point
if (Regex.IsMatch(s, #"^\d+\.?\d*$"))
{
double d = Convert.ToDouble(s);
return d >= 0 && d <= 100;
}
return false;
}
Also returns false if the string contains % or has exponential (e).
if my understanding of the Q was correct and exponential representations like mentioned "0.64e2" is unwanted:
static bool IsPercentage(string s)
{
if (Single.TryParse(s, NumberStyles.AllowLeadingSign |
NumberStyles.AllowDecimalPoint, NumberFormatInfo.InvariantInfo, out Single n))
return n >= 0 && n <= 100;
return false;
}

Why do I need +-1 in a Binary Search?

So I'm curious.. Why is it that I need to do +1 and -1 when truncating a side of the array.
I get that an array is index based and starts at 0 but is that really the reason to why I need to do it? What's the actual logic behind it? I've noticed that if I don't do it, it just never exists the loop because it gets to a point where it just keeps dividing the values to the same value over and over again.
private static int[] values = { 1, 3, 5, 7, 10, 13, 15, 17 };
public static int FindValue(int valueToFind)
{
int l = 0;
int r = values.Length - 1;
while (l <= r)
{
var mid = (l + r) / 2;
if (values[mid] == valueToFind)
return mid;
if (values[mid] < valueToFind)
l = mid + 1;
else
r = mid - 1;
}
return -1;
}
If instead of l = mid + 1; we would have l = mid; then a problem arises when the l and r differ by at most 1 (so there are at most two array values in the running). In that case (l + r) / 2 == l, so that mid will be equal to l. Now let's suppose the value we look for is greater than values[mid], then the if block will execute and l will be assigned mid. But it already had that value, so nothing changes! The next iteration will start with exactly the same state as the previous one, and we'll loop without end.
If you would replace r = mid - 1; with just r = mid, then a similar problem can arise when there is just one value in the array left, i.e. l and r are equal. If the value we look for is less than that only value values[mid], then r will be assigned mid, but again, it already had that value. Nothing changes, and the looping goes on for ever.
The reasoning to have the +1 and -1 in those assignments is that:
it ensures that the interval will get smaller in each iteration, and so it will be impossible to have an infinite loop
it excludes mid from the reduced range, which makes sense, as with the first if we already compared with the value at that index, so it is no longer a candidate.
taking in your last comment, I would assume that it's a rounding issue. It's rounding up and the next calculated number is still higher than the target value. I would add some console logging to printout the value as it's searching.

How do I generate random number between 0 and 1 in C#?

I want to get the random number between 1 and 0. However, I'm getting 0 every single time. Can someone explain me the reason why I and getting 0 all the time?
This is the code I have tried.
Random random = new Random();
int test = random.Next(0, 1);
Console.WriteLine(test);
Console.ReadKey();
According to the documentation, Next returns an integer random number between the (inclusive) minimum and the (exclusive) maximum:
Return Value
A 32-bit signed integer greater than or equal to minValue and less than maxValue; that is, the range of return values includes minValue but not maxValue. If minValue equals maxValue, minValue is returned.
The only integer number which fulfills
0 <= x < 1
is 0, hence you always get the value 0. In other words, 0 is the only integer that is within the half-closed interval [0, 1).
So, if you are actually interested in the integer values 0 or 1, then use 2 as upper bound:
var n = random.Next(0, 2);
If instead you want to get a decimal between 0 and 1, try:
var n = random.NextDouble();
You could, but you should do it this way:
double test = random.NextDouble();
If you wanted to get random integer ( 0 or 1), you should set upper bound to 2, because it is exclusive
int test = random.Next(0, 2);
Every single answer on this page regarding doubles is wrong, which is sort of hilarious because everyone is quoting the documentation. If you generate a double using NextDouble(), you will not get a number between 0 and 1 inclusive of 1, you will get a number from 0 to 1 exclusive of 1.
To get a double, you would have to do some trickery like this:
public double NextRandomRange(double minimum, double maximum)
{
Random rand = new Random();
return rand.NextDouble() * (maximum - minimum) + minimum;
}
and then call
NextRandomRange(0,1 + Double.Epsilon);
Seems like that would work, doesn't it? 1 + Double.Epsilon should be the next biggest number after 1 when working with doubles, right? This is how you would solve the problem with ints.
Wellllllllllllllll.........
I suspect that this will not work correctly, since the underlying code will be generating a few bytes of randomness, and then doing some math tricks to fit it in the expected range. The short answer is that Logic that applies to ints doesn't quite work the same when working with floats.
Lets look, shall we? (https://referencesource.microsoft.com/#mscorlib/system/random.cs,e137873446fcef75)
/*=====================================Next=====================================
**Returns: A double [0..1)
**Arguments: None
**Exceptions: None
==============================================================================*/
public virtual double NextDouble() {
return Sample();
}
What the hell is Sample()?
/*====================================Sample====================================
**Action: Return a new random number [0..1) and reSeed the Seed array.
**Returns: A double [0..1)
**Arguments: None
**Exceptions: None
==============================================================================*/
protected virtual double Sample() {
//Including this division at the end gives us significantly improved
//random number distribution.
return (InternalSample()*(1.0/MBIG));
}
Ok, starting to get somewhere. MBIG btw, is Int32.MaxValue(2147483647 or 2^31-1), making the division work out to:
InternalSample()*0.0000000004656612873077392578125;
Ok, what the hell is InternalSample()?
private int InternalSample() {
int retVal;
int locINext = inext;
int locINextp = inextp;
if (++locINext >=56) locINext=1;
if (++locINextp>= 56) locINextp = 1;
retVal = SeedArray[locINext]-SeedArray[locINextp];
if (retVal == MBIG) retVal--;
if (retVal<0) retVal+=MBIG;
SeedArray[locINext]=retVal;
inext = locINext;
inextp = locINextp;
return retVal;
}
Well...that is something. But what is this SeedArray and inext crap all about?
private int inext;
private int inextp;
private int[] SeedArray = new int[56];
So things start to fall together. Seed array is an array of ints that is used for generating values from. If you look at the init function def, you see that there is a whole lot of bit addition and trickery being done to randomize an array of 55 values with initial quasi-random values.
public Random(int Seed) {
int ii;
int mj, mk;
//Initialize our Seed array.
//This algorithm comes from Numerical Recipes in C (2nd Ed.)
int subtraction = (Seed == Int32.MinValue) ? Int32.MaxValue : Math.Abs(Seed);
mj = MSEED - subtraction;
SeedArray[55]=mj;
mk=1;
for (int i=1; i<55; i++) { //Apparently the range [1..55] is special (All hail Knuth!) and so we're skipping over the 0th position.
ii = (21*i)%55;
SeedArray[ii]=mk;
mk = mj - mk;
if (mk<0) mk+=MBIG;
mj=SeedArray[ii];
}
for (int k=1; k<5; k++) {
for (int i=1; i<56; i++) {
SeedArray[i] -= SeedArray[1+(i+30)%55];
if (SeedArray[i]<0) SeedArray[i]+=MBIG;
}
}
inext=0;
inextp = 21;
Seed = 1;
}
Ok, going back to InternalSample(), we can now see that random doubles are generated by taking the difference of two scrambled up 32 bit ints, clamping the result into the range of 0 to 2147483647 - 1 and then multiplying the result by 1/2147483647. More trickery is done to scramble up the list of seed values as it uses values, but that is essentially it.
(It is interesting to note that the chance of getting any number in the range is roughly 1/r EXCEPT for 2^31-2, which is 2 * (1/r)! So if you think some dumbass coder is using RandNext() to generate numbers on a video poker machine, you should always bet on 2^32-2! This is one reason why we don't use Random for anything important...)
so, if the output of InternalSample() is 0 we multiply that by 0.0000000004656612873077392578125 and get 0, the bottom end of our range. if we get 2147483646, we end up with 0.9999999995343387126922607421875, so the claim that NextDouble produces a result of [0,1) is...sort of right? It would be more accurate to say it is int he range of [0,0.9999999995343387126922607421875].
My suggested above solution would fall on its face, since double.Epsilon = 4.94065645841247E-324, which is WAY smaller than 0.0000000004656612873077392578125 (the amount you would add to our above result to get 1).
Ironically, if it were not for the subtraction of one in the InternalSample() method:
if (retVal == MBIG) retVal--;
we could get to 1 in the return values that come back. So either you copy all the code in the Random class and omit the retVal-- line, or multiply the NextDouble() output by something like 1.0000000004656612875245796924106 to slightly stretch the output to include 1 in the range. Actually testing that value gets us really close, but I don't know if the few hundred million tests I ran just didn't produce 2147483646 (quite likely) or there is a floating point error creeping into the equation. I suspect the former. Millions of test are unlikely to yield a result that has 1 in 2 billion odds.
NextRandomRange(0,1.0000000004656612875245796924106); // try to explain where you got that number during the code review...
TLDR? Inclusive ranges with random doubles is tricky...
You are getting zero because Random.Next(a,b) returns number in range [a, b), which is greater than or equal to a, and less than b.
If you want to get one of the {0, 1}, you should use:
var random = new Random();
var test = random.Next(0, 2);
Because you asked for a number less than 1.
The documentation says:
Return Value
A 32-bit signed integer greater than or equal to minValue and less than maxValue; that is, the range of return values
includes minValue but not maxValue. If minValue equals maxValue,
minValue is returned.
Rewrite the code like this if you are targeting 0.0 to 1.0
Random random = new Random();
double test = random.NextDouble();
Console.WriteLine(test);
Console.ReadKey();

How to calculate the infinite value of a division? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to know the repeating decimal in a fraction?
1/3 is different by 3/10. 0.33333 != 0.3
So 1/3 will be 0.3 (with a line above number three)
1/12 = 0.833333 = 0.083 (with a line above number three)
1/13 = 0.076923076923 = 0.|076923|
Those lines represent the repeating part.
I plan to have this model in a class. I'm a bit lost on this situation. I just need some ideas to know determine the repeating value. Thanks.
Cycle detection algorithm is the answer. You can use Floyd's cycle detection algorithm or Brent's cycle detection algorithm.
The function to plug into those algorithms is the function to produce the next digit of the quotient.
At each step, divide, floor, take the remainder, multiply that by ten, repeat until you get the same number.
For example, for 1/81:
1/81 = 0 with remainder 1 0
10/81 = 0 with remainder 10 0.0
100/81 = 1 with remainder 19 0.01
190/81 = 2 with remainder 28 0.012
280/81 = 3 with remainder 37 0.0123
...
10/81 = 0 with remainder 10; saw this already.
0.|012345679|
Here's a sample implementation:
private static string GetRepeatingPart(int n, int d) {
var seen = new HashSet<int>();
var result = new StringBuilder();
n = (n % d) * 10;
while(true) {
int p = n / d;
n = (n % d) * 10;
if(seen.Contains(n)) {
return result.ToString();
}
result.Append(p);
seen.Add(n);
}
}

how can we compare whether the result of an arithmetic operation is NaN or infinity..?

double SampleInterval = (PopulationValue - valueOfSignItems) / (SampleSize - noOfSignItems);
if my divisor = 0, sampleInterval wil bcom infinity and it will be = NaN if both dividend and divisor are = 0
i need to do my code when SampleInterval = infinity and in another context when SampleInterval = NaN.
How it is possible..??
can any one tel me how can i compare a decinmal value to infinity or to NaN.?
You must use the Double.IsInfinity() and Double.IsNaN() methods.
if (Double.IsInfinity(SampleInterval))
{
//TODO
}
if (Double.IsNaN(SampleInterval))
{
//TODO
}
Don't compare directly to Double.NaN, it will always return false.
Upping a old topic to add another solution (not really good looking but still worth the try if not working for -oo)
You can generate an -Infinity double by yourself, and use it as a comparison
double minusInfinity = -1.0/0.0;
if (yourDouble==minusInfinity ) {
// yourDouble is equal to -oo
}
else {
// yourDouble is not equal to -oo
}
You can do the same for +oo or NaN by using comparison :
double nan = 0.0/0.0;
double infinity = 1.0/0.0;

Categories