convert double to string and show decimal values only if required [duplicate] - c#

This question already has answers here:
C# Double - ToString() formatting with two decimal places but no rounding
(15 answers)
Closed 8 years ago.
I want to convert following 3 double values to string.
Double value converted string value
1 1
1.200 1.200
1.666 1.666
I want my output string values in same format as double. Means in above values 1 doesn't have any decimal value, so it will remain same. In case of 1.200 it will give me string as 1.200 and same for 1.666. However I tried .ToString() method but it truncated the ZERO value for 1.200 value. But i don't want this. I want Actual values in string format.

I admit that I don't like the idea of doing this, but I wrote an extension method for the Double type to format it. Feel free to change the funny names. :)
public static class StupidDouble
{
public static string StupidFormat(this double theValue)
{
// geth the double value to three decimal points
string s = string.Format("{0:0.000}", theValue);
// get the whole number value
int check = (int) Math.Truncate(theValue);
// if the format of the int matches the double, display without decimal places
if (string.Format("{0:0.000}", check) == s)
{
s = check.ToString();
}
return s;
}
}

C#, or any other language (including SQL), does not make differences in the values of floating-point types (float, double) based on their representation in your code.
This means that the compiler does not make a difference between:
double v1 = 1;
and
double v2 = 1.000;
Neither does the database where you say (in the comments) you get these values from.
The reason databases display decimals in a certain way is because of a pre-defined formatting applied to the result set. This could either be defined by the database tool you use, or depend on your locale system settings. Anyway, the .NET framework provides you with capabilities to explicitly format your data.
You need to decide which formatting suits your needs best an use it. For instance this will format the number with 4 decimal places after the dot:
String.Format("{0:0.0000}", v1); // outputs 1.0000
String.Format("{0:0.0000}", v2); // outputs 1.0000 too
If you already know your desired format, adjust the formatting string (the first argument that looks like "{0:0000}" in a way that best corresponds to your requirements.

Related

Convert int and float to 3 decimal places [duplicate]

This question already has answers here:
Formatting a float to 2 decimal places
(9 answers)
C# How to format a double to one decimal place without rounding
(6 answers)
Closed 11 months ago.
This is what I want to do:
if a double field has more than 3 decimal places then it should convert to 3 decimal figures and if no decimal places are present then it should convert to 3 decimals
e.g 12.878999 -> 12.878
120 -> 120.000
I cannot use string.Format() as I want the double field to stay double.
The first example requires Math.Round, eg Math.Round(d,3,MidPointRounding.ToZero).
The second isn't meaningful. Trailing decimal zeroes aren't significant. In the real types (float, double) they don't affect the storage of the number. The call Math.Round(120d, 3, MidpointRounding.AwayFromZero) will print 120 without a format string.
Displaying a double with three trailing zeroes is a formatting operation.
Update
From the comments it appears the actual problem is how to format a report sum in DevExpress Reports. All report engines allow specifying a format for fields and cells.
The Format Data page in the DevExpress Reports docs shows how to modify the FormatString property for a specific value
You can use Math.Round to achieve it
var value = Math.Round(12.878999, 3, MidpointRounding.ToZero);
For the integer type, you can do it this way
var value = 129 + 0.000m; //extend 3 decimals for an integer number

Display double as its true value?

I have a double in C# like below:
var myDouble = 1.0;
When I want to display this double, it prints as 1 when it should print as 1.0, I'm using this for a version so it kind of defeats the object.
How can I display it as its true value? 1.0 not 1...
Use
var myDouble = 1.0;
Console.WriteLine(myDouble.ToString("0.0"));
This question does not technically have an answer. The double is a 64-bit (and float as 32-bit) numeric floating point type. There's fundamentally no distinction between 1, 1.0, 1.00 and 1.000. These are all the SAME value.
In fact, that binary value if its 64-bit comes out to 3FF0000000000000 for ALL those examples. If its 32-bit, the binary expression is different but the idea is the same.
The format is defined by IEE 754 specification. More information on that is here:
https://en.wikipedia.org/wiki/IEEE_754
There are 3 sections if a floating point number:
1. Sign Bit
2. Exponent
3. Mantissa
There's no section for "number of zeros I typed".
Basically though, once you convert it to a number, you have lost the definition of how you had formatted the text, that just doesn't exist for a number.
If you want to remember how many decimal places you typed, you need to store it as a string. If you just want to format the decimal data type, you need to specify a format as there's no knowledge of your original format.
It is just as correct to say that "1" is its true value.
You can format the number as you want using something like this:
myDouble.ToString("0.0");
But I really don't understand why you would. A version is generally formatted a specific way. Some people format it as "1.00". I really think it makes more sense to store it in a string so it is always guaranteed to appear exactly as it should.
You should declare the variable in double type like this:
double a = 1.0;
Console.WriteLine(string.Format("{0:0.0}",a));

Display two decimal places for a string value [duplicate]

This question already has answers here:
Two Decimal places using c#
(13 answers)
Closed 6 years ago.
I've retrieved a decimal value from database as a string:
string get_amt = dt_.Rows[i]["billing_amt"].ToString();
Values of billing_amt are 100.0000, 150.0000, 0.0000.
I tried to display the value of get_amt rounding up to two decimal places using the code:
string.Format("{0:0.00}", get_amt)
but it is not working. How can I show the value of get_amt as 100.00 or 150.00? Please suggest.
You'll probably want to try something like:
double get_amt = 0;
if (dt_.Rows[i]["billing_amt"] != DBNull.Value)
get_amt = Convert.ToDouble(dt_.Rows[i]["billing_amt"]);
Then:
string.Format("{0:0.00}", get_amt)
should work.
It's currently not working as it's a string value your trying to format - which wont have decimal places.
Strictly speaking, you could use Regex to cut the string down to a 2 decimal point number like so:
string formatted = Regex.Match(unformattedString, #"^-?\d+\.\d{2}").Value;
That being said, you almost never want to use a string to hold number information. It's a bother and a pain to get them to do what you want. It's much more advisable to store them as either a double or a decimal, then convert to string only when you have to.

How to get the length of a Float? (C#)

I'm learning C# from the 'Fundamentals of Computer Programming with C#' by Svetlin Nakov and others (available for free here: http://www.introprogramming.info/english-intro-csharp-book/)
After each chapter, the authors like to ask questions that go beyond the scope of the chapter. Pg 135, Question 3 asks me to write a program that can correctly compare two real numbers with an accuracy of 0.000001 (7 significant digits).
So I'm using floats to compare the numbers and I decided to add some code that would check to see if the numbers entered are longer than the 7 significant digits that floats can handle. So I need to check for the number of significant digits. Google tells me that I should use sizeof(float) to do that, but I keep getting CS0246 error on the lines of the sizeof check (The type or namespace could not be found.)
The program works if I don't include the code that checks the length of the numbers. I can't find a answer on SO for C#.
What's the problem?
Edit: Thanks for all the answers. Let me clarify my question: I understand that parsing for string to float automatically checks for validity. However, I tried with my program yesterday, and floats will lose any more than 7 significant digits. So if I compare 0.123457 and 0.12345678, the program will declare that the two numbers are the same because the second number is rounded up. That's why I'm trying to catch for floats longer than 7 digits. I interpret the question this way because it occured to me that these two very similar, but not identical numbers slip through the cracks.
using System;
// Compare two real numbers with up to 0.000001 (7) significant digits
class Compare_Numbers
{
static void Main(string[] args)
{
// Processing the first number
String firstNumString = null;
Console.WriteLine("This program compares 2 numbers with upto 7 significant digits.\nEnter the FIRST number with up to 7 significant digits");
firstNumString = Console.ReadLine();
float firstNum = Single.Parse(firstNumString);
if (sizeof(firstNum) > 7)
{
Console.WriteLine("That number is too long!\nEnter a number with a MAX of 7 significant digits!");
}
// Processing the second number
String secondNumString = null;
Console.WriteLine("Enter the SECOND number with up to 7 significant digits");
secondNumString = Console.ReadLine();
float secondNum = Single.Parse(secondNumString);
if (sizeof(secondNum) > 7)
{
Console.WriteLine("That number is too long!\nEnter a number with a MAX of 7 significant digits!");
}
if (firstNum == secondNum)
{
Console.WriteLine("The two numbers are the SAME!");
}
else
{
Console.WriteLine("The two numbers are DIFFERENT!");
}
}
}
static private int GetNumDigitsInFloat(float n)
{
string s = n.ToString();
return s.Length - 1;
}
"How to get the length of a Float?"
In short, assuming 7 significant digits:
firstNum.ToString("G7").Length // 7 significant digits
Ex.
float pi = 3.14159265f;
string g5 = a.ToString("G5");
string g7 = a.ToString("G7");
However, your title asks something simple, but the body of your question indicates something else. So it appears that you think finding the length of a float is en route to a larger solution. I am not sure, so I will just try to point out several issues.
First, you are misusing sizeof; sizeof() in C# takes a type, not a variable. (So sizeof(float) would work, but not sizeof(num) ).
In any case, sizeof it isn't going to give you the number of significant digits. It will give you the number of bytes for the storage of the unmanaged type, which will be constant (4, 8, etc.). Instead, for a given string, use String.Length
However, what you can't do is try to parse the number to a float, and then try to check for out of range values by checking the float variable. By definition, if you can successfully parse to a float, then it was valid. If it is invalid, it won't parse. The part of your example where you use Single.Parse() and then proceed to try validating using the float variable is moot. You need to validate the string value, or validate that the parse succeeds, or change your approach.
I think the simplest solution is to just use Single.TryParse() and check the boolean return value. if it returns false, either the string value is invalid, or out of range of Single.MinValue and Single.MaxValue. So you might rethink your approach (since it isn't the author's original challenge). I, personally would use the large type in C# for my calculator, but the purpose of the exercise might be to learn these tangential issues, so:
If you already have a single precision (float), then you can get the length by converting to a string using Single.ToString() or string.Format() and using string.Length on the result, though it will include the decimal point, so account for that.
See the ToString() and format specifiers at:
http://msdn.microsoft.com/en-us/library/fzeeb5cd(v=vs.110).aspx
http://msdn.microsoft.com/en-us/library/0c899ak8(v=vs.110).aspx
The problem with this is by the time you use ToString() you already have a valid float and by that time the check is moot. You need to check the original value. See (2)
If you are starting from a string (which in this sample you are reading from console to string, then parsing with Single.Parse(), then you will either get a valid value, or an exception. You need to use a try-catch block with Single.Parse(), otherwise switch to Single.TryParse() and check the boolean return value.
Lastly, if you want to ensure you can both parse the value, as well as validate numbers of greater precision or range, you may add a Double.TryParse() as well.
if(!Single.TryParse(str, ref snum)) {
if(Double.TryParse(str, ref dnum))
// valid number is out of range for Single
else
// valid number is out of range for Double, or invalid
}
Or you may use Single.Parse and catch(OverflowException)
try {
snum = Single.Parse(str);
}
catch(OverflowException e) {
}
All that was said regarding your actual question, but the spirit of the problem is how to compare 2 valid numbers, in my opinion. In that case, use TryParse() to valid them, then just compare them directly, or use approaches given in #drf's answer https://stackoverflow.com/a/24482343/257090
If the intent is to ensure that two floating-point numbers are approximately equal within 1E-7, there is no need to convert to a string at all. In fact, using string conversions is probably not a robust approach:
The question as written requires seven significant figures after the decimal point, not seven significant figures total. The length of the string will include both.
Single.ToString by default only prints 7 digits of precision, but stores up to 9 internally. The floats 20.000001 and 20.000003 will both convert to "20" by default, but are not equal within 1e-7. (This is a function of the string conversion, not precision limits with this datatype.)
Floats can be parsed and output in exponential notation. What happens if a user enters 1e+20 at the prompt, a perfectly-valid float with a length of 5?
Given two numbers f1 and f2, and an accepted error ε of 10^-7, it follows mathematically that f1 and f2 should be considered equal (within accepted tolerance) if and only if:
|f1 - f2| ≤ ε
Or in C#, we can write the equivalent function:
// preconditions: e is non-negativeps, f1 and f2 are not NaN, Inf, or -Inf.
bool AreApproximatelyEqual(float f1, float f2, float eps)
{
return Math.Abs(f1 - f2) <= eps;
}
Given floats firstNum and secondNum, approximate equality is obtained as:
bool equal = AreApproximatelyEqual(firstNum, secondNum, 1e-7f);

Double to String Format text format

i have the follwing lines of code
double formId=2013519115027601;
txtEditFormID.Text = formid.ToString();
it gives me output
2.0135191150276E+15
if i write
txtEditFormID.Text = formId.ToString("0.0", CultureInfo.InvariantCulture);
it gives me
2013519115027600.0
but i want the label text
2013519115027601
how to do it?
I don't have enough information about the usage of your formId variable.
As it is shown above it seems an error to use a double datatype when there is no decimals to work on. So redefining your variable as a long datatype will be easy and the conversion will be the same.
long formId=2013519115027601;
txtEditFormID.Text = formid.ToString();
Not to mention the added benefit to your code to work with whole numbers instead of floating point numbers.
However, if you want to maintain the current datatype then
txtEditFormID.Text = formId.ToString("R");
The Round Trip Format Specifier
When a Single or Double value is formatted using this specifier, it is
first tested using the general format, with 15 digits of precision for
a Double and 7 digits of precision for a Single. If the value is
successfully parsed back to the same numeric value, it is formatted
using the general format specifier. If the value is not successfully
parsed back to the same numeric value, it is formatted using 17 digits
of precision for a Double and 9 digits of precision for a Single.
Your first option is to use data type as long or decimal . Something else you can do if you want to keep using double is this :
double formId = 2013519115027601;
string text = formId.ToString();
txtEditFormID.Text = text.Replace(".",string.Empty);
this will remove all the '.' chars
There are times where I want calculations handled in double but I want the result displayed as as an int or even rounded amount, so the question isn't so strange (assuming that the given sample is simplified in order to ask the question).
I was going to post sample code for rounding, but it makes more sense to just use the built-in method Math.Round(). You can cast to a long, as mentioned above, but you won't have rounding, if desired (which it usually is, IMHO).
txtEditFormId.Text = ((long)formId).ToString();

Categories

Resources