I have some problem with parsing float value from string.
Problem is with decimal part of value, here is example:
var tmp = "263148,21";
var ftmp = float.Parse(tmp); //263148.219
I tried some other values, but I don't figured out, from what reason are some decimal values incorrect.
This doesn't have anything to do with the comma in the OP's code - instead, this question is about a float value not accurately representing a real number.
Floating point numbers are limited in their precision. For really precise numbers you should use double instead.
See also this answer: why-is-floating-point-arithmetic-in-c-sharp-imprecise? and have a look at this for more information: What Every Computer Scientist Should Know About Floating-Point Arithmetic
var tmp = "263148,21";
var culture = (CultureInfo)CultureInfo.CurrentCulture.Clone();
culture.NumberFormat.NumberDecimalSeparator = ",";
var ftmp = double.Parse(tmp, culture);
You have to use double instead of float
As stated in other answers and comments, this is related to floating point precision.
Consider using Decimal if you need to have the exact same decimals or to leverage rounding errors. But please note that this type is much more heavy weight (128 bits) and might not be suited for your case.
var tmp = "263148,21";
var dtmp = Decimal.Parse(tmp); //263148.21
Related
I have the following numbers as strings; 22570438, 22570481, 22570480.
var listOfStrings = new List<string> { "22570438", "22570481", "22570480" };
foreach (var val in listOfStrings)
{
float numTest = 0;
numTest = Convert.ToInt64(float.Parse(val));
numTest = long.Parse(val);
numTest = float.Parse(val.ToString().TrimStart().TrimEnd(), CultureInfo.InvariantCulture.NumberFormat);
}
For number, 22570438, in these 3 instances the number returned is 22570438, as with 22570480
But for 22570481, these 3 instances return 22570480. Code below is a sample how I'm doing the testing and not an code issue. I have tried it in other projects and still getting same result.
Has anyone experience this issue and is it a compiler issue when converting 22570481 to a float ??
I tried finding similar questions but If anyone knows a post that could help please reply with link.
float has limited precision; it can't accurately store arbitrary integers beyond a certain size, and it doesn't have the precision to retain what you want here.
Consider using int, decimal or double instead.
It is not a compiler bug or a runtime bug. It is a fundamental feature of floating point arithmetic (in this case 32-bit IEEE 754 floating points)
I need to convert my value 2.8634 to 2.8. I tried the following ,
var no = Math.Round(2.8634,2,MidpointRounding.AwayFromZero)
I'm getting 2.87.
Suggest me some ideas how to convert.
Thanks
This might do the trick for you
decimal dsd = 2.8634m;
var no = Math.Truncate(dsd * 10) / 10;
Math.Truncate calculates the integral part of a specified decimal number. The number is rounded to the nearest integer towards zero.
You can also have a look on the difference between Math.Floor, Math.Ceiling, Math.Truncate, Math.Round with an amazing explanation.
Use this one.Hope this will work for you.
var no = Math.Round(2.8634,1,MidpointRounding.AwayFromZero)
It's a tad more cryptic (but more efficient) than calling a Math method, but you can simply multiply the value by 10, cast to an integer (which effectively truncates the decimal portion), and then divide by 10.0 (or 10d/10f, all just to ensure we don't get integer division) to get back the value you are after. I.e.:
float val = 2.8634;
val = ((int)(val * 10)) / 10.0;
Can't find simple way to convert double to string. I need to convert large numbers without distortion. Such as:
double d = 11111111111111111111;
string s = d.ToString();
Console.WriteLine(s);
//1.11111111111111E+19
How to get string value from double value exactly the same as user enter.
11111111111111111111111 => "11111111111111111111111"
1.111111111111111111111 => "1.111111111111111111111"
Any ideas how it can be done?
double is a floating point type. So it has a limited accuracy. In your example, you could do something like this:
double d = 11111111111111111111;
string s = d.ToString("F0");
Console.WriteLine(s);
But as you'll see,this would output 11111111111111100000 instead of 11111111111111111111,so it has lost accuracy in the process. So the answer here is use the right type for the work. If you need a string, use a string variable to store the value.
Edit
This was the question i was trying to find that explains the problem with floating point math., thanks to #GSerg
First of all: 11111111111111111111111 is to large for a double value and also this value: 1.111111111111111111111 since the double max decimal length is 17.
By default, a Double value contains 15 decimal digits of precision,
although a maximum of 17 digits is maintained internally.
For this reason you should use BigInteger and then ToString for formatting the output.
There is also a library in the nuget Directory called BigRational, never used and seems in Beta stage but probably will help in solving this problem.
In general case, you can't do this: user can well input, say 123, in many a way:
123
123.00
1.23e2
12.3E1
123.0e+00
1230e-1
etc. When you convert the user input into double you loose the initial format:
string userInput = ...
// double is just 123.0 whatever input has been
double value = double.Parse(userInput);
In case you want to drop exponent if it's possible you can
double value = 11111111111111111111;
string result = value.ToString("#######################");
And, please, notice, that double has 64 bit to store the value, that's why a distortion is inevitable for large numbers:
// possible double, which will be rounded up
double big = 123456789123456789123456789.0;
// 1.2345678912345679E+26
Console.WriteLine(big.ToString("R"));
// 123456789123457000000000000
Console.WriteLine(big.ToString("###########################"));
May be you want BigInteger instead of double:
using System.Numerics;
...
BigInteger value = BigInteger.Parse("111111111111111111111111111111111");
// 111111111111111111111111111111111
Console.WriteLine(value.ToString());
How to read figure without any symbol??
example -8759.328 and 8569.659"
output should be 8759.32 and 8569.65 in double
var debit = txtDebit.Text.Split('-');
oBankPages.DebitAmount = Convert.ToDouble(debit);
If I understand, you have two strings,
var numberStringOne = "-8759.328";
var numberStringTwo = "8569.659";
If you want to treat these strings like decimals, first you must parse them.
var numberOne = decimal.Parse("-8759.328");
var numberTwo = decimal.Parse("8569.659");
Next, you could get the value ignoring the sign, by using Math.Abs, Abs. being an abbreviation of Absolute.
var numberOne = Math.Abs(numberOne);
Then you convert the number back to a rounded string using the appropriate format specifier.
var formattedNumberOne = numberOne.ToString("D2");
or perhaps
Console.WriteLine("{0:D2}", numberTwo);
so, all on one line.
var formattedNumberOne = Math.Abs(decimal.Parse("-8759.328")).ToString("D2");
Formatting can be done only with strings integral and floating point types doesn't have any formatting by thier own
var res = Math.Abs(-8759.328).ToString("f2");
If at all you need the result as Double you can Round the result
var res = Math.Round(Math.Abs(-8759.328), 2);
Note: above calls Math.Round so result will be rounded rather than formatted. In other words you may get result as 8759.33 instead of 8759.32
oBankPages.DebitAmount = Math.Abs(Convert.ToDouble(txtDebit.Text));
Beware that fractions like these cannot be accurately represented in floating point.You can simply solve it out in your case.
double value = Math.Truncate(100 * Math.Abs(-8759.328)) / 100;
OUTPUT : 8759.32
Try this.
string debit = Regex.Replace(txtDebit.Text, "[^0-9^.]+", "");
oBankPages.DebitAmount = Math.Abs(Convert.ToDouble(debit)).ToString("f");
Use decimal instead of double. Your data is related to money. Even one cent off is significant. You cannot afford to use floats or doubles, as they are lossy data types that remember only the "beginning" of the number and forget the ending. decimal is designed to be precise. If you ever work for financial sector, remember: no floats, no doubles. Of course unless some high-accountant orders tells you they level it up somehow and it's safe due to their creativity..
Read about Salami Attack
I have a code, and I do not understand it. I am developing an application which precision is very important. but it does not important for .NET, why? I don't know.
double value = 3.5;
MessageBox.Show((value + 1 * Math.Pow(10, -20)).ToString());
but the message box shows: 3.5
Please help me, Thank you.
If you're doing anything where precision is very important, you need to be aware of the limitations of floating point. A good reference is David Goldberg's "What Every Computer Scientist Should Know About Floating-Point Arithmetic".
You may find that floating-point doesn't give you enough precision and you need to work with a decimal type. These, however, are always much slower than floating point -- it's a tradeoff between accuracy and speed.
You can have precision, but it depends on what else you want to do. If you put the following in a Console application:
double a = 1e-20;
Console.WriteLine(" a = {0}", a);
Console.WriteLine("1+a = {0}", 1+a);
decimal b = 1e-20M;
Console.WriteLine(" b = {0}", b);
Console.WriteLine("1+b = {0}", 1+b);
You will get
a = 1E-20
1+a = 1
b = 0,00000000000000000001
1+b = 1,00000000000000000001
But Note that The Pow function, like almost everything in the Math class, only takes doubles:
double Pow(double x, double y);
So you cannot take the Sine of a decimal (other then by converting it to double)
Also see this question.
Or use the Decimal type rather than double.
The precision of a Double is 15 digits (17 digits internally). The value that you calculate with Math.Pow is correct, but when you add it to value it just is too small to make a difference.
Edit:
A Decimal can handle that precision, but not the calculation. If you want that precision, you need to do the calculation, then convert each value to a Decimal before adding them together:
double value = 3.5;
double small = Math.Pow(10, -20);
Decimal result = (Decimal)value + (Decimal)small;
MessageBox.Show(result.ToString());
Double precision means it can hold 15-16 digits. 3.5 + 1e-20 = 21 digits. It cannot be represented in double precicion. You can use another type like decimal.