In C#, I have a situation where I have two possible numbers in a textbox control.
The numbers can be either:
a) .xxxx
or
b) .xx
How do I write a condition that says, "If the textbox has 4 decimal places, then call this function, otherwise, if the textbox has 2 decimal places, then call this function."
Seems easy, but I don't know how to evaluate the decimal places.
Thanks much!
You can use Regex
new Regex(@"\.\d{2}$").IsMatch(input.Value)
if(txtNumber.Text.Split(new[]{'.'})[1].Length == 2)
{
//case b
}
else
{
//case a
}
you may want to take the decimal separator from the system's current culture instead of hardcoding the dot.
You could take advantage of a very obscure feature of the Decimal type. Its internal representation is a 96-bit number with an exponent. The exponent is equal to the number of digits in the fraction, even if the fractional digits are zero. Thus:
public static int GetFractionalDigits(string txt) {
decimal value = decimal.Parse(txt);
return (decimal.GetBits(value)[3] >> 16) & 0x7fff;
}
Use decimal.TryParse() if you need to validate the user input.
Condition will evaluate true
on two but not four decimal places:
Math.Round( 100*x ) == 100*x
EDIT: above condition works only for Decimal type. Well, following works for real numbers of all types:
( Math.Ceiling( 100 * x ) - 100 * x ) < 10e-8 )
EDIT: Well, if you are interested in strings then use following (extension string contains last point and subsequent digits/numbers):
System.IO.Path.GetExtension( input ).Length
This may not work perfectly depending on your needs, but it works for my purposes and could be useful to someone else.
static class MathCustom
{
static public byte NumberOfDecimals(decimal value)
{
sbyte places = -1;
decimal testValue;
do
{
places++;
testValue = Math.Round(value, places);
} while (testValue != value);
return (byte)places;
}
static public byte NumberOfDecimals(float value)
{
sbyte places = -1;
float testValue;
do
{
places++;
testValue = (float)Math.Round((decimal)value, places);
} while (testValue != value);
return (byte)places;
}
/// <summary>
/// This version of NumberOfDecimals allows you to provide a Maximum
/// for allowable decimals. This method will allow for the correction
/// of floating point errors when it is less than 10 or passed in as null.
/// </summary>
/// <param name="value">Value to check the number of held decimal places</param>
/// <param name="knownMaximum"></param>
/// <returns>The number of decimal places in Value.</returns>
static public byte NumberOfDecimals(decimal value, byte? knownMaximum)
{
byte maximum;
decimal localValue;
sbyte places = -1;
decimal testValue;
if (knownMaximum == null)
{
maximum = 9;
}
else
{
maximum = (byte)knownMaximum;
}
localValue = Math.Round(value, maximum);
do
{
places++;
testValue = Math.Round(localValue, places);
} while (testValue != localValue);
return (byte)places;
}
}