Error: Specified cast is not valid while converting decimal to double - c#

I have a function as under
private double RoundOff(object value)
{
return Math.Round((double)value, 2);
}
And I am invoking it as under
decimal dec = 32.464762931906M;
var res = RoundOff(dec);
I am gettingthe below error
Specified cast is not valid
What is the mistake?
Thanks

Casting the object to double will attempt to unbox the object as a double, but the boxed object is a decimal. You need to convert it to a double after first unboxing it. Then you perform the rounding:
Math.Round((double)(decimal)value, 2);

The other answers are correct in terms of getting something that will run - but I wouldn't recommend using them.
You should almost never convert between decimal and double. If you want to use a decimal, you should use Math.Round(decimal). Don't convert a decimal to double and round that - there could easily be nasty situations where that loses information.
Pick the right representation and stick with it. Oh, and redesign RoundOff to not take object. By all means have one overload for double and one for decimal, but give them appropriate parameter types.

As an alternative to John's answer, if you want to use other number types than just decimal, you could use this code;
private double RoundOff(object value)
{
return Math.Round(Convert.ToDouble(value), 2);
}

Related

Could someone explain line after line this code? And why i have an error: "Specified cast is not valid."? [duplicate]

I have the below function
public object Convert(object value)
{
string retVal = string.Empty;
int oneMillion = 1000000;
retVal = ((double)value / oneMillion).ToString("###,###,###.###");
return retVal;
}
I am invoking like
var result = Convert(107284403940);
Error: "Specified cast is not valid."
how to fix...
Note:~ the object value can be double, decimal, float, integer(32 and 64)..anything
Is it possible to do the typecasting at runtime?
Use Convert.ToDouble(value) rather than (double)value. It takes an object and supports all of the types you asked for! :)
Also, your method is always returning a string in the code above; I'd recommend having the method indicate so, and give it a more obvious name (public string FormatLargeNumber(object value))
If you are expecting double, decimal, float, integer why not use the one which accomodates all namely decimal (128 bits are enough for most numbers you are looking at).
instead of (double)value use decimal.Parse(value.ToString()) or Convert.ToDecimal(value)

A value of type 'int' cannot be used

I'm only learning C# and can't figure out what is wrong with this code.
Error CS1750 A value of type 'int' cannot be used as a default parameter because there are no standard conversions to type 'MidpointRounding'
Code:
public static double MyRound(double value, int point, MidpointRounding midpointRounding = 1)
{
if (!Enum.IsDefined(typeof (MidpointRounding), midpointRounding))
throw new ArgumentOutOfRangeException(nameof(midpointRounding));
decimal num = (decimal)((double)value);
try
{
num = Math.Round(num, point, midpointRounding);
}
catch (Exception exception1)
{
Exception exception = exception1;
MessageBox.Show(exception.Message, "Error : MyRound", MessageBoxButton.OK, MessageBoxImage.Hand);
}
return (double)((double)num);
}
The last parameter is of type MidpointRounding, which is an enum. The only int literal you can implicitly assign to an enum is 0. Your provided a default value of 1, which is what the compiler complains about.
Use MidpointRounding.ToEven instead, if that's what you meant.
Some other observations:
No need to check if midpointRounding is in range, Math.Round will take care of that.
Don't show message boxes from exceptions, this is not a good approach, it mixes UI code with logic code. You should let the exception propagate, if any.
You wrote return (double)((double)num);, one cast would be enough ;)
No need to cast (double)value, as value is already a double
Finally... Casting a double to decimal, then rounding it with a given method, then casting it back to double is not a good idea. You'll lose precision, and the midpoint rounding metod will most probably be defeated. Use decimal all along if the midpoint rounding method is of importance.

Why can't I cast an object-var of a long to a double?

I'm new to C# (but I know C++, JavaScript and Java) and I'm using JSON.net to parse a JSON file to a Dictionary<string, object>. Now I'm trying to store a value which was parsed as a long into a double variable. (I looked at the inspector and it says the dictionary value is of type object{long}.)
object obj = 123L;
double dbl = (double)obj;
Which gives me an InvalidCastException. I experimented a bit and found out that Convert.ToDouble(obj) works out just fine. I looked around and couldn't find anything about that difference between casting and Convert-ing. Also:
var v = 123L;
double dbl = (double)v;
This works perfectly. I guess that's because in this case, var is turned into Int64 at compile time.
Because that's an unboxing conversion. In order to cast a boxed long to a double, you can first unbox it, then actually convert it, for example: (not tested)
object obj = 123L;
double dbl = (double)(long)obj;
The second snippet works for the reason you identified.
When you cast an object to a value type, you unbox it. Unboxing is only possible to the type of the value type. As the type of the object is long, you can't unbox it to double. Check the Convert class:
double dbl = Convert.ToDouble(obj, null);

Function Int32.TryParse("23.0") returning false - C# MVC4

In my code i try to get browser version for charging the good css file, but this code doesn't work, and i don't see my error...
I've simply try first with a Convert.ToInt32 but don't works too...
public ActionResult Index()
{
ViewBag.logged = false;
ViewBag.BrowserName = Request.Browser.Browser.ToString();
Int32 v = 0;
string version = Request.Browser.Version;
if (version != null)
{
bool result = Int32.TryParse(version, out v);
}
ViewBag.BrowserVersion = v;
return View();
}
In my debugger :
version => string : "23.0"
v => int 0
result => false
Request.Browser.Version => string "23.0"
This is by design.
Parsing a version string would work better with System.Version.
You can, alternatively, parse it to a float and then see if a lossless conversion to Int32 can be made.
I fully agree with Andrei's answer; that's the approach you should take.
However, I think it's important to note that there is a way to parse int values from strings such as "23.0": it can be done using this overload of int.TryParse() which allows you to pass NumberStyles flags as parameters.
Concretely, after executing this code:
int v;
var wasParsedOK = Int32.TryParse(
"23.0",
NumberStyles.AllowDecimalPoint,
CultureInfo.InvariantCulture,
out v);
v will hold the value 23 and wasParsedOK will be true.
You can't assume that the version string is going to be integral, or even decimal. A browser could perfectly report 7.0b as its version. None of int, float, decimal or System.Version can represent this.
If you're only concerned about the major and minor version numbers, you can use the MajorVersion and MinorVersion properties of your Browser object, assuming it is of type HttpBrowserCapabilities. The framework has done the parsing for you, so it should be reliable.
It is giving false because 23.0 is not an int, So you can try with decimal,double or float.
decimal v = 0;
string version = "23.0";
Decimal.TryParse(version, out v);
It's been almost 2 years and no one has answered this correctly. The question is simple, "Why is it returning false?"
This question has already been answered, simply because your string is not an Integer, but is a Double or Decimal. By design, TryParse will try to get the EXACT match of the type integer from your string, if not it will return false, and your string ("23.0") is not an exact match.
Now if you're trying to find a solution in converting your version string to a number, What you can do is filter out the non-numeric, excluding 1 dot (.), in the string, then convert what's left to decimal/double. After this conversion you can then try converting it integer. Since you already converted your stirng to double/decimal, you can no longer use TryParse because the parameter needs to be in string format. You can then use Convert.ToInt32 inside a Try block.

dividing efficiently

I want to divide a number of type double, by an int. I only need the result in 2 deicmal place in string format. What is the best way to do this in terms of stack efficiency?
double d=321321321313131233213213213213;
int i=123;
ToString(d/i); //what do I get when I do this? A double? A float?
public String ToString(float? result) //what should I cast the result?
{
return #String.Format("{0:#,0.##;} divided double by int", result);
}
ToString(d/i); //what do I get when I do this? A double? A float?
You'll get a double. Dividing a double by an int will result in a double value.
public String ToString(float? result) //what should I cast the result?
You'll get a double for the value, so you'd be better off just using a double here. You'll never get a nullable type, and definitely wouldn't get a float as a result, so using float? is wholly inappropriate.
What is the best way to do this in terms of stack efficiency?
This is really not worth worrying about, unless, of course, you profile and find this really happens to be a problem. Building the string will be far more expensive than the division operation, and neither is likely to be a hotspot in terms of performance.
A clean way to handle this would just be to use double.ToString("N2"), ie:
double result = d/i;
string resultAsString = result.ToString("N2");
If you want a full, formatted string, you can use:
string resultAsString = string.Format("{0:N2} divided double by int", result);
Ok. First off, you get double, not double? or float?. Math functions should never return a nullable type. If you are assuming that infinity is represented as null, you are wrong. Infinities are determined by the bits. You can see if a double is infinity with Double.IsInfinity(double).
[SecuritySafeCritical]
public static unsafe bool IsInfinity(double d)
{
return ((*(((long*) &d)) & 0x7fffffffffffffffL) == 0x7ff0000000000000L);
}
What is the best way to do this in terms of stack efficiency?
I would recommend a look at the tragedies of micro optimization over at Coding Horror.
As for the function. That is completely unnecessary. Your best bet is Double.ToString(...):
double val = d / i;
string result = val.ToString("N2");
However, if you are using String.Format(...), you can use:
double val = d / i;
string result = string.Format("{0:N2} divided double by int", val);
Hacky solution:
If you need only 2 decimal places, you can multiply your double by 100, convert it to an integer, and then divide it by i.
Now take the string of the result, and add a dot before the last two chars.
Don't forget to handle the edge cases of negative values and rounding problems.
If you really care about efficiency, division of fractions is a slow process in comparison to division of integers.

Categories

Resources