Why am I not being warned about too much in C # (and other questions)?
I am learning C # myself and solving project Euler problems for practice. I wrote the code below that solves problem 8, which asks to find the largest product with 13 consecutive digits in a long sequence of digits. I read this sequence of numbers in a program from a file.
First, I started by defining the numeric variables "maxProduct" and "productTmp" as being of type "int", but I didn't get the right answer because it is larger than the maximum range of that type. What confuses me is that I didn't get an error or warning stating that I was trying to manipulate numbers that were too large when dealing with my targets. Instead, he seemed to "wrap up" his range, which seems useless. Is this how it should be?
Second, the part where it reads the file is what I found on the internet. For some reason, however, I cannot write just "IO.StreamReader", but I have to include "System". in front of it, although I have enabled "use the system"; line. I thought that in the statement being used, everything in "System" is available for reference without the System prefix.
And third, in the while loop, where it reads in the file, what's going on? I am assuming that (line = file.ReadLine ()) is a boolean operator, but in this case it doesn't make sense that it could be zero. Also, I didn't give a value for "string", so the statement looks like it is comparing the null value of a string to something else.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace problem8
{
class Program
{
static void Main(string[] args)
{
int noAdjacentDigits = 13;
long maxProduct = 0;
string numberSequence = "", line;
System.IO.StreamReader file = new System.IO.StreamReader("C:/problem8.txt");
while ((line = file.ReadLine()) != null)
{
numberSequence = numberSequence + line;
}
for (int i = 0; i <= numberSequence.Length-noAdjacentDigits;i++)
{
string substrTmp = numberSequence.Substring(i, noAdjacentDigits);
long productTmp = 1;
for (int j = 0; j <= noAdjacentDigits-1; j++)
{
productTmp = productTmp * int.Parse(substrTmp.Substring(j,1));
}
if (productTmp > maxProduct) maxProduct = productTmp;
}
Console.WriteLine(maxProduct);
Console.ReadLine();
}
}
}
source to share
Instead, he seemed to be "wrapping" his range, which seems useless. Is this how it should be?
Yes, unless you put the math in a block checked
or use a compiler option /checked
. The solution is mainly for performance reasons, as overflow checking takes time and is usually unnecessary.
I canβt write alone
IO.StreamReader
, but I must turnSystem.
in front of it
You cannot run a declaration in the middle of a namespace. Add Using System.IO
to the beginning and you can just type StreamReader
.
I am assuming that (line = file.ReadLine ()) is a boolean expression
No, ReadLine
returns a string which null
, if end of file is reached.
The documentation is simple enough:
Reads a character string from the current stream and returns the data as a string.
...
Return value
null
if the end of the input stream has been reached.
source to share
For some reason, however, I cannot write just "IO.StreamReader", but I have to include "System". in front of it, although I have enabled "use the system"; line. I thought that in the statement being used, everything in "System" is available for reference without the System prefix.
All types in the namespace System
will be available using System;
, but System.IO
not a type, it's a different namespace. You can write using System.IO;
and then use StreamReader
directly.
And third, in the while loop, where it reads in the file, what's going on? I am assuming that (line = file.ReadLine ()) is a boolean expression,
This is not true. The result of the assignment is the value that was assigned. (line = file.ReadLine()) != null
calls file.ReadLine()
, assigns the result line
, and then checks if the assigned value was the result of the function call null
.
source to share
Statements can run in verified or unverified contexts .
In a checked context, arithmetic overflow throws an exception. In an uncontrolled context, arithmetic overflow is ignored and the result is truncated.
The C # Language Specification Β§7.6.12 contains the following about default behavior:
For volatile expressions (expressions that are evaluated at runtime) that are not enclosed in any checked or unchecked statements or statements, the default overflow check context is unchecked if external factors (such as as compiler parameters and runtime configuration) call verification score.
source to share