Restrict value on decimal TryParse - c#

I have following code:
Decimal.TryParse("1.0e-50", NumberStyles.Float,CultureInfo.CurrentCulture.NumberFormat, out val)
I want to restrict it to e-45. Is there a way to do this without using regular expressions? I googled it but only best way i got was regex.

You should really just parse it as a decimal without bounds checking it, and then check the min/max values after you've parsed it into a numeric value. Trying to do the bounds checking on the string, before parsing it, is just asking for trouble; it'll be way more work, and more error prone.

Parse the value first and just compare it with a min/max value afterwards because there is no better way than regex to check how big the decimal value contained by the string is. All in all, parsing is much cleaner, efficient and I also would guess that it is faster.

Related

How to use string format to omit period but leave digits

I have the format string ######.00 used for formatting decimals in C#. I need to change it so that it omits the period but keeps the digits following the period. Can I accomplish this just by changing the format? I've searched, but haven't been able to find a solution online.
I found this answer to a very similar question, but it involves multiplying the decimal by 100 before formatting it. I'm not able to manipulate the number going in, nor the resulting string because I don't have access to them. This is because we're using a function from a third-party library that fetches the number from elsewhere and displays it formatted to the UI. I can only provide it with a format string. (If manipulating the number or resulting string is the only way to get it in the format we can probably do it, it would just take a good deal of refactoring, so I wanted to see if there's a simpler solution first. Hence the constraints.)
Just as an example of the output I'm looking for, consider the following code:
var myFormat = "{0:######.00}";
Console.WriteLine(string.Format(myFormat, 1234.1234));
Console.WriteLine(string.Format(myFormat, 5));
The code above currently outputs 1234.12 and 5.00, but I would like it to output 123412 and 500 just by changing myFormat. Is there a way to do this?
If only the format string is what you can change, there's probably no way to remove the dot.
However, you can implement your own Formatter, as MSDN's example.
string.Format(new CustomerFormatter(), "{0}", 1234.1234)

Sprache: parse signed integer

I wonder if there is a better way to parse signed integer using Sprache parser framework.
There is well known parser definition for integers without sign
Parse.Number.Select(int.Parse)
But I want to parse integers with - prefix as well.
What I have got right now is Parse.Regex(#"\-?\d+").Select(int.Parse).
Is there a better way to do that without using regular expressions?
For example use Parse.Char('-').Optional() and then parse following number.
Thanks
The way I do this is similar to the following:
from op in Parse.Optional(Parse.Char('-').Token())
from num in Parse.Decimal
from trailingSpaces in Parse.Char(' ').Many()
select decimal.Parse(num) * (op.IsDefined ? -1 : 1);
Of course, leave out the trailingSpaces portion depending on the context of what you're parsing.

string to double validation c# please answer

ok so I am building a program in WPF format.
as you know wpf's inputs are usually string, to turn those into double first I need to validate if those string fit and then to proceed and convert them.
the problem is in the validation, I have done the part in the validation that is checking if the string.IsNullOrEmpty but the thing I could not do is validate if the answer is completely not convertable... let me show an example because some strings that are not completely numeric are still should be accepted for example:
"sadasdaasd" - not accepted (obviously)
"8945a4554" - not accepted (there is an 'a' in the middle)
"3519" - accepted
"12.55" - accepted
"-3/4" - accepted and the value should be converted to double as (-3) divided by (4). so '/' is accepted and it splits the string by 2 and then converts it to double as first part/ second part.
I have been trying to do this validation all day and still have not succeeded, I have tried searching the web for some input validation, some said that I need to use double.TryParse(string, out double) but this function does not work with the '/' split that i wanted. so please help me!!!
I would start by parsing your string via regex (q: is "-3*4" acceptable as -3 times 4?). Basically you're looking for a match on a regex which is kind of like this (this works on -3/4, you'd want to test it further and modify if multiplication is allowed): -?\d+[/]\d+
If you find that match, parse out your string with string.Split('/') which will give you an array of strings. TryParse each of those and do the math.
If there is not a match, use TryParse (as recommended previously). That will either succeed (3519, 12.55 in your examples) or fail (sadasdaasd, 8945a4554 in your examples).
Note: you could also use string.Contains('/'), but then you have to check to see if it holds more than one slash (unless such a thing is allowed- in which case you'll need to revisit that regex).

How to safely and correctly convert a number from user input to double?

This is, basically, a CultureInfo problem. Formally, in my country, the decimal separator is a comma (,) and a thousands separator is a dot (.). In practice, however, this is only used by accountants and diligent people. Normally people never use a thousands separator, and they use both a comma and a dot interchangeably as a decimal separator. I've seen this being the problem even in some Excel spreadsheets that I received from other people, with Excel not having recognized a dot as a decimal separator, leaving the field formatted as a string, rather than a number.
My "solution" thus far has been to simply replace all commas in user input with dots and then parsing the double with InvariantCulture, like so:
string userInput;
...
userInput = userInput.Replace(',', '.');
double result;
double.TryParse(userInput, NumberStyles.Float, CultureInfo.InvariantCulture, out result);
This will obviously fail when someone actually enters the thousands separator and this seems to me more like a hack than a real solution. So, other than making my own parser for doubles, are there any cleaner ways to handle this problem?
If you are using ASP.Net you can use the AjaxControlToolkit FilteredTextBox you can also accomplish the task using regular expressions and pattern matching. It is nearly always better to try and get a standard input than attempting to deal with every possible human input variable.
Some other links:
MaskedTextBox
WPF Tools FilteredTextBox
If there are rules that can conclusively determine what they meant, then you can code the logic. With this problem, though, it is impossible to know the intent in every case:
1,001 === 1.001 or 1001
Also, even though any "better" logic might assume that numbers like "1,01" are unambiguous, such an entry might be a typo of "1,001." How likely this is depends on what kind of data you're gathering.
If people rarely use a thousands separator, then your existing logic seems good. If you want to be 100% certain of intent, though, the only way to be sure is to ask them what they meant in such cases. E.g. if someone enters 1,001 or 1.001 then fail validation, but recode it as "1,001.0" (or .00 if dealing with currency) to disambiguate it, forcing them to resumbit it.
In practice, you probably would cause more harm than good with this kind of abundance of caution since people don't really use the thousands separator. I'd stick with what you got.

C#: Anything similar to the php ctype_digit function for C#?

I have a string and I want to check that it only consists of digits. I don't really want to (or need to) parse it or anything, I just want to know that it does not contain anything but digits (and no floating point separator either, just digits).
PHP has this nice function called ctype_digit. Is there anything similar for C# anywhere in the .Net Framework? Or do I need to use a regular expression or something like that?
Creating a regex for this would of course be pretty simple, but I would like to not use it if there are better ways :p
You could use int.TryParse. It will return true if the supplied string represents a valid number, false otherwise. Don't forget to use NumerStyles.None to disallow blank spaces and the plus/minus sign.
UPDATE: As empi says, this will not work for very large strings. If you have arbitrarily large strings, maybe a regex is your only option. You could do something like Regex.IsMatch(theString,"^[0-9]+$")
The answer of #bruno conde made me think of this :D
if(subject.All(char.IsDigit))
// Do something
Can't believe I didn't think of it before...
bool onlyDigits = "1234".All(c => char.IsDigit(c));
Methinks, you'd be better to use regex to do the job for you... "\d+" should do it...ok, you said you do not want to use it... but it is foolproof way of ensuring the string contains only numbers, then if the regexp passes, then you can use int.Parse(...) straightaway.
Yes, you can use
bool Int32.TryParse(string s, out int result);
Code sample:
string myString = "1265";
int myInt;
if (Int32.TryParse(myString,myInt) // Returns true if mystring contains only digits
{
...
}
Other option is to use Regex:
public static bool IsDigit(string myString)
{
string pattern = #"^\d*$";
if (Regex.IsMatch(myString, pattern))
return true;
else
return false;
}
You can change the pattern as per your requirement.
There is no built-in method. Int32.TryParse or Int64.TryParse won't work for very long strings containing just numbers (they may also allow other chars used to represent integer numbers).
As other people have said, you can use the int.TryParse method, although unless your number is really really EXTREMELY big, you could use the TryParse method of other types, that have a bigger range than int32's. (of course using the NumberStyles.None option, to avoid signs and punctuation).
Here's the break down:
int -2,147,483,648 .. 2,147,483,647
uint 0 .. 4,294,967,295
long -9,223,372,036,854,775,808 .. 9,223,372,036,854,775,807
ulong 0 .. 18,446,744,073,709,551,615
float -3.402823e38 .. 3.402823e38
double -1.79769313486232e308 .. 1.79769313486232e308
decimal -79228162514264337593543950335 .. 79228162514264337593543950335
The one that can parse the biggest numbers is Double. If you need to use the number , you will lose some precision, but it can parse really long numbers (although you say you dont need to use it so it shouldnt be a problem). In a quick test I did, it managed to successfully parse the following string:
79228162514264337593543950335792281625142643375935439503357922816251426433759354395033579228162514264337593543950335792281625142643375935439503357922816251426433759354395033579228162514264337593543950335792281625142643375935439503357922816251426433759354395033579228162514264337593543950335234234234234243423
(thats 308 characters, it would fail with one more number)
Still, if you are not going to use the number, it might be an overkill, so I would go for the Regex, or even better the loop checking that each character is a digit.
If you then wanna go a little crazy you could split that into several smaller strings, and use the Task library to check it in a parallel way :P
(I know its a little offtopic now, but if you DO want to do that, you should check parallel.for and the Partition Ranger, check out this C9 10min clip: Parallel For Partition Ranger )

Categories