Check range of string values that contains a number - c#

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)) {.....}

Related

Finding the largest possible number in permutations of digits less than a limit

I want to permute the digits of an int in a way that the result is the biggest possible permutation. This is easily done like this:
//how to deal with really large ints e.g.int32.MaxValue goes here
// in this case the algorithm would need to round down to the largest possible value
// but still needs to be less than int32.MaxValue
//This code will just handle normal values <int32.MaxValue
public static int Max(int number)
{
var numberAsCharArray = number.ToString().OrderByDescending(c => c).ToArray();
var largestNumberAsString = new string(numberAsCharArray);
return Int32.Parse(largestNumberAsString);
}
However, when the input has the same number of digits as Int32.MaxValue and contains at least one high digit, this digit will go to the first position making the result > Int32.MaxValue and leading to an exception when converting to int.
How could I limit the result to be <= Int32.MaxValue but within this limit still be the greatest possible permutation?
N.B. Negative numbers, e.g. -1234567890 are allowed as well as positive ones; in case of negative input, - sign should be dropped: -1234567890 should produce 2147398650 output
For small numbers (less or equal to 1000000000) you can do the business as usual; for numbers greater than one billion
you can try the follow approach:
Try follow int.MaxValue pattern (2147483647) as long as it's possible
When it's not possible, put the maximum number you can do and continue doing the business as usual for the remaining digits.
For instance, given 1234567890
1234567890 <- initial value
2147483647 <- int.MaxValue pattern
2147398650 <- solution
^
|
Here we can't put another 4, we put maximum available - 3
Remaining digits [56890] we order by descending - "98650" - business as usual
Implementation
private static int Biggest(int value) {
// Special MinValue case;
// we can't do Math.Abs() because of integer overflow
if (value == int.MinValue)
return 2147483486;
string st = value.ToString().Trim('-');
if (value <= 1000000000 && value >= -1000000000)
return int.Parse(string.Concat(st.OrderByDescending(c => c)));
string max = int.MaxValue.ToString();
List<int> digits = st.Select(c => c - '0').ToList();
StringBuilder sb = new StringBuilder(9);
bool exact = true;
while (digits.Any()) {
for (int i = 0; i < max.Length; ++i) {
int digitToFind = max[i] - '0';
int digitActual;
digitActual = digits
.Where(d => !exact || d <= digitToFind)
.OrderByDescending(d => d)
.First();
if (exact)
exact = digitActual == digitToFind;
sb.Append(digitActual);
digits.Remove(digitActual);
}
}
return int.Parse(sb.ToString());
}
Test:
// 2147398650 (for reference: int.MaxValue == 2147483647)
Console.WriteLine(Biggest(1234567890));
I suggest this:
int number = 587;
int maximum = Int32.MaxValue;
var result = "";
if(number == Int32.MinValue)
{
result = "2147483486";
}
else
{
// create list of available digits removing - sign from the string
var inputDigits = number.ToString().Replace("-", String.Empty).Select(c => Int32.Parse(new string(c, 1))).ToList();
var limitDigits = maximum.ToString().Select(c => Int32.Parse(new string(c, 1))).ToList();
var orderedDigits = inputDigits.OrderByDescending(c => c).ToList();
int position = 0;
// we only have to compare to the maximum if we have at least the same amount of digits in the input.
bool compareValues = limitDigits.Count <= inputDigits.Count;
// while we have not used all of the digits
while (orderedDigits.Count > 0)
{
// loop over the remaining digits from high to low values
for (int i = 0; i < orderedDigits.Count; i++)
{
// if it is above the digit in the maximum at the corresponding place we may only use it if input is shorter than maximum or if we have already used a lower value in a previous digit.
if (orderedDigits[i] > limitDigits[position])
{
if (compareValues)
{
continue;
}
}
else if (orderedDigits[i] < limitDigits[position])
{
// remember that we have already used a lower value
compareValues = false;
}
result += (orderedDigits[i].ToString());
orderedDigits.RemoveAt(i);
break;
}
position++;
}
}
var intResult = Int32.Parse(result);
EDIT:
inserted .Replace("-", String.Empty) when defining inputDigits to support negative numbers

Sorting a list of strings that contains hex value

I have a list of strings type that contains hex values, and the values are not the same length. hence the List can have FA1 and FA and F9F as values in the list, depends on user input, I was wondering what is the best way to sort this.
so the problem is the order of this list after sorted will be FA1,FA,F9F when it should be FA1,F9F,FA.
You may sort the list and pass a custom comparison function, see http://msdn.microsoft.com/en-us/library/3da4abas.aspx
That function can convert hex strings to regular integers and compare these integers. Conversion can be done with help of Convert.ToInt32:
int n = Convert.ToInt32("FF1", 16);
see http://msdn.microsoft.com/en-us/library/1k20k614.aspx
Could be something like this:
list.Sort(delegate(string lhs, string rhs)
{
int n = Convert.ToInt32(lhs, 16);
int m = Convert.ToInt32(rhs, 16);
return (n > m) ? -1 : (n < m) ? +1 : 0;
});
or (see #AlexR's remark) just
list.Sort(delegate(string lhs, string rhs)
{
return Convert.ToInt32(rhs, 16) - Convert.ToInt32(lhs, 16);
});
Thanks to #AlexR I used this code to solve the Problem.
ListOfString.Sort(delegate(string temp1, string temp2)
{
if (temp1.Length > temp2.Length) return 1;
else if (temp1.Length < temp2.Length) return -1;
return temp1.CompareTo(temp2);
});
if you want it to be descending simply do this
ListOfString.Sort(delegate(string temp1, string temp2)
{
if (temp1.Length < temp2.Length) return 1;
else if (temp1.Length > temp2.Length) return -1;
return temp1.CompareTo(temp2) * -1;
});
Complementary to my comment, a comparison code would look like this:
int compare(string a, string b) {
if (a.StartsWith("0")) // Short circuit if RegEx won't do anything
a = Regex.Replace(a, "^0+", ""); // RegEx replacement of all leading 0's by ""
if (b.StartsWith("0"))
b = Regex.Replace(b, "^0+", "");
if (a.Length != b.Length)
return a.Length - b.Length; // < 0 for a < b, > 0 for a > b
else
return a.CompareTo(b);
}
Please don't bite me on syntax, I haven't coded in C# for a while since at work we use Java.

Converting decimal number to hexadecimal number using recursive method

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());
}

Format a double value to fit into a maximum string size

I need to format a double value so that it fits within a field of 13 characters. Is there a way to do this with String.Format or am I stuck with character-by-character work?
Edits: (hopefully they will stay this time)
With cases greater than a trillion I am to report an error. It's basically a calculator interface.
My own answer:
private void DisplayValue(double a_value)
{
String displayText = String.Format("{0:0." + "".PadRight(_maxLength, '#') + "}", a_value);
if (displayText.Length > _maxLength)
{
var decimalIndex = displayText.IndexOf('.');
if (decimalIndex >= _maxLength || decimalIndex < 0)
{
Error();
return;
}
var match = Regex.Match(displayText, #"^-?(?<digits>\d*)\.\d*$");
if (!match.Success)
{
Error();
return;
}
var extra = 1;
if (a_value < 0)
extra = 2;
var digitsLength = match.Groups["digits"].Value.Length;
var places = (_maxLength - extra) - digitsLength;
a_value = Math.Round(a_value, places);
displayText = String.Format("{0:0." + "".PadRight(_maxLength, '#') + "}", a_value);
if (displayText.Length > _maxLength)
{
Error();
return;
}
}
DisplayText = displayText;
}
If this is calculator, then you can not use character-by-character method you mention in your question. You must round number to needed decimal places first and only then display it otherwise you could get wrong result. For example, number 1.99999 trimmed to length of 4 would be 1.99, but result 2 would be more correct.
Following code will do what you need:
int maxLength = 3;
double number = 1.96;
string output = null;
int decimalPlaces = maxLength - 2; //because every decimal contains at least "0."
bool isError = true;
while (isError && decimalPlaces >= 0)
{
output = Math.Round(number, decimalPlaces).ToString();
isError = output.Length > maxLength;
decimalPlaces--;
}
if (isError)
{
//handle error
}
else
{
//we got result
Debug.Write(output);
}
You have a lot formatting options using String.Format, just specify format after placeholder like this {0:format}.
Complete example looks like this:
Console.WriteLine("Your account balance is {0:N2}.", value);
Output would be:
Your account balance is 15.34.
All of the options for numeric types are listed here:
http://msdn.microsoft.com/en-us/library/dwhawy9k(v=vs.110).aspx
This seems to work for me (but is hand-rolled):
static string FormatDouble(double d)
{
int maxLen = 13;
double threshold = Math.Pow(10, maxLen);
if (d >= threshold || d <= 0 - (threshold/10))
return "OVERFLOW";
string strDisplay = "" + d;
if (strDisplay.Length > maxLen )
strDisplay = strDisplay.Substring(0, maxLen);
if (strDisplay.EndsWith("."))
strDisplay = strDisplay.Replace(".", "");
return strDisplay;
}
Let me know if it gives you trouble with scientific notation creeping in. I believe the format "{0:R}" should help you avoid that explicitly.
Also, I wasn't sure if you were including +/- sign in digit count or if that was in a separate UI slot.
The theory on rounding here is that, yes, "" + d might round some things, but in general it's going to be many more digits out than are ever displayed so it shouldn't matter. So this method should always truncate.
Here's a solution that does rounding. (I couldn't think of a non-mathematical way to do it):
static string FormatDouble(double d)
{
int maxLen = 13;
int places = (int)Math.Max(Math.Log10(Math.Abs(d)), 0);
places += (d == Math.Abs(d) ? 1 : 2);
if (places > maxLen || places < 1 - maxLen)
return "OVERFLOW";
if (Math.Floor(d) == d) ++places; // no decimal means one extra spot
d = Math.Round(d, Math.Max(maxLen - places - 1, 0));
return string.Format("{0:R}", d);
}
Note: I still think your users might appreciate seeing something closer to what is being stored in the underlying memory than what is often typical of calculators. (I especially hate the ones that can turn 0.99 into 1.01) Either way, you've got at least 3 solutions now so it's up to you.

C# how to check same sign of 2 decimal values using bit?

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.

Categories

Resources