-6

I have byte array which holds 4 bytes to be converter to integer. I have these two examples, they both produce same result when tested on int.MinValue, 0, int.MaxValue and other values.

byte[] bytes; //holds 4 bytes

//solution a
int a = bytes[0] | (bytes[1] << 8) | (bytes[2] << 16) | (bytes[3] << 24);

//solution b
return bytes[0] + (bytes[1] << 8) + (bytes[2] << 16) + (bytes[3] << 24);

What are differences between these two examples, are they both valid to be used, might there be any execution speed difference? Unfortunately i were not able to find descriptions on the difference.

::Note that im looking answers for this specific case, please, instead of answering dont suggest BitConverter or other libraries.

Thanks

Scavs
  • 673
  • 1
  • 5
  • 16
  • 4 downvotes in 20 seconds, thank you for your help – Scavs Feb 14 '18 at 18:38
  • 6
    You wrote some code two ways and you want to know which of them is faster. I have two horses and I want to know which is faster; should I ask strangers on the internet to guess, or should I race my horses? **Run your code** and then you will know which way ran faster! – Eric Lippert Feb 14 '18 at 18:56
  • @EricLippert You can only compare horses of the same type and if they can run at all, im not an expert running these horses nor training them. Testing their speed in barn and and not in production cannot be done as stakes might be too high. I hoped i might find some experience stable men, who might possible know and tell me that both horses are not the same and one might fail under specific circumstance, because of specific value, endian or platform difference. If horses are the same and only difference is the color i have to problem grabbing a stopwatch and test them on the lap. – Scavs Feb 14 '18 at 19:07
  • 1
    If you want to know if the two code fragments always produce the same results, **there are only four billion possible inputs**. Try them all and then you'll know. You're a computer programmer; when you have a problem, your first question should be "how can I write a program to answer this question?" – Eric Lippert Feb 14 '18 at 19:14
  • @EricLippert Wouldn't it be easier to understanding the principle of the math and how is it calculated instead of just looking at the results? My first point i'd like to know is the difference, not sure why are you skipping that and attacking only about second point which is performance. I am not a math guy, not sure how | and + operators in-between same statement variables produces same result. I think its a valid question for stackoverflow don't you think? – Scavs Feb 14 '18 at 19:23
  • [practical applications of bitwise operations](https://stackoverflow.com/questions/3883384/practical-applications-of-bitwise-operations) Roughly 6800 more posts here, then there are all those articles on MSDN – Ňɏssa Pøngjǣrdenlarp Feb 14 '18 at 19:31
  • @Plutonix Did you just throw a random google search in just to show the productivity of your response? All the examples in the post you yourself mentioned are only about | operator, ive seen only some which give examples using + operator - But what is the difference? But the directions are very clear and bright - compare 4 billion results for every possible data type in c# to look for possible mismatches and read 6800 pages. Thank you very much a nice valentines day. – Scavs Feb 14 '18 at 19:44
  • 2
    You could have written and run a program that compared all four billion results in the amount of time you've been complaining about the quality of the help you've gotten for free. – Eric Lippert Feb 14 '18 at 19:45
  • 2
    Now, if your question is which one of these would I *prefer*, unambiguously I would choose "use a library dedicated to that purpose", a correct solution which you have rejected without giving any reason. If forced to choose between these two solutions, I would always choose the one that does *not* mix arithmetic with bitwise operations. Ints can be seen as numbers, or as arrays of bits; if you're treating ints as numbers, use number operations on them: addition, subtraction, multiplication, and so on. If you're going to treat them as bit arrays, use bit operations. – Eric Lippert Feb 14 '18 at 20:06
  • @Eric Lippert Run program on what system and what framework, all of them? Suggestion sounds like something first class college student would do. You cant possibly say that answering to my post grants you chance to offend me that I am not automatically sending money to everyone who makes a comment, and you mention it like it's expected of me. – Scavs Feb 14 '18 at 20:06
  • You could maybe add a disclaimer or a note on your page that reading anything you write taxes me an automated bill, maybe even add a Patreon. And offending me of complaining about the quality is just nonsense and low, defensing my position on the matter against possible bully mods is now considered complaining. – Scavs Feb 14 '18 at 20:06
  • I'd prefer to know how and why this works and produces same results, id really not prefer using library blindly and i'd like to know computers work. – Scavs Feb 14 '18 at 20:09

1 Answers1

3

Both will give the same result, but I’d choose the | always, because you are dealing with bits, not numbers.

In order to understand why they are equivalent you first have to understand binary numbers and binary maths:

var b = 0b0011; //binary 0011

Ok, lets do something similar to your code:

var s = b + (b << 2);

Step by step:

0011 < 2 is 1100

And to evaluate 1100 | 0011, you simply or every bit with its counterpart. The result is 1111

Now, what’s (0011 < 2) + 1100? Well, do normal addition but remember, this is binary numbers so we carry over twos not tens:

 0011 +
 1100
 ———-
 1111

You see now why both will always give the same result? There will never be any carry overs so addition and oring is essentially the same: 0 + 1 and 0|1 give the same result, but again, they are totally different operations.

InBetween
  • 32,319
  • 3
  • 50
  • 90