I have 2 decimal values: a and b. How do I use bit operator to check if two value is same sign?
You can use Math.Sign(). When you use Math.Sign(x), if x is negative it returns -1 else if its positive, the function returns 1 or when its 0 it returns 0. So :
if(Math.Sign(a) == Math.Sign(b))
{
// Code when sign matched.
}
else
{
// Code when sign not matched.
}
Do you mean if both are positive or both are negative?
bool bothSameSign = (d1 >= 0 && d2 >= 0) || (d1 < 0 && d2 < 0);
I don't think you really need to use the bit operator for this, but if for some reason you must (e.g. this is a school question):
Firstly you can use Decimal.GetBits() get all the bits in the two Decimals to compare, as an array of 4 ints.
Then you can inspect the sign bit which is at bit 31 in the int at offset 3 in the array of ints.
Decimal d1 = 1;
Decimal d2 = -1;
var bits1 = Decimal.GetBits(d1);
var bits2 = Decimal.GetBits(d2);
const int signMask = 1 << 31;
const int signWord = 3;
bool sameSign = ((bits1[signWord] & signMask) == (bits2[signWord] & signMask));
You could make,
static int Sign(this decimal value)
{
return Decimal.GetBits(value)[3] & 0x8000;
}
and do
a.Sign == b.Sign;
Bitwise shift is required for the sign-checking you want to accomplish:
if ( ( number >> sizeof(byte) * sizeof(numberType) -1 ) & 1)
{ /* < 0 */ }
else
{ /* >= 0 */ }
// you can of course use magic numbers
// example for int: if ( ( number >> 31 ) & 1) { /* < 0 */ }
Problem is, you can't bitshift a decimal. You would have to do something like this:
var shiftableNumber = Int.Parse(Math.Truncate(yourDecimal));
I can't verify it, but I suspect it would defeat the purpose of optimizing through bitwise operators. You might aswell use the builtin Math.Sign() directly.
Related
I am trying to convert decimal to hexadecimal. I have found many codes online. I used
int decValue = int.Parse(hexValue, System.Globalization.NumberStyles.HexNumber);
but my instructor told me I can't use any of those, just use recursive method. I am new to programming and little confused about recursive method.
I did find other methods to convert it, I am using below method, and I used switch statement to change numbers to letters. Program works fine. But not sure if it is recursive method? Can someone let me know if it is recursive method, if not help me understand how recursive method work.
static void HexadecimalConversion(int decimals)
{
if (decimals == 0)
return;
else
{
int hexadecimals = decimals % 16;
decimals = decimals / 16;
HexadecimalConversion(decimals);
With most recursive problems, you have 1 or 2 special cases and a general case. For this problem there are 3 cases:
Special Case #1. The value to be converted is 0.
The General Case. The value to be converted is greater than 0.
The Terminating Case. When the value to be converted is finally decremented to 0.
You need to distinguish between the two 'zero' conditions, lest you always append a trailing zero to the result, so...you need a 2-layered approach, something like this:
static string Int2Hex( int value )
{
if ( value < 0 ) throw new ArgumentOutOfRangeException("value") ;
if ( value == 0 ) return "0" ;
string result = ToHex( (uint) value ).ToString() ;
return result ;
}
static StringBuilder ToHex ( uint value )
{
StringBuilder buffer ;
if ( value <= 0 )
{
buffer = new StringBuilder() ;
}
else
{
buffer = ToHex( value / 16 ).Append( "0123456789ABCDEF"[ (int)(value % 16 ) ] ) ;
}
return buffer ;
}
Yet another implementation:
public string ConvertToHexa(int number)
{
if (number == 0)
return String.Empty;
var head = ConvertToHexa(number / 16);
var remainder = number % 16;
var tail = (char)(remainder + (remainder >= 10 ? 'A' - 10 : '0'));
return head + tail;
}
Console.WriteLine(ConvertToHexa(202)) gives "CA" (which is correct).
Another implementation
public void ConvertToHexa(int number)
{
if (number == 0)
return;
ConvertToHexa(number / 16);
var remainder = number % 16;
Console.Write(remainder >= 10 ? ((char)(remainder - 10 + 'A')).ToString() : remainder.ToString());
}
Ok, I have N = integer, P = position,V = 0 or 1
I have to change the bit at position P of integer N with the value V
I'm trying with
N = 5 (101)
P = 2 (takes the 1)
V = 0 (has to make it a zero)
and the result is 97 (1100 0001) (should be 0000 0001)
I think the problem is from the mask because when I write it in the console its -5 (as it should be) but if I parse it, to see its bits I get an error (overflow)
the program is in the making so I'm currently working on V = 0 so don't try with 1
Yesterday I posted a question and a lot of people posted sh*t like "this is not a question - you want us to solve u your problem" - No, I don't want you to solve me the problem I want to know why after int result = mask & integerBinary; I get 97 and not 1
using System;
class ChangeBit
{
static void Main()
{
Console.Write("(n) Type an integer: ");
string integerLine = Console.ReadLine(); // Read string from console
Console.Write("(p) Type position: ");
string positionLine = Console.ReadLine(); // Read string from console
Console.Write("(v) Type 0 or 1: ");
string valueLine = Console.ReadLine(); // Read string from console
int value;
int integer;
int position;
if (int.TryParse(integerLine, out integer) && int.TryParse(positionLine, out position) && int.TryParse(valueLine, out value)) // Try to parse the strings as integers
{
int integerBinary = int.Parse(Convert.ToString(integer, 2));
int bitValue = ((1 << position) & integerBinary) >> position;
int mask = ~(1 << position);
if (value==0)
{
int result = mask & integerBinary;
Console.WriteLine("(n) After bit conversion = {0}", result);
}
else Console.WriteLine("(n) After bit conversion = {0}", integer);
}
else
{
Console.WriteLine("Invalid input.");
}
}
}
Much easier:
if (int.TryParse(integerLine, out integer) && int.TryParse(positionLine, out position) && int.TryParse(valueLine, out value)) // Try to parse the strings as integers
{
BitArray a = new BitArray(BitConverter.GetBytes(integer));
a.Set(position, value == 1);
Console.WriteLine("(n) After bit conversion = {0}", a.GetInt32());
}
With GetInt32 declared :
internal static class BitArrayEx
{
internal static int GetInt32(this BitArray bitArray)
{
int[] array = new int[1];
bitArray.CopyTo(array, 0);
return array[0];
}
}
Try:
integer ^ ((-value ^ integer) & (1 << position))
This will check if the bit is set and, if so, will change its value using the bitwise operator ^.
You are mixing binary string representation with binary integers:
int integerBinary = int.Parse(Convert.ToString(integer, 2));
after this line integerBinary is 101 because you have converted it from binary string representation "101" of 5. After that all integers operation are invalid as such 101 makes no sense.
this code has two problems
first
int integerBinary = int.Parse(Convert.ToString(integer, 2));
does not need, cause the input integer is can be directly used to do logic operation,
and this line does not mean convert integer to its binary format, after this line integer has become a different number
second
else Console.WriteLine("(n) After bit conversion = {0}", integer);
if value is 1 you still need to do some thing( if the original position is 0)
so the right code maybe
if (int.TryParse(integerLine, out integer) && int.TryParse(positionLine, out position) && int.TryParse(valueLine, out value)) // Try to parse the strings as integers
{
int mask= (1<< position);
int temp = mask | integer;
int mask2 = ~((1-value)<<position);
int result = mask2 & temp;
result = mask & result;
Console.WriteLine("(n) After bit conversion = {0}", result);
}
I have a list of values for example: G1, G2, G2.5, G3, G4, etc..) How can I check a range of these values in c# say if I wanted to see if value was between G1 and G2.5 ?
In Vb.net I can do:
Select Case selectedValue
Case "G1" To "G2.5" //This would be true for G1, G2, and G2.5
How can I do this in c#?
Remove the G from selectedValue
Parse the remaining into a decimal
Implement your logic against the decimal value
-
var number = decimal.Parse(selectedValue.Replace("G", ""));
if (number >= 1.0m && number <= 2.5m)
{
// logic here
}
To do string comparison, you could just do this
if (string.Compare(selectedValue, "G1") >= 0 && string.Compare(selectedValue, "G2.5") <= 0)
{
...
}
But to do numeric comparison, you'd have to parse it as a number (double or decimal)
var selectedValueWithoutG = selectedValue.Substring(1);
var number = decimal.Parse(selectedValueWithoutG);
if (number >= 1D && number <= 2.5D)
{
...
}
First you need to parse your value:
var number = decimal.Parse(selectedValue.Substring(1))
Then you can apply an extension method like this:
bool Between(this int value, int left, int right)
{
return value >= left && value <= right;
}
if(number.Between(1, 2.5)) {.....}
I would like to generate a code like goo.gl and jsfiddle websites (http://jsfiddle.net/XzKvP/).
I tried different things that give me too large of a guid, a repeating alphanumeric code, etc.
I'm thinking I should be able to generate an alphanumeric code based on the Primary Key in my database table. This way it will be non-repeating? The PK is an auto-incremented integer by 1. But not sure that's how it should be done.
I want the code to look random, but it does NOT have to be.
For example, I do NOT want item 1234 in my database to be BCDE and the 1235 item to be BCDF.
Examples:
Notice how the url http://jsfiddle.net/XzKvP/ has a unique 5 character code XzKvP associated to the page. I want to be able to generate the same type of code.
goo.gl does it too: http://goo.gl/UEhtg has UEhtg
How is this done?
The solutions based on a random substring are no good because the outputs will collide. It may happen prematurely (with bad luck), and it will eventually happen when the list of generated values grows large. It doesn't even have to be that large for the probability of collisions to become high (see birthday attack).
What's good for this problem is a pseudo random permutation between the incrementing ID and its counterpart that will be shown in the URL. This technique guarantees that a collision is impossible, while still generating into an output space that is as small as the input space.
Implementation
I suggest this C# version of a Feistel cipher with 32 bits blocks, 3 rounds and a round function that is inspired by pseudo-random generators.
private static double RoundFunction(uint input)
{
// Must be a function in the mathematical sense (x=y implies f(x)=f(y))
// but it doesn't have to be reversible.
// Must return a value between 0 and 1
return ((1369 * input + 150889) % 714025) / 714025.0;
}
private static uint PermuteId(uint id)
{
uint l1=(id>>16)&65535;
uint r1=id&65535;
uint l2, r2;
for (int i = 0; i < 3; i++)
{
l2 = r1;
r2 = l1 ^ (uint)(RoundFunction(r1) * 65535);
l1 = l2;
r1 = r2;
}
return ((r1 << 16) + l1);
}
To express the permuted ID in a base62 string:
private static string GenerateCode(uint id)
{
return ToBase62(PermuteId(id));
}
The Base62 function is the same as the previous answer except that is takes uint instead of int (otherwise these functions would have to be rewritten to deal with negative values).
Customizing the algorithm
RoundFunction is the secret sauce of the algorithm. You may change it to a non-public version, possibly including a secret key. The Feistel network has two very nice properties:
even if the supplied RoundFunction is not reversible, the algorithm guarantees that PermuteId() will be a permutation in the mathematical sense (wich implies zero collision).
changing the expression inside the round function even lightly will change drastically the list of final output values.
Beware that putting something too trivial in the round expression would ruin the pseudo-random effect, although it would still work in terms of uniqueness of each PermuteId output. Also, an expression that wouldn't be a function in the mathematical sense would be incompatible with the algorithm, so for instance anything involving random() is not allowed.
Reversability
In its current form, the PermuteId function is its own inverse, which means that:
PermuteId(PermuteId(id))==id
So given a short string produced by the program, if you convert it back to uint with a FromBase62 function, and give that as input to PermuteId(), that will return the corresponding initial ID. That's pretty cool if you don't have a database to store the [internal-ID / shortstring] relationships: they don't actually need to be stored!
Producing even shorter strings
The range of the above function is 32 bits, that is about 4 billion values from 0 to 2^32-1. To express that range in base62, 6 characters are needed.
With only 5 characters, we could hope to represent at most 62^5 values, which is a bit under 1 billion. Should the output string be limited to 5 characters, the code should be tweaked as follows:
find N such that N is even and 2^N is as high as possible but lower than 62^5. That's 28, so our real output range that fits in 62^5 is going to be 2^28 or about 268 million values.
in PermuteId, use 28/2=14 bits values for l1 and r1 instead of 16 bits, while being careful to not ignore a single bit of the input (which must be less than 2^28).
multiply the result of RoundFunction by 16383 instead of 65535, to stay within the 14 bits range.
at the end of PermuteId, recombine r1 and l1 to form a 14+14=28 bits value instead of 32.
The same method could be applied for 4 characters, with an output range of 2^22, or about 4 million values.
What does it look like
In the version above, the first 10 produced strings starting with id=1 are:
cZ6ahF
3t5mM
xGNPN
dxwUdS
ej9SyV
cmbVG3
cOlRkc
bfCPOX
JDr8Q
eg7iuA
If I make a trivial change in the round function, that becomes:
ey0LlY
ddy0ak
dDw3wm
bVuNbg
bKGX22
c0s5GZ
dfNMSp
ZySqE
cxKH4b
dNqMDA
You can think of the five-letter code as a number in base-62 notation: your "digits" are 26 lowercase and 26 uppercase letters, and digits from 0 to 9. (26+26+10) digits in total. Given a number from 0 to 62^5 (which equals 916132832) (say, your primary key) you can do the conversion to a five-digit base-62 as follows:
private static char Base62Digit(int d) {
if (d < 26) {
return (char)('a'+d);
} else if (d < 52) {
return (char)('A'+d-26);
} else if (d < 62) {
return (char)('0'+d-52);
} else {
throw new ArgumentException("d");
}
}
static string ToBase62(int n) {
var res = "";
while (n != 0) {
res = Base62Digit(n%62) + res;
n /= 62;
}
return res;
}
private static int Base62Decode(char c) {
if (c >= '0' && c <= '9') {
return 52 + c - '0';
} else if (c >= 'A' && c <= 'Z') {
return 26 + c - 'A';
} else if (c >= 'a' && c <= 'z') {
return c - 'a';
} else {
throw new ArgumentException("c");
}
}
static int FromBase62(string s) {
return s.Aggregate(0, (current, c) => current*62 + Base62Decode(c));
}
Here is how to generate cryptographically strong random numbers (you need to add a reference to System.Security):
private static readonly RNGCryptoServiceProvider crypto =
new RNGCryptoServiceProvider();
private static int NextRandom() {
var buf = new byte[4];
crypto.GetBytes(buf);
return buf.Aggregate(0, (p, v) => (p << 8) + v) & 0x3FFFFFFF;
}
This is what I ended up doing
(Updated since Daniel Vérité's answer):
class Program
{
private static double RoundFunction(uint input)
{
// Must be a function in the mathematical sense (x=y implies f(x)=f(y))
// but it doesn't have to be reversible.
// Must return a value between 0 and 1
return ((1369 * input + 150889) % 714025) / 714025.0;
}
private static char Base62Digit(uint d)
{
if (d < 26)
{
return (char)('a' + d);
}
else if (d < 52)
{
return (char)('A' + d - 26);
}
else if (d < 62)
{
return (char)('0' + d - 52);
}
else
{
throw new ArgumentException("d");
}
}
private static string ToBase62(uint n)
{
var res = "";
while (n != 0)
{
res = Base62Digit(n % 62) + res;
n /= 62;
}
return res;
}
private static uint PermuteId(uint id)
{
uint l1 = (id >> 16) & 65535;
uint r1 = id & 65535;
uint l2, r2;
for (int i = 0; i < 3; i++)
{
l2 = r1;
r2 = l1 ^ (uint)(RoundFunction(r1) * 65535);
l1 = l2;
r1 = r2;
}
return ((r1 << 16) + l1);
}
private static string GenerateCode(uint id)
{
return ToBase62(PermuteId(id));
}
static void Main(string[] args)
{
Console.WriteLine("testing...");
try
{
for (uint x = 1; x < 1000000; x += 1)
{
Console.Write(GenerateCode(x) + ",");
}
}
catch (Exception err)
{
Console.WriteLine("error: " + err.Message);
}
Console.WriteLine("");
Console.WriteLine("Press 'Enter' to continue...");
Console.Read();
}
}
I'm sure there must be a much better way of doing this. I'm trying to do a count operation on a Flags enum. Before I was itterating over all the possible values and counting the succesful AND operations.
e.g.
[Flags]
public enum Skills
{
None = 0,
Skill1 = 1,
Skill2 = 2,
Skill3 = 4,
Skill4 = 8,
Skill5 = 16,
Skill6 = 32,
Skill7 = 64,
Skill8 = 128
}
public static int Count(Skills skillsToCount)
{
Skills skill;
for (int i = 0; i < SkillSet.AllSkills.Count; i++)
{
skill = SkillSet.AllSkills[i];
if ((skillsToCount & skill) == skill && skill != Skills.None)
count++;
}
return count;
}
I'm sure there must be a better way of doing this though, but must be suffering from a mental block. Can anyone advise a nicer solution?
The following code will give you the number of bits that are set for a given number of any type varying in size from byte up to long.
public static int GetSetBitCount(long lValue)
{
int iCount = 0;
//Loop the value while there are still bits
while (lValue != 0)
{
//Remove the end bit
lValue = lValue & (lValue - 1);
//Increment the count
iCount++;
}
//Return the count
return iCount;
}
This code is very efficient as it only iterates once for each bit rather than once for every possible bit as in the other examples.
After looking on the site Assaf suggested I managed to find a slightly different solution that I got working for Int32's.
Here's the code for anyone else:
internal static UInt32 Count(this Skills skills)
{
UInt32 v = (UInt32)skills;
v = v - ((v >> 1) & 0x55555555); // reuse input as temporary
v = (v & 0x33333333) + ((v >> 2) & 0x33333333); // temp
UInt32 c = ((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24; // count
return c;
}
A very concise way to do it using BitArray and LINQ:
public static int Count(Skills skillsToCount)
{
return new BitArray(new[] {(int)skillsToCount}).OfType<bool>().Count(x => x);
}
If you're targeting .NET Core 3.0 or above, you can use BitOperations.PopCount(), it operates in uint or ulong and returns the number of 1 bits.
If your CPU supports SSE4, it'll use the POPCNT CPU instruction, otherwise it'll use a software fallback.
public static int Count(Skills skillsToCount)
{
return BitOperations.PopCount((ulong)skillsToCount);
}
The count is equivalent to counting how many bits are set to 1 in the integer value of the enum.
There are very fast ways of doing this in C/C++, which you can adapt to C#:
e.g.
int bitcount(unsigned int n) {
/* works for 32-bit numbers only */
/* fix last line for 64-bit numbers */
register unsigned int tmp;
tmp = n - ((n >> 1) & 033333333333)
- ((n >> 2) & 011111111111);
return ((tmp + (tmp >> 3)) & 030707070707) % 63;
}
Taken from here.
EDIT
Provided link is dead. Found another one that probably contains the same content.
There's a straight-forward way using functional programming (LINQ):
var skillCount = Enum
.GetValues(typeof(Skills))
.Cast<Enum>()
.Count(skills.HasFlag);
It might be a bit slower than the bit-juggling solutions but it has a constant run-time and is more intuitive.
While GetValues still allocates, there is a good chance that the compiler optimizes this away.
<FlagsAttribute()> _
Public Enum Skills As Byte
None = 0
Skill1 = 1
Skill2 = 2
Skill3 = 4
Skill4 = 8
Skill5 = 16
Skill6 = 32
Skill7 = 64
Skill8 = 128
End Enum
Dim x As Byte = Skills.Skill4 Or Skills.Skill8 Or Skills.Skill6
Dim count As Integer
If x = Skills.None Then count = 0 Else _
count = CType(x, Skills).ToString().Split(New Char() {","c}, StringSplitOptions.RemoveEmptyEntries).Count
depends on the definition of "better".
the check for Skills.None is required because if no bits are on, the string() returns Skills.None which results in a count of 1. this would work the same for integer, long, and their unsigned relatives.
the only reason to use this method is if the flags are not contiguous and if flags will be added periodically.
<FlagsAttribute()> _
Public Enum Skills As Integer
Skill1 = CInt(2 ^ 0) 'bit 0
Skill2 = CInt(2 ^ 1)
Skill3 = CInt(2 ^ 2)
Skill4 = CInt(2 ^ 3)
Skill5 = CInt(2 ^ 4)
Skill6 = CInt(2 ^ 5)
Skill7 = CInt(2 ^ 6)
Skill8 = CInt(2 ^ 7)
Skillx = CInt(2 ^ 10) 'bit 10, some bits were skipped
End Enum
Dim mySkills As Integer = Skills.Skillx Or Skills.Skill4 Or Skills.Skill8 Or Skills.Skill6
Dim count As Integer 'count of bits on
count = CType(mySkills, Skills).ToString().Split(New Char() {","c}, _
StringSplitOptions.RemoveEmptyEntries).Count
if "better" means faster this ain't ;) it.
int count = Enum.GetValues(typeof(Skills)).Length;