C#: Min to max number of digits after a decimal - c#

I'm trying to do a check for a user input for the rate entered, I want to accept the value entered if it has min 2 digits to a max of 5 digits after the decimal.
Valid Example:
*1.12
*1.123
*1.1234
*1.12345
Not Valid:
1
1.1
1.123456
etc.
I've been trying to get it with Regex but right now it only allows only 5 digits after the decimal nothing less nothing more. Here's the code:
//Check if the string is a double
bool IsDouble(string s)
{
var regex = new Regex(#"^\d+\.\d{5}?$");
var check = regex.IsMatch(s);
return check;
}
A little help would be greatly appreciated.

This should do it:
^\d+\.\d{2,5}$

Use the pattern
"^\d+\.\d{2,5}?$"
to match between 2 and 5 characters

Try this Regex
you can specify your own range here d{2,5}
^\s*-?[1-9]\d*(\.\d{2,5})?\s*$
(Or)
^(\d{1,5}|\d{0,5}\.\d{2,5})$
REGEX DEMO

A non-regex solution
It also returns the decimal
public int? DecimalAfter (string strDec, out decimal? decNull)
{
int? decAfter = null;
strDec = strDec.Trim();
decimal dec;
if (decimal.TryParse(strDec, out dec))
{
decNull = dec;
int decPos = strDec.IndexOf('.');
if (decPos == -1)
{
decAfter = 0;
}
else
{
decAfter = strDec.Length - decPos - 1;
}
}
else decNull = null;
return decAfter;
}

Related

I need to check if each digit from an integer is even or odd in c# an return even or odd

I'm new to c# language and still learning. I have to write a console application (like example) but the real problem for me is that I don't know how to access each number for the input integer and pass it on the division function (n % 2 ==0) and return even/odd for the given number.
For example:
the user input: 4444
and the console result: even
even
even
even
string inputData = Console.ReadLine(); // the 4 digit number
int number = Convert.ToInt32(inputData);
string emptyStr = String.Empty;
string divided = "even";
string notDivided = "odd";
// here .......????
if (number % 2 == 0)
{
Console.WriteLine(divided);
}
else
{
Console.WriteLine(notDivided);
}
I think this is what you are looking for.
First of all use this
Is there an easy way to turn an int into an array of ints of each digit?
After that just check every individual item in your array
public void main
{
var numbers = NumbersIn(987654321).ToArray();
foreach (int element in numbers)
{
if (element % 2 == 0)
{
Console.Write("even");
}
else
{
Console.Write("uneven");
}
}
}
public Stack<int> NumbersIn(int value)
{
if (value == 0) return new Stack<int>();
var numbers = NumbersIn(value / 10);
numbers.Push(value % 10);
return numbers;
}
https://learn.microsoft.com/en-us/dotnet/api/system.console.readline?view=netcore-3.1 you can use the hyperlink provided to use the method Console.ReadLine method for the conditional output that you are C#-ing.
You can read each key written by user in loop with:
var digit = Console.ReadKey()
Remember to parse char to int properly.
As Mong Zhu noticed, you cannot parse char value with: Int32.Parse('1'). You have to do it with string value.
So full solution is:
var digitStr = Console.ReadKey();
var digit = Int32.Parse(digitStr.KeyChar.ToString());

How to find out a String is an non-digit Integer number?

I need to found out if a given String is a pure Integer number, that means it is no double and no float .
What I have tried is a regular expression:
#"^\d+$"
if (Regex.IsMatch(oStreamDataValues[i].ToString(), #"^\d+$") == false)
That works fine but only until a String contains a number like 0.00 or any other digit value.
You can use the TryParse method:
int value;
if(int.TryParse(myString, out value)) {
// it is an integer
}
Why not just try to parse it using int.TryParse:
string s = "-12";
int i;
bool isInt = int.TryParse(s, out i);
If you also want to parse 0.00:
bool isInt;
decimal d;
if (decimal.TryParse(s, out d))
{
if (d % 1 == 0)
{
isInt = true;
}
else
{
isInt = false;
}
}
else
{
isInt = false;
}
As I can see, some floating point values are positive examples in your case
4.00 // <- just 4
1e3 // <- is 1000
1e100 // <- 10...0 (100 zeros)
So I suggest parsing it into Double, and then test if fractional part is 0:
String s = "123.0";
Double v;
if (Double.TryParse(s, NumberStyles.Any, CultureInfo.InvariantCulture, out v))
if ((v - Math.Truncate(v)) < Math.Abs(v) / 1.0e20) //TODO: Adjast tolerance here
Console.Write("this is an integer value");
I personnaly would use Int32 static methods to parse the String.
There is TryParse and Parse (depends if you want to use a try/catch or not).
int returnedNumber = 0;
if(!Int32.TryParse(oStreamDataValues[i].ToString(), out returnedNumber)) {
//enter code here
}
or
bool isInt = true;
int returnedNumber = 0;
try {
returnedNumber = Int32.Parse(oStreamDataValues[i].ToString());
}
catch(FormatException) {
isInt = false;
}
if(!isInt) {
//enter code here
}
Parse method uses the following format :
The s parameter contains a number of the form:
[ws][sign]digits[ws]
Items in square brackets ([ and ]) are optional. The following table describes each element.
ws Optional white space.
sign An optional sign.
digits A sequence of digits ranging from 0 to 9.
References :
Parse : https://msdn.microsoft.com/en-us/library/b3h1hf19%28v=vs.110%29.aspx
TryParse : https://msdn.microsoft.com/en-us/library/f02979c7%28v=vs.110%29.aspx

How to format floating point value with fix number of digits?

Is it possible in C# to format a double value with double.ToString in a way that I have always a fixed number of digits, no matter on which side of the decimal point?
Say I wish 6 digits, I want to have these results:
0.00123456789 gives "0.00123"
1.23456789 gives "1.23457"
123.456789 gives "123.457"
0.0000000123456789 gives "0.00000"
12345678.9 gives "12345679" (on overflow I want to see all digits left of decimalpoint)
4.2 gives "4.20000"
I'm experimenting with double.ToString, but cannot find any suitable format string.
Already tried "G6" (gives sometimes exponential format), "F6" (comes close, but 0.123456789 gives "0.123457" which are 7 digits).
I think some of your examples are wrong.
But I still think that I understand what you want to achieve.
I made an extension method.
public static class StringExtensionMethods
{
public static string ToString(this double d, int numberOfDigits)
{
var result = "";
// Split the number.
// Delimiter can vary depending on locale, should consider this and not use "."
string[] split = d.ToString().Split(new string[] { "." }, StringSplitOptions.None);
if(split[0].Count() >= numberOfDigits)
{
result = split[0].Substring(0, numberOfDigits);
}
else
{
result = split[0];
result += ".";
result += split[1];
// Add padding.
while(result.Count() < numberOfDigits +1)
result += "0";
result = result.Substring(0, numberOfDigits + 1);
}
return result;
}
}
I ran it with your examples:
double d0 = 0.00123456789;
double d1 = 1.23456789;
double d2 = 123.456789;
double d3 = 0.0000000123456789;
double d4 = 12345678.9;
double d5 = 4.2;
Console.WriteLine(d0.ToString(6));
Console.WriteLine(d1.ToString(6));
Console.WriteLine(d2.ToString(6));
Console.WriteLine(d3.ToString(6));
Console.WriteLine(d4.ToString(6));
Console.WriteLine(d5.ToString(6));
This is the output:
0.00123
1.23456
123.456
1.23456
123456
4.20000
I don't think this is the best way to solve it, but I like extension methods.
DoubleConverter class: http://1drv.ms/1yEbvL4
If your goal is to avoid "jumping" of the decimal point:
Use g formating, this does the most sensible thing to do
See where the decimal point is in your resulting string
pad with spaces at the beginning to align the column at the decimal point
As I understand, there is no predefined format that does what I need. So for everyone who is interested, here is the function I ended up with:
public string FormatValue(double d, int noOfDigits)
{
double abs = Math.Abs(d);
int left = abs < 1 ? 1 : (int)(Math.Log10(abs) + 1);
int usedDigits = 0;
StringBuilder sb = new StringBuilder();
for(; usedDigits < left; usedDigits++)
{
sb.Append("0");
}
if(usedDigits < noOfDigits)
{
sb.Append(".");
for(; usedDigits < noOfDigits; usedDigits++)
{
sb.Append("0");
}
}
return d.ToString(sb.ToString());
}

Break decimal value into two values (before and after decimal)

How to break a decimal value into integer values, first value should be the value before decimal and the other value of after decimal.
Problem : Decimal place is unknown as well as the number of digits;
ex :
double value = 2635.215;
int firstValue = 2635; // Should be
int secondValue = 215; // Should be
A possible solution:
using System.Globalization;
namespace DecimalSplit
{
class Program
{
static void Main(string[] args)
{
double value = 2635.215;
var values = value.ToString(CultureInfo.InvariantCulture).Split('.');
int firstValue = int.Parse(values[0]);
int secondValue = int.Parse(values[1]);
}
}
}
Using CultureInfo.InvariantCulture when converting to String will ensure that the decimal separator will be a . and the split will be done in the right place. In my culture the decimal separator was a , for example
You can use String.Split method for splitting a string. Convert double to string and then split it based on .
This problem is unsolvable, because a double value can have an extremely large number of decimal digits, so you cannot guarantee to be able to represent them in an integer. The closest I can give you is this, which works not with integers, but with doubles:
double left = System.Math.Floor(value);
double right = left - value;
Here is a little improvment of Răzvan Panda example.
An exception was raised in int secondValue = int.Parse(values[1]); if we parse a value with no decimal.
Another point is that it's better to have a string for the second value. See, example 3.
static void Main(string[] args)
{
double val1 = 2635.215;
Console.Out.WriteLine(GetFirstValue(val1)); // out 2635
Console.Out.WriteLine(GetSecondValue(val1)); // out 215
double val2 = 2;
Console.Out.WriteLine(GetFirstValue(val2)); // out 2
Console.Out.WriteLine(GetSecondValue(val2)); // out ''
double val3 = 3.04;
Console.Out.WriteLine(GetFirstValue(val3)); // out 3
Console.Out.WriteLine(GetSecondValue(val3)); // out 04
}
public static string GetFirstValue(double value)
{
var values = value.ToString(CultureInfo.InvariantCulture).Split('.');
return values[0];
}
public static string GetSecondValue(double value)
{
var values = value.ToString(CultureInfo.InvariantCulture).Split('.');
return values.Length > 1 ? values[1] : string.Empty;
}
try:
double value = 2635.215;
string a = value.ToString();
string[] b =a.Split('.');
int firstValue= int.Parse(b[0]);
int secondValue= int.Parse(b[1]);
You could do:
double decimalNumber = 123.456;
var numbersBeforeDecimalPoint = Math.Truncate(decimalNumber);
var numbersAfterDecimalPoint = decimalNumber - numbersBeforeDecimalPoint;
Using Math.Truncate we can get only the whole numbers, and we can then use that in tandem with our original number to get the decimal part.
This would give you 123 and 0.456 as a result.
Not sure if that's exactly what you're after (I appreciate you might want 123 and 456) - there are lots of good suggestions here for string manipulations to do it if you need more specific formatting.

How to determine if a decimal/double is an integer?

How do I tell if a decimal or double value is an integer?
For example:
decimal d = 5.0; // Would be true
decimal f = 5.5; // Would be false
or
double d = 5.0; // Would be true
double f = 5.5; // Would be false
The reason I would like to know this is so that I can determine programmatically if I want to output the value using .ToString("N0") or .ToString("N2"). If there is no decimal point value, then I don't want to show that.
For floating point numbers, n % 1 == 0 is typically the way to check if there is anything past the decimal point.
public static void Main (string[] args)
{
decimal d = 3.1M;
Console.WriteLine((d % 1) == 0);
d = 3.0M;
Console.WriteLine((d % 1) == 0);
}
Output:
False
True
Update: As #Adrian Lopez mentioned below, comparison with a small value epsilon will discard floating-point computation mis-calculations. Since the question is about double values, below will be a more floating-point calculation proof answer:
Math.Abs(d % 1) <= (Double.Epsilon * 100)
There are any number of ways to do this. For example:
double d = 5.0;
bool isInt = d == (int)d;
You can also use modulo.
double d = 5.0;
bool isInt = d % 1 == 0;
How about this?
public static bool IsInteger(double number) {
return number == Math.Truncate(number);
}
Same code for decimal.
Mark Byers made a good point, actually: this may not be what you really want. If what you really care about is whether a number rounded to the nearest two decimal places is an integer, you could do this instead:
public static bool IsNearlyInteger(double number) {
return Math.Round(number, 2) == Math.Round(number);
}
Whilst the solutions proposed appear to work for simple examples, doing this in general is a bad idea. A number might not be exactly an integer but when you try to format it, it's close enough to an integer that you get 1.000000. This can happen if you do a calculation that in theory should give exactly 1, but in practice gives a number very close to but not exactly equal to one due to rounding errors.
Instead, format it first and if your string ends in a period followed by zeros then strip them. There are also some formats that you can use that strip trailing zeros automatically. This might be good enough for your purpose.
double d = 1.0002;
Console.WriteLine(d.ToString("0.##"));
d = 1.02;
Console.WriteLine(d.ToString("0.##"));
Output:
1
1.02
bool IsInteger(double num) {
if (ceil(num) == num && floor(num) == num)
return true;
else
return false;
}
Problemo solvo.
Edit: Pwned by Mark Rushakoff.
static bool IsWholeNumber(double x)
{
return Math.Abs(x % 1) < double.Epsilon;
}
Mark Rushakoff's answer may be simpler, but the following also work and may be more efficient since there is no implicit division operation:
bool isInteger = (double)((int)f) == f ;
and
bool isInteger = (decimal)((int)d) == d ;
If you want a single expression for both types, perhaps
bool isInteger = (double)((int)val) == (double)val ;
.NET 7 now has built-in methods for this:
decimal.IsInteger: https://learn.microsoft.com/en-us/dotnet/api/system.decimal.isinteger?view=net-7.0
double.IsInteger: https://learn.microsoft.com/en-us/dotnet/api/system.double.isinteger?view=net-7.0
You can check out the source code at:
https://github.com/dotnet/runtime/blob/main/src/libraries/System.Private.CoreLib/src/System/Decimal.cs
https://github.com/dotnet/runtime/blob/main/src/libraries/System.Private.CoreLib/src/System/Double.cs
If upper and lower bound of Int32 matters:
public bool IsInt32(double value)
{
return value >= int.MinValue && value <= int.MaxValue && value == (int)value;
}
You can use String formatting for the double type. Here is an example:
double val = 58.6547;
String.Format("{0:0.##}", val);
//Output: "58.65"
double val = 58.6;
String.Format("{0:0.##}", val);
//Output: "58.6"
double val = 58.0;
String.Format("{0:0.##}", val);
//Output: "58"
Let me know if this doesn't help.
public static bool isInteger(decimal n)
{
return n - (Int64)n == 0;
}
I faced a similar situation, but where the value is a string. The user types in a value that's supposed to be a dollar amount, so I want to validate that it's numeric and has at most two decimal places.
Here's my code to return true if the string "s" represents a numeric with at most two decimal places, and false otherwise. It avoids any problems that would result from the imprecision of floating-point values.
try
{
// must be numeric value
double d = double.Parse(s);
// max of two decimal places
if (s.IndexOf(".") >= 0)
{
if (s.Length > s.IndexOf(".") + 3)
return false;
}
return true;
catch
{
return false;
}
I discuss this in more detail at http://progblog10.blogspot.com/2011/04/determining-whether-numeric-value-has.html.
Using int.TryParse will yield these results:
var shouldBeInt = 3;
var shouldntBeInt = 3.1415;
var iDontWantThisToBeInt = 3.000f;
Console.WriteLine(int.TryParse(shouldBeInt.ToString(), out int parser)); // true
Console.WriteLine(int.TryParse(shouldntBeInt.ToString(), out parser)); // false
Console.WriteLine(int.TryParse(iDontWantThisToBeInt.ToString(), out parser)); // true, even if I don't want this to be int
Console.WriteLine(int.TryParse("3.1415", out parser)); // false
Console.WriteLine(int.TryParse("3.0000", out parser)); // false
Console.WriteLine(int.TryParse("3", out parser)); // true
Console.ReadKey();
You can simply compare the double against the int cast of the same value.
double d = 5.0m;
if (d == (int)d)
{
....
}
This is my solution to this problem. Maybe someone will useful.
public static bool IsInt(object number, int? decimalPlaces = null)
{
bool isInt;
var splinted = number.ToString().Split(',');
if (splinted.Length == 1)
isInt = true;
else
{
var charsAfterComma = decimalPlaces != null ? splinted[1].Substring(0, (int) decimalPlaces) : splinted[1];
isInt = charsAfterComma.First().ToString() == "0" && charsAfterComma.Replace("0", "") == "";
}
return isInt;
}
Try this:
number == Convert.ToInt16(number);
Perhaps not the most elegant solution but it works if you are not too picky!
bool IsInteger(double num) {
return !num.ToString("0.################").Contains(".");
}

Categories