I'm new to ASP.NET MVC C# Programming
I have a class which contains an attribute called Credits of type double. This attribute should be represented as a Time Format (hh:mm) in my web application. So for example, if I were to give Credits the value of 2.5, I want it to display 2:50, 6.15 as 6:15, etc. I know TimeSpan can convert a double to the time format but it converts 2.5 to 2:30. Is there a way to do easily convert a double to this time format without changing its data type to a String? Is there some sort of helper Attribute tag or something that would make this easy?
It appears that you want to get the whole number and the fractional part separated, and that you want the fractional part as a two-digit number.
So here's how you would get the whole number part as an int.
var whole = (int)Math.Truncate(value);
And this would give you the fractional part as an int, in this case only the first two decimal places.
var twoFrac = (int)(((decimal)value % 1) * 100);
So, if value was 12.345, then twoFrac would turn out to be 34 in int.
Now you can display these whichever way you like.
And you can actually put the above inside of a method so you can get the fractional part up to however many decimal places you want, like this:
private static int GetFractionalPart(double value, int decimalPlaces)
{
var factor = (int)Math.Pow(10, decimalPlaces);
var fractional = (int)(((decimal)value % 1) * factor);
return fractional;
}
NOTE
However, as many others pointed out in comments, this is a confusing and you could even say wrong way of doing things if you're actually dealing with time values. For example, using your criteria, a value of 2.75 would convert to 2:75, but that doesn't mean anything in terms of time.
So you really ought to use TimeSpan as you mentioned in your original post, which would convert 2.5 to 2:30 etc.
Related
I want to add a thousands separator to a double number but want to keep the decimal places as is i.e. dont want any rounding.
#,# is solving my problem of adding the thousand separator but how do I preserve the decimal places ? #,# strips off the part after ..
I cannot use any culture or something like that & the developer whose function I am calling has only given me a way of changing the format by passing as parameter strFormat.
I did check other posts & even the docs but somehow not able to figure this out.
string strFormat = "#,#";
string str = double.parse("912123456.1123465789").ToString(strFormat);
//Expected here 912,123,456.1123465789
//Actual Output 912,123,456
//912123456.123 should give 912,123,456.123
//912123456.1 should give 912,123,456.1
//912123456.1123465789 should give 912,123,456.1123465789
//912123456 should give 912,123,456
Well, after looking at the documentation on Microsoft, it would appear that there is no particular way to allow a floating point position in a number - all characters in a format string are character placeholders.
I would recommend that you either use a very nasty predetermined number of #s to set the width of the decimal position, or the slightly less (or possibly more, depending on your outlook) nasty option of reading all numbers into an array, determining the longest decimal position, then building a format of #s using the result.
At the end of the day, this is a single format string that you can put into place, test and ensure it works, then come back later and fix if you find a better alternative.
Also, this is one of those things where you could put the string into a configuration setting and change as and when you need to - far more flexible.
To be honest, this is a very slight thing to be worried about in the grand scheme of performance and writing a program.
Technically, Udi Y gets my vote!
If you know the max number of decimal places, e.g. 10, then use:
string strFormat = "#,#0.##########";
Update:
This max number is known.
According to Microsoft documentation a Double value has up to 15 decimal digits of precision (including both before and after the decimal point). More than 15 digits will be rounded.
So if you must invoke that method of 'double.parse' and can only send the format, this is the best you can do:
string strFormat = "#,#0.###############";
You can calculate the formatting dynamically for each number:
public static void Main()
{
var number = 1234.12312323123;
var format = GetNumberFormat(number);
Console.WriteLine(number.ToString(format));
}
public static string GetNumberFormat(double number)
{
var numberAsString = number.ToString();
var decimalPartSize = numberAsString.Substring(numberAsString.LastIndexOf('.') + 1).Length;
return $"N{decimalPartSize}";
}
So
number = 1234.12312323123
will give you 1,234.12312323123. Works for negative numbers as well. Also, as we work with strings, there won't be any rounding errors or precision artifacts.
I have a lot of data in Science notation when I load this data into my double variable, everything works fine (in VS I see value 0.00000000022). But when I multiply this number by 1000000 I got unrounded value (0.00021999999999999998).
I must multiply this value because I use it for selection filter. After send data from selection filter I again divide this data to my raw format 0.00021999999999999998 / 1000000 = 0.00000000022.
2.20E-10 = 0.00000000022 * 1000000 = 0.00021999999999999998
Expected value is this:
0.00021999999999999998 => 0.00022
When I use a similar number, for example, 2.70E-10 I got after multiple value 0.00027 (In this case conversion work fine).
Values are converted only for use in the selection menu so that no unnecessary zeros are shown and the label indicates which unit they represent. (For this example from Ohm to microOhm in select box)
Is there any way to correctly convert these values?
I use LINQ for convert this values in like this:
var x = y.Select(s => s.Resistance * 1000000).Distinct();
problem is floating point numbers, a good article about this is link
use decimal type instead of double for fast solving :)
I'm working for several years in financial market and from times to times I need to treat specifically the decimal part of a value. When I get the value as a string I use to use Regex and when I get the value as a double or a decimal I use to use %, ceiling and pow.
// with math operations to get a truncated int value from the decimal part
// of a decimal or double
(int)Math.Ceiling((value % 1) * Math.Pow(10D, (double)(decimalLength - 1)))
// with Regex to get a truncated string value from the decimal part
// of a string
Regex.Replace(value, #"^[^.]+\.([0-9]{" + decimalLength.ToString() + "}).*$", "$1")
The question, as described at the headline, witch one is best? Should I convert my double or decimal values to string and always use Regex? Maybe I should convert my string to double and always use math operations? Or am I doing great dealing this way?
It's always better to use mathematical function to perform mathematical operations.
Not only does it make the code more readable, it's also likely to have better performance.
Therefor, as stribizhev wrote in the comments - Use #1 :).
Also, your regular expression does not take into consideration that different cultures might have different decimal separators.
Not everyone is writing one and a quarter as 1.25, some cultures use , as the decimal separator and thus it's written as 1,25.
Should you encounter a decimal like that, your regular expression will not work as you expect.
Another (quite easy method) which I'm sure people will state is bad or something (out of ignorance, mostly) is to convert it to a string and then split the string on the decimal point.
You can easily get the left and right parts of the decimal value in this manner, though it is not going to have the performance of the mathematical operations.
The nice thing of this method is that you don't need to use Math.Pow to get the decimal as a number that large, you can handle that in the .ToString portion.
int decimalPlaces = 10;
decimal number = 123456789.1234567890M;
string[] parts = number.ToString("F" + decimalPlaces).Split(System.Globalization.CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator[0]);
long[] lParts = new long[parts.Length];
for (int i = 0; i < parts.Length; i++)
lParts[i] = Convert.ToInt64(parts[i]);
for (int i = 0; i < parts.Length; i++)
Console.WriteLine(lParts[i].ToString());
Output:
123456789
1234567890
I'm not saying this is always the answer, but it can most certainly have it's advantages. It's also quite simple to use: all you have to do is change the 10 in the decimalPlaces to the number of decimal places you want, and you will have your same value. (Which of course, your method is just as modular.)
Merely putting this out here as another alternative to your methods, really the only bad method is using a Regex. If you wish to use strings then use regular string manipulation.
Update: Also, I just did a few benchmarks, on the Math method vs this string method, and found that the Math method can return slightly inaccurate results. When tested with double number = 9.1234567890D; the string method returned 1234567890, whereas the Math method returned 1234567891. This is something to keep in mind if you need the absolute and exact decimal values. The other issue is that the Math method cannot use a decimal type (which has greater precision than a double type) implicitly, it must be converted to a double first. The string method is, however, slower. It takes 250-300% of the time of the Math method.
These are just more things to keep in mind with it.
I am trying to round decimal number upto two decimal places which is working perfectly.
I am doing as below :
Math.Round(Amount, 2)
So, if I have Amount as 40000.4567, I am getting 40000.46which is exactly what I want.
Now problem is I have decimal number like 40000.0000, when I round it, the result is 40000, and what I really want is 40000.00. So round will always neglect trailing zeros.
To solve this problem, I have the option of converting it to string and use format , but I don't want to do that as that will be inefficient and I believe there must be some way to do it better.
I also tried something like
Decimal.Round(Amount, 2)
Now one way can be to check whether number contains anything in fractional part and use round function accordingly , but that is really bad way to do it.
I can't use truncate as well due to obvious reasons of this being related to amount.
What is the way around?
It is rounding correctly but you fail to understand that the value is not the format. There is no difference between the two values, 40000 and 40000.00, and you'll have a similar issue with something like 3.1.
Simply use formatting to output whatever number you have to two decimal places, such as with:
Console.WriteLine(String.Format("{0:0.00}", value));
or:
Console.WriteLine(value.ToString("0.00"));
You are mixing two things - rounding and output formatting. In order to output a number in a format you want you can use function string.Format with required format, for example:
decimal number = 1234.567m;
string.Format("{0:#.00}", number);
You can read more about custom numeric format strings in MSDN
I think what you're looking for is displaying two decimals, even if they are zero. You can use string.Format for this (I've also combined it with Round):
Console.WriteLine(string.Format("{0:0.00}", Math.Round(Amount, 2));
for rounding decimal number you can use
decimal number=200.5555m;
number= Math.Round(number, 2);
string numString= string.Format("{0:0.00}", number);
I have number of type double.
double a = 12.00
I have to make it as 12 by removing .00
Please help me
Well 12 and 12.00 have exactly the same representation as double values. Are you trying to end up with a double or something else? (For example, you could cast to int, if you were convinced the value would be in the right range, and if the truncation effect is what you want.)
You might want to look at these methods too:
Math.Floor
Math.Ceiling
Math.Round (with variations for how to handle midpoints)
Math.Truncate
If you just need the integer part of the double then use explicit cast to int.
int number = (int) a;
You may use Convert.ToInt32 Method (Double), but this will round the number to the nearest integer.
value, rounded to the nearest 32-bit signed integer. If value is
halfway between two whole numbers, the even number is returned; that
is, 4.5 is converted to 4, and 5.5 is converted to 6.
Use Decimal.Truncate
It removes the fractional part from the decimal.
int i = (int)Decimal.Truncate(12.66m)
Use Math.Round
int d = (int) Math.Round(a, 0);
Reading all the comments by you, I think you are just trying to display it in a certain format rather than changing the value / casting it to int.
I think the easiest way to display 12.00 as "12" would be using string format specifiers.
double val = 12.00;
string displayed_value = val.ToString("N0"); // Output will be "12"
The best part about this solution is, that it will change 1200.00 to "1,200" (add a comma to it) which is very useful to display amount/money/price of something.
More information can be found here:
https://msdn.microsoft.com/en-us/library/kfsatb94(v=vs.110).aspx
here is a trick
a = double.Parse(a.ToString().Split(',')[0])
Because the numbers after point is only zero, the best solution is to use the Math.Round(MyNumber)
//I am doing a basic Calculation here and this works for me.
// it takes values from textboxes and performs the following as far as I understand it. as I have only been coding now for a few months.
double VC2 = Convert.ToDouble(txt_VC_M16_Tap.Text); // converts to double.
double total2 = (VC2 * 1000) / (3.14157 * 14.5); // performs the calculation.
total2 = Math.Round(total2); //Round the result to a whole number(integer)
txt_RPM2.Text = Convert.ToString(total2); // converts result to string and puts it in the textbox as required.
// Hope this helps people that are looking for simple answers.