I'm learning C# and have been messing about on the Pex for fun site. The site challenges you to re-implement a secret algorithm, by typing code into the site and examining how the inputs and outputs differ between your implementation and the secret implementation.
Anyway, I got stuck on a basic code duel called XAndY.
From the name it seemed obvious that the answer was just:
public static bool Puzzle(bool x, bool y)
{
return x && y;
}
However, this was incorrect and Pex informed me that the following inputs produced a different result than the secret implementation:
Input:
x:true y:true (0x02)
Output:
my implementation: true (0x02)
secret implementation: false
Mismatch Your puzzle method produced the wrong result.
Code: Puzzle(true, PexSafeHelpers.ByteToBoolean((byte)2));
After a lot of confusion trying to compare different types of true, I realised that the implementation that Pex was looking for was actually just using a bitwise AND:
return x & y;
I thought that for both semantic and short-circuiting reasons you should use logical && for comparing boolean values, but regardless:
x & y and x && y definitively do not have the same outputs for all possible bool arguments? (or could it be something buggy in Pex?)true in C#? If so, how?X-rays are commonly produced in X-ray tubes by accelerating electrons through a potential difference (a voltage drop) and directing them onto a target material (i.e. tungsten). The incoming electrons release X-rays as they slowdown in the target (braking radiation or bremsstrahlung).
When X-ray radiation is absorbed within our bodies, it can damage molecular structures and potentially cause harm. Very high doses of radiation cause damage to human cells, as evidenced by skin burns, loss of hair, and increased incidence of cancer.
Now we come to the most important question, How much of Xray is safe for a person in his lifetime? Xray is generally measured or compared with normal environment radiation. The American College of Radiology recommends 100mSv in a lifetime which is equal to 10000 chest Xrays or 25ct chest scans.
The puzzle is exploiting what, in my opinion, is a bug in the C# compiler. (The bug affects VB.NET as well.)
In the C# 5.0 specification, §4.1.8 says that "The possible values of type bool are true and false", and §7.11.3 says that operator &(bool x, bool y) is a logical operator:
The result of
x & yistrueif bothxandyaretrue. Otherwise, the result isfalse.
It's obviously a violation of the specification for true & true to yield false. What's going on?
At run time, a bool is represented by a 1-byte integer. The C# compiler uses 0 to represent false and 1 to represent true. To implement the & operator, the C# compiler emits a bitwise AND instruction in the generated IL. At first glance, this seems to be okay: bitwise AND operations involving 0 and 1 correspond exactly with logical AND operations involving false and true.
However, §III.1.1.2 of the CLI specification explicitly allows a bool to be represented by an integer other than 0 or 1:
A CLI Boolean type occupies 1 byte in memory. A bit pattern of all zeroes denotes a value of false. A bit pattern with any one or more bits set (analogous to a non-zero integer) denotes a value of true.
By going beyond the scope of C#, it is indeed possible—and perfectly legal—to create a bool whose value is, say, 2, thus causing & to behave unexpectedly. This is what the Pex site is doing.
Here's a demonstration:
using System;
using System.Reflection.Emit;
class Program
{
static void Main()
{
DynamicMethod method =
new DynamicMethod("ByteToBoolean", typeof(bool), new[] { typeof(byte) });
ILGenerator il = method.GetILGenerator();
il.Emit(OpCodes.Ldarg_0); // Load the byte argument...
il.Emit(OpCodes.Ret); // and "cast" it directly to bool.
var byteToBoolean =
(Func<byte, bool>)method.CreateDelegate(typeof(Func<byte, bool>));
bool x = true;
bool y = byteToBoolean(2);
Console.WriteLine(x); // True
Console.WriteLine(y); // True
Console.WriteLine(x && y); // True
Console.WriteLine(x & y); // False (!) because 1 & 2 == 0
Console.WriteLine(y.Equals(false)); // False
Console.WriteLine(y.Equals(true)); // False (!) because 2 != 1
}
}
So the answers to your questions are:
x & y and x && y to have different values. However, this behavior violates the C# specification.Boolean.Equals (as shown above) to differentiate between true values. However, this behavior violates the CLI specification of Boolean.Equals.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With