Bitwise operations in C# - c#

Is there a shorter and better-looking alternative to
(b == 0) ? 0 : 1;
in terms of bitwise operations?
Also, to get the correct sign (-1, 0 or 1) of a given integer a I am currently using
(a > 0) ? 1 : (a >> 32);
Are there any shorter (but not slower) ways?

Personally I'd stick with the first option for your "equal to zero or not" option.
For the sign of an integer, I'd use Math.Sign and assume that the JIT compiler is going to inline it - testing that assumption with benchmarks if it turns out to be a potential bottleneck.
Think about the readability above all - your first piece of code is blindingly obvious. Your second isn't. I'm not even convinced your second piece of code works... I thought that right-shifts were effectively masked to the bottom 5 bits, assuming this is an Int32 (int).
EDIT: Just checked, and indeed your current second piece of code is equivalent to:
int y = x > 0 ? 1 : x;
The shift doesn't even end up in the compiled code.
Take this as an object lesson about caring more about micro-optimization than readability.
It's much easier to make code work if it's easy to understand. If your code gives the wrong result, I don't care how quickly it runs.

Microoptimizations are the root of all evil. You sacrifice readability for a nanosecond. That's a bad bargain

in terms of bitwise operations... Can
anyone please point that to me? Also,
to get the correct sign (-1, 0 or 1)
of a given integer a I am currently
using
(a > 0) ? 1 : (a >> 32);
Armen Tsirunyan and Jon Skeet answered your technical question, I am going to attempt to explain some technical misconceptions you appear to have.
The first mistake is that if you have a 32 bit signed integer and attempted to shift it by 32, you would be attempting to look at the 33rd bit which in the case of a signed base 2 arthmetic would be an overflow bit.
The second mistake is when you have 32-bit signed binary value. The last bit would either be a one or zero. There is a only a single zero value. So your statement of trying to figure out if the sign is ( -1,0,1) clearly indicates you don't understand this fact. If the signed bit is a 1 the number would be negative, if it was zero, it would be positive. The structures that handle a number for the most part within the .NET Framework are not aware of 2's complement and 1's complement. This of course does not mean you cannot extend that functionality or simply convert a signed integer to a 2's complement number ( really simple honestly ).
I should add that there is only one value for zero when you have a signed integer. I guess this is was my major problem with your "check the sign" statement that you made which shows a misconception about binary numbers.
http://en.wikipedia.org/wiki/Signed_magnitude#Sign-and-magnitude

Related

Denormalized numbers C#

I recently came across denormalized definition and I understand that there are some numbers that cannot be represented in a normalized form because they are too small to fit into its corresponding type. According with IEEE
So what I was trying to do is catch when a denormalized number is being passed as a parameter to avoid calculations with this numbers. If I am understanding correct I just need to look for numbers within the Range of denormalized
private bool IsDenormalizedNumber(float number)
{
return Math.Pow(2, -149) <= number && number<= ((2-Math.Pow(2,-23))*Math.Pow(2, -127)) ||
Math.Pow(-2, -149) <= number && number<= -((2 - Math.Pow(2, -23)) * Math.Pow(2, -127));
}
Is my interpretation correct?
I think a better approach would be to inspect the bits. Normalized or denormalized is a characteristic of the binary representation, not of the value itself. Therefore, you will be able to detect it more reliably this way and you can do so without and potentially dangerous floating point comparisons.
I put together some runnable code for you, so that you can see it work. I adapted this code from a similar question regarding doubles. Detecting the denormal is much simpler than fully excising the exponent and significand, so I was able to simplify the code greatly.
As for why it works... The exponent is stored in offset notation. The 8 bits of the exponent can take the values 1 to 254 (0 and 255 are reserved for special cases), they are then offset adjusted by -127 yielding the normalized range of -126 (1-127) to 127 (254-127). The exponent is set to 0 in the denormal case. I think this is only required because .NET does not store the leading bit on the significand. According to IEEE 754, it can be stored either way. It appears that C# has opted for dropping it in favor of a sign bit, though I don't have any concrete details to back that observation.
In any case, the actual code is quite simple. All that is required is to excise the 8 bits storing the exponent and test for 0. There is a special case around 0, which is handled below.
NOTE: Per the comment discussion, this code relies on platform specific implementation details (x86_64 in this test case). As #ChiuneSugihara pointed out, the CLI does not ensure this behavior and it may differ on other platforms, such as ARM.
using System;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("-120, denormal? " + IsDenormal((float)Math.Pow(2, -120)));
Console.WriteLine("-126, denormal? " + IsDenormal((float)Math.Pow(2, -126)));
Console.WriteLine("-127, denormal? " + IsDenormal((float)Math.Pow(2, -127)));
Console.WriteLine("-149, denormal? " + IsDenormal((float)Math.Pow(2, -149)));
Console.ReadKey();
}
public static bool IsDenormal(float f)
{
// when 0, the exponent will also be 0 and will break
// the rest of this algorithm, so we should check for
// this first
if (f == 0f)
{
return false;
}
// Get the bits
byte[] buffer = BitConverter.GetBytes(f);
int bits = BitConverter.ToInt32(buffer, 0);
// extract the exponent, 8 bits in the upper registers,
// above the 23 bit significand
int exponent = (bits >> 23) & 0xff;
// check and see if anything is there!
return exponent == 0;
}
}
}
The output is:
-120, denormal? False
-126, denormal? False
-127, denormal? True
-149, denormal? True
Sources:
extracting mantissa and exponent from double in c#
https://en.wikipedia.org/wiki/IEEE_floating_point
https://en.wikipedia.org/wiki/Denormal_number
http://csharpindepth.com/Articles/General/FloatingPoint.aspx
Code adapted from:
extracting mantissa and exponent from double in c#
From my understanding denormalized numbers are there for help with underflows in some cases (see answer to Denormalized Numbers - IEEE 754 Floating Point).
So to get a denormalized number you would need to explicitly create it or else cause an underflow. In the first case it seems unlikely that a literal denormalized number would be specified in code, and even if someone tried it I am not sure that .NET would allow it. In the second case as long as you are in a checked context you should get an OverflowException thrown for any overflow or underflow in an arithmetic computation so that would guard against the possibility of getting a denormalized number. In an unchecked context I am not sure if an underflow will take you to a denormalized number, but you can try it and see if you are wanting to run calculations in unchecked.
Long story short you can not worry about it if you are running in checked and try an underflow and see in unchecked if you want to run in that context.
EDIT
I wanted to update my answer since a comment didn't feel substantial enough. First off I struck out the comment I made about the checked context since that only applies to non-floating point calculations (like int) and not to float or double. That was my mistake on that one.
The issue with denormalized numbers is that they are not consistent in the CLI. Notice how I am using "CLI" and not "C#" because we need to go lower level than just C# to understand the issue. From The Common Language Infrastructure Annotated Standard Partition I Section 12.1.3 the second note (page 125 of the book) it states:
This standard does not specify the behavior of arithmetic operations on denormalized floating point numbers, nor does it specify when or whether such representations should be created. This is in keeping with IEC 60559:1989. In addition, this standard does not specify how to access the exact bit pattern of NaNs that are created, nor the behavior when converting a NaN between 32-bit and 64-bit representation. All of this behavior is deliberately left implementation specific.
So at the CLI level the handling of denormalized numbers is deliberately left to be implementation specific. Furthermore, if you look at the documentation for float.Epsilon (found here), which is the smallest positive number representable by a float you will get a denormalized number on most machines that matches what is listed in the documentation (which is approximately 1.4e-45). This is what #Kevin Burdett was most likely seeing in his answer. That being said if you scroll down farther on the page you will see the following quote under "Platform Notes"
On ARM systems, the value of the Epsilon constant is too small to be detected, so it equates to zero. You can define an alternative epsilon value that equals 1.175494351E-38 instead.
So there are portability issues that can come into play when you are dealing with manually handling denormalized numbers even just for the .NET CLR (which is an implementation of the CLI). In fact this ARM specific value is kind of interesting since it appears to be a normalized number (I used the function from #Kevin Burdett with IsDenormal(1.175494351E-38f) and it returned false). In the CLI proper the concerns are more severe since there is no standardization on their handling by design according to the annotation on the CLI standard. So this leaves questions about what would happen with the same code on Mono or Xamarin for instance which is a difference implementation of the CLI than the .NET CLR.
In the end I am right back to my previous advice. Just don't worry about denormalized numbers, they are there to silently help you and it is hard to imagine why you would need to specifically single them out. Also as #HansPassant mentioned you most likely won't even encounter anyway. It is just hard to imagine how you would be going under the smallest, positive normalized number in double which is absurdly small.

Is there a reason I shouldn't be testing a set of variables for 0 by testing their product?

Is there a reason I shouldn't be testing a set of variables for 0 by testing their product?
Often in my coding across different languages I will test a set of variables to do something if they all consist of zeros.
For example (c#):
if( myString.Length * myInt * (myUrl.LastIndexOf(#"\")+1) == 0 )
Instead of:
if( myString.Length == 0 || myInt == 0 || myUrl.LastIndexOf(#"\") < 0)
Is there a reason I shouldn't be testing this way?
Here are a few reasons. All are important, and they're in no particular order.
Short circuiting. In your first example, all three things will be evaluated even if they don't need to be. In some cases, this can be a real problem: short circuiting is nice because you can do things like if (myObj != null && myObj.Enabled) without throwing exceptions
Correctness. Is myString.Length * myInt * myUrl.LastIndexOf(#"\") == 0 actually equivalent in all practical cases to if( myString.Length > 0 && myInt != 0 && myUrl.LastIndexOf(#"\") <= 0)? I'm not sure. I doubt it. I'm sure I could figure it out with some effort, but why should I have to in the first place? Which brings me to...
Clarity. Since the conventional way is to use separate statements and &&, anyone reading this code in the future will have a harder time understanding what it's doing. And don't make the excuse that, "I'll be the only one to read it", because in a few months or years, you'll probably have forgotten the thoughts and conventions you had when you wrote it, and be reading it just like anyone else.
You shouldn't do that because it's not obvious what you're doing. Code should be clean, readable, and easily maintainable.
It's clever, but it's going to make the next person who looks at your code have to "decipher" what your intent was by doing it that way.
There are practical cases in which that will not work.
Consider for example a string of length 65536 where the last character is a "\". 65536 * myInt * 65536 is always zero, because the product contains a factor 232 and int's are only 32 bits long. All the bits that would be set are not actually present in the result.
Depending on the value of myInt, that can also happen for shorter strings, but a string of 65k isn't that much of a stretch. (an URL of 65k may be a bit of a stretch, but whatever)
Note, by the way, that it's not so much the overflow that causes the problem, the problem is having several too-high powers of 2 as factor. For example, if all factors are odd (but high), the result will be odd as well (regardless of overflows), and therefore at least one bit will be set.

C# and strange exponentiation of complex numbers

Have been playing around with complex numbers in C#, and I found something interesting. Not sure if its a bug or if I have just missed something, but when I run the following code:
var num = new Complex(0, 1);
var complexPow = Complex.Pow(num, 2);
var numTimesNum = num * num;
Console.WriteLine("Complex.Pow(num, 2) = {0} num*num = {1}", complexPow.ToString(), numTimesNum.ToString());
I get the following output:
Complex.Pow(num, 2) = (-1, 1.22460635382238E-16) num*num = (-1, 0)
If memory serves, a complex number times itself should be just -1 with no imaginary part (or rather an imaginary part of 0). So why doesnt Complex.Pow(num, 2) give -1? Where does the 1.22460635382238E-16 come from?
If it matters, I am using mono since Im not in Windows atm. Think it might be 64-bit, since I am running a 64-bit OS, but I am not sure where to check.
Take care,
Kerr.
EDIT:
Ok, I explained poorly. I of course mean the square of i is -1, not the square of any complex number. Thanks for pointing it out. A bit tired right now, so my brain doesnt work too well, lol.
EDIT 2:
To clarify something, I have been reading a little math lately and decided to make a small scripting language for fun. Ok, "scripting language" is an over statement, it just evaluates equations and nothing more.
You're seeing floating-point imprecision.
1.22460635382238E-16 is actually 0.00000000000000012....
Complex.Pow() is probably implemented through De Moivre's formula, using trigonometry to compute arbitrary powers.
It is therefore subject to inaccuracy from both floating-point arithmetic and trig.
It apparently does not have any special-case code for integral powers, which can be simpler.
Ordinary complex multiplication only involves simple arithmetic, so it is not subject to floating-point inaccuracies when the numbers are integral.
So why doesnt Complex.Pow(num, 2) give -1? Where does the 1.22460635382238E-16 come from?
I suspect it's a rounding error, basically. It's a very small number, after all. I don't know the details of Complex.Pow, but I wouldn't be at all surprised to find it used some trigonometry somewhere - you may well be observing the fact that pi/2 isn't exactly representable as a double.
The * operation is able to avoid this by being more simply defined - Complex.Pow could be special-cased to just use x * x where the power is 2, but I expect that hasn't been done. Instead, a general algorithm is used which gives an answer very close to the hypothetical one, but which can result in small errors.
So why doesnt Complex.Pow(num, 2) give -1? Where does the 1.22460635382238E-16 come from?
Standard issues with floating point representations, and the algorithms that are used to compute Complex.Pow (it's not as simple as you think). Note that 1.22460635382238E-16 is extremely small, close to machine epsilon. Additionally, a key fact here is that (0, 1) is really (1, pi / 2) in polar coordinates, and pi / 2 doesn't have an exact representation in floating point.
If this is at all uncomfortable to you, I recommend reading What Every Computer Scientist Should Know About Floating-Point Arithmetic. It should be required reading for college CS curriculum.

C#/XNA - Multiplication faster than Division?

I saw a tweet recently that confused me (this was posted by an XNA coder, in the context of writing an XNA game):
Microoptimization tip of the day: when possible, use multiplication instead of division in high frequency areas. It's a few cycles faster.
I was quite surprised, because I always thought compilers where pretty smart (for example, using bit-shifting), and recently read a post by Shawn Hargreaves saying much the same thing. I wondered how much truth there was in this, since there are lots of calculations in my game.
I inquired, hoping for a sample, however the original poster was unable to give one. He did, however, say this:
Not necessarily when it's something like "center = width / 2". And I've already determined "yes, it's worth it". :)
So, I'm curious...
Can anyone give an example of some code where you can change a division to a multiplication and get a performance gain, where the C# compiler wasn't able to do the same thing itself.
Most compilers can do a reasonable job of optimizing when you give them a chance. For example, if you're dividing by a constant, chances are pretty good that the compiler can/will optimize that so it's done about as quickly as anything you can reasonably substitute for it.
When, however, you have two values that aren't known ahead of time, and you need to divide one by the other to get the answer, if there was much way for the compiler to do much with it, it would -- and for that matter, if there was much room for the compiler to optimize it much, the CPU would do it so the compiler didn't have to.
Edit: Your best bet for something like that (that's reasonably realistic) would probably be something like:
double scale_factor = get_input();
for (i=0; i<values.size(); i++)
values[i] /= scale_factor;
This is relatively easy to convert to something like:
scale_factor = 1.0 / scale_factor;
for (i=0; i<values.size(); i++)
values[i] *= scale_factor;
I can't really guarantee much one way or the other about a particular compiler doing that. It's basically a combination of strength reduction and loop hoisting. There are certainly optimizers that know how to do both, but what I've seen of the C# compiler suggests that it may not (but I never tested anything exactly like this, and the testing I did was a few versions back...)
Although the compiler can optimize out divisions and multiplications by powers of 2, other numbers can be difficult or impossible to optimize. Try optimizing a division by 17 and you'll see why. This is of course assuming the compiler doesn't know that you are dividing by 17 ahead of time (it is a run-time variable, not a constant).
Bit late but never mind.
The answer to your question is yes.
Have a look at my article here, http://www.codeproject.com/KB/cs/UniqueStringList2.aspx, which uses information based on the article mentioned in the first comment to your question.
I have a QuickDivideInfo struct which stores the magic number and the shift for a given divisor thus allowing division and modulo to be calculated using faster multiplication. I pre-computed (and tested!) QuickDivideInfos for a list of Golden Prime Numbers. For x64 at least, the .Divide method on QuickDivideInfo is inlined and is 3x quicker than using the divide operator (on an i5); it works for all numerators except int.MinValue and cannot overflow since the multiplication is stored in 64 bits before shifting. (I've not tried on x86 but if it doesn't inline for some reasons then the neatness of the Divide method would be lost and you would have to manually inline it).
So the above will work in all scenarios (except int.MinValue) if you can precalculate. If you trust the code that generates the magic number/shift, then you can deal with any divisor at runtime.
Other well-known small divisors with a very limited range of numerators could be written inline and may well be faster if they don't need an intermediate long.
Division by multiple of two: I would expect the compiler to deal with this (as in your width / 2) example since it is constant. If it doesn't then changing it to width >> 1 should be fine
To give some numbers, on this pdf
http://cs.smith.edu/dftwiki/index.php/CSC231_Pentium_Instructions_and_Flags
of the Pentium we get some numbers, and they aren't good:
IMUL 10 or 11
FMUL 3+1
IDIV 46 (32 bits operand)
FDIV 39
We are speaking of BIG differences
while(start<=end)
{
int mid=(start+end)/2;
if(mid*mid==A)
return mid;
if(mid*mid<A)
{
start=mid+1;
ans=mid;
}
If i am doing this way the outcome is the TIME LIMIT EXCEEDED for square root of 2147483647
But if i am doing the following way then the thing is clear that for Division compiler responds faster than for multiplication.
while(start<=end)
{
int mid=(start+end)/2;
if(mid==A/mid)
return mid;
if(mid<A/mid)
{
start=mid+1;
ans=mid;
}
else
end=mid-1;
}

long/large numbers and modulus in .NET

I'm currently writing a quick custom encoding method where I take a stamp a key with a number to verify that it is a valid key.
Basically I was taking whatever number that comes out of the encoding and multiplying it by a key.
I would then multiply those numbers to the deploy to the user/customer who purchases the key. I wanted to simply use (Code % Key == 0) to verify that the key is valid, but for large values the mod function does not seem to function as expected.
Number = 468721387;
Key = 12345678;
Code = Number * Key;
Using the numbers above:
Code % Key == 11418772
And for smaller numbers it would correctly return 0. Is there a reliable way to check divisibility for a long in .NET?
Thanks!
EDIT:
Ok, tell me if I'm special and missing something...
long a = DateTime.Now.Ticks;
long b = 12345;
long c = a * b;
long d = c % b;
d == 10001 (Bad)
and
long a = DateTime.Now.Ticks;
long b = 12;
long c = a * b;
long d = c % b;
d == 0 (Good)
What am I doing wrong?
As others have said, your problem is integer overflow. You can make this more obvious by checking "Check for arithmetic overflow/underflow" in the "Advanced Build Settings" dialog. When you do so, you'll get an OverflowException when you perform *DateTime.Now.Ticks * 12345*.
One simple solution is just to change "long" to "decimal" (or "double") in your code.
In .NET 4.0, there is a new BigInteger class.
Finally, you say you're "... writing a quick custom encoding method ...", so a simple homebrew solution may be satisfactory for your needs. However, if this is production code, you might consider more robust solutions involving cryptography or something from a third-party who specializes in software licensing.
The answers that say that integer overflow is the likely culprit are almost certainly correct; you can verify that by putting a "checked" block around the multiplication and seeing if it throws an exception.
But there is a much larger problem here that everyone seems to be ignoring.
The best thing to do is to take a large step back and reconsider the wisdom of this entire scheme. It appears that you are attempting to design a crypto-based security system but you are clearly not an expert on cryptographic arithmetic. That is a huge red warning flag. If you need a crypto-based security system DO NOT ATTEMPT TO ROLL YOUR OWN. There are plenty of off-the-shelf crypto systems that are built by experts, heavily tested, and readily available. Use one of them.
If you are in fact hell-bent on rolling your own crypto, getting the math right in 64 bits is the least of your worries. 64 bit integers are way too small for this crypto application. You need to be using a much larger integer size; otherwise, finding a key that matches the code is trivial.
Again, I cannot emphasize strongly enough how difficult it is to construct correct crypto-based security code that actually protects real users from real threats.
Integer Overflow...see my comment.
The value of the multiplication you're doing overflows the int data type and causes it to wrap (int values fall between +/-2147483647).
Pick a more appropriate data type to hold a value as large as 5786683315615386 (the result of your multiplication).
UPDATE
Your new example changes things a little.
You're using long, but now you're using System.DateTime.Ticks which on Mono (not sure about the MS platform) is returning 633909674610619350.
When you multiply that by a large number, you are now overflowing a long just like you were overflowing an int previously. At that point, you'll probably need to use a double to work with the values you want (decimal may work as well, depending on how large your multiplier gets).
Apparently, your Code fails to fit in the int data type. Try using long instead:
long code = (long)number * key;
The (long) cast is necessary. Without the cast, the multiplication will be done in 32-bit integer form (assuming number and key variables are typed int) and the result will be casted to long which is not what you want. By casting one of the operands to long, you tell the compiler to perform the multiplication on two long numbers.

Categories

Resources