C# float.Parse losing precision [duplicate] - c#

This question already has answers here:
c# float [] average loses accuracy
(3 answers)
Why is my number being rounded incorrectly?
(5 answers)
Closed 5 years ago.
I'm having some trouble to convert data taken in my database to float numbers. Basically, the application is rounding one of my values to one decimal house. The table contains a set of fields with monetary values and one of these values te application keeps rounding. The strangest thing is that, despite the fact that there are more float values on my database, just one of them is rounded (valorAtualizadoAcordo). So, this is my query:
SELECT
idAcordo,
tipoAcordo,
valorAtualizadoAcordo,
dataAtualizacaoAcordo,
valorConfessadoAcordo,
valorAcordo,
valorEntradaAcordo,
valorParceladoAcordo,
quantidadeParcelasAcordo,
taxaAcordo,
atualizacaoTrAcordo,
dataPrimeiraParcelaAcordo,
dataUltimaParcelaAcordo,
dataAssinaturaAcordo,
dataAprovacaoAcordo,
primeiraDataAbertoAcordo,
dataProtocoloAcordo,
tipoProtocoloAcordo,
cadastroDspsAcordo,
dataSolicitacaoAcordo,
contabilizadoAcordo,
dataLancamentoAcordo,
contratoDevolvidoAcordo,
dataDevolucaoAcordo,
volumetriaAcordo,
pagamentoRealizadoDataAcordo,
contratoAntesAjuizamentoDataAcordo
FROM
acordo
WHERE
FK_idContrato = 46;
And this is my convertion:
ac.setValor(float.Parse(acd.Rows[i][5].ToString(), CultureInfo.InvariantCulture));
The value I'm trying to retrieve from the database is 325,360.69. I'm converting it to PT-BR format, what gives me "325360,7" (in Brazil, we use "," instead of "." to define the decimal floating point).

Not sure why you think making a string from a float and back is a good idea, but I would start by dropping the ToString. The use a cast or a real conversion method like convert.ToFloat:
float f = (float)acd.Rows[i][5];
Or:
float f = Convert.ToFloat(acd.Rows[i][5]);

Related

Why does this ulong divided by ulong give me 0? [duplicate]

This question already has answers here:
Why does integer division in C# return an integer and not a float?
(8 answers)
Closed 3 years ago.
I am grabbing total RAM of a computer system and available RAM and trying to work out what percentage is available.
I am using the following code:
double percent = my.Info.AvailablePhysicalMemory / my.Info.TotalPhysicalMemory;
and have also tried:
decimal percent = my.Info.AvailablePhysicalMemory / my.Info.TotalPhysicalMemory;
I am sure it's an issue with the type but I am unsure why both methods give a result of 0.
The actual values are Total: 17072574464 and Available: 8746000384. The values come back from the system cast as ulong. So what does percent always equal 0? If I put the numbers in directly it works fine. Just can't use the ulong variables - hence why I am sure it's my lack of experience with types in C# that is the problem.
You are trying to divide an integer by an integer, which always rounds down. You need to convert to a floating point number before you divide; for example:
double percent = my.Info.AvailablePhysicalMemory * 1.0 / my.Info.TotalPhysicalMemory;

Why does my double round my variables sometimes? [duplicate]

This question already has answers here:
Difference between decimal, float and double in .NET?
(18 answers)
Closed 3 years ago.
I really dont unterstand why, but my double array just sometimes round my variables, even though it shouldn't. The weird thing is, that it only does this sometimes, as you see in the picture. All of the array elements should have this long precision. The Variable "WertunterschiedPerSec" is also at this precision every time, but still, if i add it to Zwischenwerte[i], then it sometimes just get less precisie, even though i dont do anything anywhere. Does anybody know why?
I would suggest using a decimal, but let's get into the exact details:
double, float and decimal are all floating point.
The difference is double and float are base 2 and decimal is base 10.
Base 2 numbers cannot accurately represent all base 10 numbers.
This is why you're seeing what appears to be "rounding".
I would use the decimal variable instead of double because you can basically do the same functions as a double except for using the Math function. Try to use Decimals and if you need to convert than use:
Double variable = Convert.ToDouble(decimal var);
Decimals are meant for decimals so they will hold more information than a float or decimal

Is the double data type not suitable for my data / calculation? [duplicate]

This question already has answers here:
Is double Multiplication Broken in .NET? [duplicate]
(6 answers)
Closed 6 years ago.
my unit test failed because of this, so I wonder if I am using the right datatype?
Reading the specs of the double I'd think it should be ok, but this is what's happening:
I'm reading a string from a file with value 0,0175 (comma as decimal sep.)
then I convert it to a double and then multiply it by 10000.
The function which does the multiply is this:
private static double? MultiplyBy10000(double? input)
{
if (!input.HasValue)
{
return null;
}
return input.Value*10000;
}
next is from the immediate window:
input.Value
0.0175
input.Value*10000
175.00000000000003
And that is where my unit test fails, because I expect 175.
Is the double not accurate enough for this?
Checked other values too:
input.Value*1
0.0175
input.Value*10
0.17500000000000002
input.Value*100
1.7500000000000002
input.Value*1000
17.5
input.Value*10000
175.00000000000003
The weird thing is, I have 12 testcases
0,0155
0,0225
0,016
0,0175
0,0095
0,016
0,016
0,0225
0,0235
0,0265
and assert 4 of these, and the other 3 don't have this behaviour
Is the double not accurate enough for this?
No, doubles are floating point numbers, which are inaccurate by design. You can use decimal which is accurate and more suitable if you need exact numbers.
Floating point numbers where the value to the right of the decimal point are not powers of 2 cannot be accurately represented. Although you've got what looks like 0.0175 there's actually more data there.
After you've scaled the number up use Math.Round to trim off date on the right off the decimal point.

float value was not correct C# in unity3d [duplicate]

This question already has answers here:
How to round a float value in c#?
(3 answers)
Closed 6 years ago.
I made a test in C# with unity3d engine.
like this:
float dt = 22.05f + 0.05f;
dt value should be 22.1f but i debug dt value in VS2015,dt value is 22.0999985f. I don't know why it was not the correct value I expected.
Because floats are binary - you can not express every decimal number exactly. Not on the fraction side, where it has to be constructed out of parts that are binary: 1/2, 1/4, 1/8 etc.
.1 (1/10th) can only be approximated.
This leads to all kinds of small issues that programmers - mostly those who refuse to learn programming by reading books that explain things in detail - fall into.
Another item is that you should not never ever compare floats to a constant - if the float is calculated, it may be SLIGHTLY off. You always compare whether the difference between two values is smaller than a given small epsilon (Abs(a-b)

Why Math.Round() works differently in C# [duplicate]

This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 8 years ago.
First I noticed that Math.Round() doesn't round for 2 digits as I as for:
double dd = Math.Round(1.66666, 2);
Result:
dd = 1.6699999570846558;
and then I created a new project with same .NET framework and the result is 1.67 now as it should been in the first place.
I've never seen Round behaving like this before, what is causing this problem?
Like the other comments mentioned, use decimal to hold the returned value:
decimal dd = Math.Round(1.66666M, 2);
The issue you described has nothing to do with the Round() function. You can read a bit about how the floating point numbers & fixed point numbers work, but the short explanation is:
With floating point variables (e.g. double), you cannot guarantee the precision of the number you save it them. So when you save something like 1.67 in a variable of the type double and then you check the value later on, therer is no guarantee you will get exactly 1.67. You may get a value like 1.66999999 (similar to what you got) or like 1.6700000001.
Fixed point variables (e.g. decimal) on the other hand, will give you that precision, so if you save 1.67, you will always get 1.67 back.
Please note that the Round() function returns the same type that you pass to it, so to make return a decimal, you need to pass it 1.66666M which is a decimal value rather than 1.66666 which is a floating point number.

Categories

Resources