How to check for valid value before converting Decimal - c#

I assume this will blow up if total is null (I don't recall if decimals are initalized to null at the beginning or zero)
public int SomePropertyName
{
get { return Convert.ToInt32(Decimal.Round(total)); }
}
So should I check for null or > 0 ?

Decimal is a value type - there's no such value as "null" for a decimal.
However, it's perfectly possible for a decimal to be out of range for an int. You might want:
decimal rounded = decimal.Round(total);
if (rounded < int.MinValue || rounded > int.MaxValue)
{
// Do whatever you ought to here (it will depend on your application)
}
return (int) rounded;
I'm somewhat confused as to why you're using Convert.ToInt32 at all though, given that your property is declared to return a decimal. What's the bigger picture here? What are you trying to achieve?

Decimal is a value type and can not be null.
If you need to know if it had been initialized, you should probably use a nullable decimal:
Decimal? total = null;
public int SomePropertyName
{
get
{
if (total.HasValue) Convert.ToInt32(Decimal.Round(total.Value));
return 0; // or whatever
}
}

Decimals are value types, and so cannot be null.
So no need to check there..

As others have said, Decimal is a value type and cannot be null. However, if converting from a string then Decimal.TryParse is your friend...

System.Decimal is a value type, so it cannot be null. Second thing, the method's return value is decimal, so why would you want to convert to a Int32?

Related

Test whether a decimal value can be converted to double

What's a good method to test whether a decimal value can be converted to double without throwing an exception and preferrably without converting to and parsing from a string?
I can test for compatibility with the long or int types like this: (yet untested)
if (value == decimal.Truncate(value))
{
if (value >= int.MinValue && value <= int.MaxValue)
return (int)value;
if (value >= long.MinValue && value <= long.MaxValue)
return (long)value;
return value.ToStringInvariant();
}
// Now try double, else revert to string again
This method should be used to serialise a decimal value to something that can be sent to JavaScript. Here, MessagePack is used but JSON should have the same constraints. decimal is not supported in both.
I could just always send the value as string but I'd like to save a bit bandwidth and use the simplest type that can represent the value (with decent precision).
PS: This doesn't compile:
if (value >= double.MinValue && value <= double.MaxValue)
return (double)value;
I cannot compare decimal with double. What would be a good solution, if this is a good path at all?
What's a good method to test whether a decimal value can be converted to double without throwing an exception?
static bool CanBeConvertedToDouble(decimal d)
{
return true;
}
:)
All decimals can be converted to double.
Note that doing so will possibly lose immense amounts of precision. A decimal has about 29 decimal places of precision; a double has only 15 or so. But converting a decimal to double never loses magnitude.

How can I deal with this double.NaN

I have the a Convert.ToDecimal() which occasionally throws an exception with the message
Value was either too large or too small for a Decimal
, because the call to DataContainer.GetValue(ColKeyId, index) returns double.NaN.
if (Convert.ToDecimal(DataContainer.GetValue(ColKeyId, index)) != Convert.ToDecimal(newValueToSet))
{
DataContainer.SetValue(ColKeyId, index, newValueToSet);
}
I cannot change the API implementation call of the GetValue().
What would be the best approach to deal with the conversion to decimal of a NaN double?
Okay, so it sounds like you just need to detect whether or not it's a NaN value:
double value = DataContainer.GetValue(ColKeyId, index);
if (double.IsNaN(value) || double.IsInfinity(value) ||
(decimal) value != (decimal) newValueToSet)
{
DataContainer.SetValue(ColKeyId, index, newValueToSet);
}
To be honest, it's not clear why you're converting from double to decimal at all, but this code at least shows how you can detect NaN/infinite values. Note that I've changed the calls to Convert.ToDecimal to simple casts to make the code simpler - but you could use Convert.ToDecimal if you want, of course..
Decimal.TryParse
So then you will know if it converted or not and if not assigne a defasult value or branch off down some other avenue.
HTH
You can check if the value is double.NaN before setting:
if (!Double.IsNaN(DataContainer.GetValue(ColKeyId, index)))
{
if (Convert.ToDecimal(DataContainer.GetValue(ColKeyId, index)) != Convert.ToDecimal(newValueToSet))
{
DataContainer.SetValue(ColKeyId, index, newValueToSet);
}
}

How can I pad nullable ints with zeros?

Is there any way to pad nullable int with zeros the way you can with normal int?
the myInt.ToString("D3") doesn't seem to work on nullale ints but for my current project I feel like I need to use nullable int in order to get the null value in my array instead of 0 as the default.
That is because int? is actually Nullable<T> where T is int here.
Calling ToString will call that on the Nullable struct, not the int. Nullable<T> has no knowledge of the overloads of ToString which int has.
You have to get the integer value first:
myInt.GetValueOrDefault(0).ToString("D3")
An int has never leading zeros, it just has a value. A string representation of an ìnt can have them. You can use the null-coalescing operator to convert the nullable-int to 0 if it has no value:
int? nullableInt = null;
string number = (nullableInt ?? 0).ToString("D3"); // 000
or use String.PadLeft:
number = (nullableInt ?? 0).ToString().PadLeft(3, '0');
You have to perform that action on the value:
myInt.Value.ToString("D3")
Example:
int? myInt = 3;
Console.WriteLine(myInt.Value.ToString("D3")); // Outputs 003

Check if decimal value is null

I would like to check if the decimal number is NULL or it has some value, since the value is assigned from database in class object:
public decimal myDecimal{ get; set; }
and then I have
myDecimal = Convert.ToDecimal(rdrSelect[23].ToString());
I am trying:
if (rdrSelect[23] != DBNull.Value)
{
myDecimal = Convert.ToDecimal(rdrSelect[23].ToString());
}
But I am getting this:
the result of the expression is always 'true' since a value of type
'decimal' is never equal to null
How can I check if that decimal number has some value?
A decimal will always have some default value. If you need to have a nullable type decimal, you can use decimal?. Then you can do myDecimal.HasValue
you can use this code
if (DecimalVariable.Equals(null))
{
//something statements
}
decimal is a value type in .NET. And value types can't be null. But if you use nullable type for your decimal, then you can check your decimal is null or not. Like myDecimal?
Nullable types are instances of the System.Nullable struct. A nullable
type can represent the normal range of values for its underlying value
type, plus an additional null value.
if (myDecimal.HasValue)
But I think in your database, if this column contains nullable values, then it shouldn't be type of decimal.
I've ran across this problem recently while trying to retrieve a null decimal from a DataTable object from db and I haven't seen this answer here. I find this easier and shorter:
var value = rdrSelect.Field<decimal?>("ColumnName") ?? 0;
This was useful in my case since i didn't have a nullable decimal in the model, but needed a quick check against one. If the db value happens to be null, it'll just assign the default value.
Assuming you are reading from a data row, what you want is:
if ( !rdrSelect.IsNull(23) )
{
//handle parsing
}
Decimal is a value type, so if you wish to check whether it has a value other than the value it was initialised with (zero) you can use the condition myDecimal != default(decimal).
Otherwise you should possibly consider the use of a nullable (decimal?) type and the use a condition such as myNullableDecimal.HasValue
If you're pulling this value directly from a SQL Database and the value is null in there, it will actually be the DBNull object rather than null. Either place a check prior to your conversion & use a default value in the event of DBNull, or replace your null check afterwards with a check on rdrSelect[23] for DBNull.
You can also create a handy utility functions to handle values from DB in cases like these.
Ex. Below is the function which gives you Nullable Decimal from object type.
public static decimal? ToNullableDecimal(object val)
{
if (val is DBNull ||
val == null)
{
return null;
}
if (val is string &&
((string)val).Length == 0)
{
return null;
}
return Convert.ToDecimal(val);
}

Nullable double NaN comparison in C#

I have 2 nullable doubles, an expected value and an actual value (let's call them value and valueExpected). A percentage is found using 100 * (value / valueExpected). However, if valueExpected is zero, it returns NaN. Everything good so far.
Now, what do I do if I need to check the value, to see if it is NaN? Normally one could use:
if (!Double.IsNaN(myDouble))
But this doesn't work with nullable values (IsNaN only works with non-nullable variables). I have changed my code to do the check (valueExpected == 0), but I'm still curious - is there any way to check for a nullable NaN?
Edit: When I say the code doesn't work, I mean it won't compile. Testing for null first doesn't work.
With all Nullable<T> instances, you first check the bool HasValue property, and then you can access the T Value property.
double? d = 0.0; // Shorthand for Nullable<double>
if (d.HasValue && !Double.IsNaN(d.Value)) {
double val = d.Value;
// val is a non-null, non-NaN double.
}
You can also use
if (!Double.IsNaN(myDouble ?? 0.0))
The value in the inner-most parenthesis is either the myDouble (with its Nullable<> wrapping removed) if that is non-null, or just 0.0 if myDouble is null. Se ?? Operator (C#).
I had the same issue and I solved it with casting the double? with double
double.IsNaN((double)myDouble)
this will return true if NaN and false if not
With C# 7.0 Pattern matching combined null + NaN check check can be written like this:
double? d = whatever;
if(d is double val && double.IsNaN(val))
Console.WriteLine(val);
The advantage is local scoped variable val at hand, which is not null, nor double.NaN and can even be used outside of if.
With pattern matching in newer Roslyn C# versions, double.NaN is a valid pattern which tests using IsNaN (that is it works differently than Equals() where NaN is never equal to NaN as specified by IEEE floating point standard).
Therefore you can now do this:
double? myDouble = something;
if (myDouble is double and not double.NaN)
Console.WriteLine("A number");
For testing NaN this can even be shortened like this:
double? myDouble = something;
if (myDouble is double.NaN)
Console.WriteLine("Not a number and not NULL");

Categories

Resources