## #1,127 – Where to Find Compiler Warning Numbers

You can use #pragma warning to selectively disable certain warnings that occur when compiling your code.

The #pragma warning line requires knowing the specific warning number, which is not displayed in the list of warnings on the Error List tab.

To find the warning number, you need to switch to the Output tab and look at the full text of the warning.  In the example below, we see that the warning about an event that is never used is warning #67.

Once you know the warning number, you can use it with a #pragma warning.

```#pragma warning disable 67
public event EventHandler CanBarkChanged;
#pragma warning restore 67
```

## #1,113 – Addition of Integers Using Twos Complement

The primary benefit of using twos complement to represent signed integers is that addition and subtraction work the same, whether the number is positive or negative.

Below is an example, showing how we add the value -2 to the value +5, yielding a result of +3.  (Assuming that both values are stored as 16-bit integers).  The carry bits are shown in the top line.  We discard the final carry bit that results from adding the leftmost two bits.

## #1,112 – How Integers Are Stored in .NET

Integer values in .NET are stored in memory as described below.  The examples below use a 2-byte short data type as an example.

A value of zero is stored by setting every bit in the storage location to zero.

Positive values are stored directly as their corresponding binary number.

The maximum possible integer value has all bits set to 1 except for the leftmost.  So Max = 2^(n-1) – 1, where n is the total number of bits.

Negative integer values are stored using a two’s complement representation, calculated by starting with the bit pattern for the corresponding positive number, negating all of the bits, and then adding 1 to the result.

The minimum possible integer value (largest negative value) has only the leftmost bit set to 1.  So Min = -(2^(n-1)), where n is the total number of bits.

## #1,106 – Using the Logical Exclusive OR Operator

You can use the exclusive OR (^) operator to do a bitwise exclusive OR operation.  The operands in this case are integer-based types.

You can also use the exclusive OR operator on boolean operands.  The result of the operation is true if exactly one of the operands (but not both) is true.

• false ^ false => false
• false ^ true => true
• true ^ false => true
• true ^ true => false
```            bool itsThursday = DateTime.Now.DayOfWeek == DayOfWeek.Thursday;
bool itsMay = DateTime.Now.Month == 5;

// Wear red shirt in May, wear red shirt every Thursday,
// but don't wear red shirt on Thursdays in May
bool wearRedShirt = itsThursday ^ itsMay;

Console.WriteLine("Thursday:{0}, May:{1}, RedShirt:{2}", itsThursday, itsMay, wearRedShirt);
```

## #1,105 – Re-Declaring a Class-Level Variable within a Method

You can re-declare a class-level variable within a method, that is–declare a local variable having the same name as a class-level variable.  Within the scope of the method, the local variable will hide the class-level variable.

```    public class MyClass
{
public int x = 10;

public void MethodA()
{
double x = 4.2;
Console.WriteLine(x);
}
}
```

You cannot, however, reference a class-level variable before declaring the local variable, since this is interpreted as referencing the local variable before it is defined.

```        public void MethodA()
{
// ERROR: Can't use local variable before it's declared
Console.WriteLine(x);

double x = 4.2;
Console.WriteLine(x);
}
```

You also can’t reference the class-level variable in an outer scope.

```        public void MethodA()
{
Console.WriteLine(x);

if (DateTime.Now.DayOfWeek == DayOfWeek.Tuesday)
{
// ERROR: Can't declare local variable within this scope
double x = 4.2;
Console.WriteLine(x);
}
}
```

## #1,104 – Can’t Re-Declare a Variable within a Nested Block

A declaration space is a region of code within which you can’t declare two entities having the same name.

Defining a class creates a new declaration space, i.e. you can declare variables at the class level.

Defining a method creates a new declaration space, known as a local variable declaration space.  A block of code within that method creates a nested local variable declaration space.

It’s of course an error to declare two variables of the same name within a local variable declaration space.  It’s also an error to re-declare a variable of the same name in a nested local variable declaration space.

```        public void MethodA()
{
int y = 1;
string y = "oops";  // ERROR

int x = 12;
Console.WriteLine(12);

if (DateTime.Now.DayOfWeek == DayOfWeek.Thursday)
{
// ERROR: Can't re-declare x within nested local variable declaration space
double x = 4.2;
Console.WriteLine(x);
}
}
```

## #1,103 – A Block Defines Both Scope and Declaration Space

• Scope is the region of code in which you can refer to a named entity using its unqualified name.
• Declaration space is a region of code within which you can’t declare two entities having the same name

A block of statements defines both a new scope and a new declaration space.

In the code below, the variable msg is declared within the block of statements following the if statement.

```    public class MyClass
{
public void AMethod()
{
if (DateTime.Now.DayOfWeek == DayOfWeek.Thursday)
{
// Can define variables within this block
string msg = "Hi";
Console.WriteLine("{0}, it's Thursday. ", msg);
}

// ERROR: The name 'msg' does not exist in the current context
Console.WriteLine(msg);
}
}
```

The block defines a new scope–the variable msg can be referred to by name anywhere within the block (after the declaration).  This block also defines a declaration space–you can only declare one variable named msg within this block.

## #1,102 – Scope vs. Declaration Space

The terms scope and declaration space are similar, but slightly different.

• Scope is the region of code in which you can refer to a named entity using its unqualified name.
• Declaration space is a region of code within which you can’t declare two entities having the same name

For example:

```    public class MyClass
{
int count1 = 1;
int count2 = 2;

public void AMethod()
{
int count2 = 22;

Console.WriteLine(count1 + ", " + count2);
}
}
```

Then:

• The class-level declarations of count1 and count2 are in the same scope and in the same declaration space
• The body of function AMethod()
• is included in the scope in which class-level fields are defined, i.e. you can reference them using their unqualified name.
• defines a new declaration space, i.e. we can define a new variable of the same name as the class-level fields
• defines a new scope, in which we can define variables, nested within outer scope

## #1,098 – Floating Point Overflow

When you perform an arithmetic operation on a floating point value and the result has a magnitude that is too large to be represented by the floating point data type, an overflow condition occurs.  This is equivalent to trying to store a value whose exponent is larger than the maximum allowed exponent value.

If the result of the calculation is greater than the maximum representable positive floating point value, the result of the calculation is +Infinity.  If the result of the calculation is less than the largest representable negative floating point value, the result of the calculation is -Infinity.

```            // Create a big floating point number
float bigNumber = float.MaxValue;
Console.WriteLine(bigNumber);  // 3.402823E+38

// Adding small number doesn't change large number
float newBig = bigNumber + 1.0f;
Console.WriteLine(newBig);     // 3.402823E+38

// But doubling the original number leads to overflow
float reallyBig = bigNumber * 2.0f;
Console.WriteLine(reallyBig);
```

## #1,097 – Summary of how Floating Point Numbers Are Stored in .NET

Here’s a complete summary of how 32-bit and 64-bit floating point numbers are represented in .NET, including special values.  For more background, look here and here.

Floating point numbers are stored in .NET according to the IEEE 754 standard:

• Normalized values (1.bb x 2^bb)
• Sign bit – positive/negative
• Mantissa – normalized binary number, does not store leading 1  (23 or 52 bits)
• Exponent – biased, add 127 (or 1023) to exponent before storing  (8 or 11 bits)
• Subnormal numbers
• Sign bit – positive/negative
• Mantissa – non-normalized, no implied leading 1  (23 or 52 bits)
• Exponent – 0
• Positive/negative zero
• Sign bit – positive/negative
• Mantissa – 0
• Exponent – 0
• Positive/negative infinity
• Sign bit – positive/negative
• Mantissa – 0
• Exponent – FF (hex) or 7FF (hex)
• NaN
• Sign bit – not defined (implementation dependent)
• Mantissa – some non-zero value
• Exponent – FF (hex) or 7FF (hex)

Ranges for (normalized) numbers represented as 32- and 64-bit floating point numbers:

• 32-bit float: -3.4 x 10^38 to 3.4 x 10^38
• 64-bit double: -1.7 x 10^308 to 1.7 x 10^308