float value looses data after converting from double - c#

I have a double var represnting the seconds passed since 01/01/1900 from an ntp server and it prints ok
3616290958.594
3616290959.611
3616290960.538
I tried to convert it to a float in different methods like System.Convert.ToSingle and regular casting but I always get
3,616,291,000.00
I print the float using it's .ToString("N") method if it makes a difference
I even tried converting the double to a long, then the long to the float (I don't need any precision data after the dot, I'm going to floor the double before converting anyway).
nothing works, help.

You can simply use Math.Truncate
Example:
Double d = 3616290958.594;
string k = Math.Truncate(d);

Related

Loss of data converting a UInt64 to float in C#

I am attempting to do some mat on two UInt64 values and store the result in a float:
UInt64 val64 = 18446744073709551615;
UInt64 val64_2 = 18446744073709551000;
float val = (float)val64 - val64_2;
Console.WriteLine(val64);
Console.WriteLine(val.ToString("f"));
Console.ReadKey();
I am expecting the val to be 615.0 but instead I am getting 0.0!
Using double instead for val seems to work but surely float is capable of storing 615.0. What am I missing here?
It's not the result that is being truncated, it's the values used in the calculation. You are casting val64 to a float in your sum. This also means val64_2 will be cast to a float (to match val64). Both have lost enough precision that they are the same value when represted as a float, and the difference is 0.
You want to keep them as UInt64 for the subtraction, and have the result as a float. i.e.
float val = (float)(val64 - val64_2);
Float is an approximation that can store only 6 or 7 significant digits (see https://msdn.microsoft.com/en-us/library/hd7199ke.aspx)
In your code both UInt64s end up as 1.84467441E+19 when cast to float.
As various people have already mentioned the solution is to keep the values as UInt64s for the subtraction.

Float / Float = strange result

I have two values, one from user input and another from DB.
var userinput = form["someInput"];
var valuefromDB = GetValue(someNumber);
public float? GetValue(int id){
return (float?) db.table.where(p=> p.id == id).select(p=> p.Value).SingleOrDefault();
}
userinput have value "1" as string, while valuefromDB havevalue 0.001 as float.
so 1 / 0.001 = 1000
but my c# code give me 999.999939 as result;
var final = float.Parse(userinput) / valuefromDB
when i have "2" as user input value, result is correct, 2000...
That's because not all decimal numbers can be accurately represented in binary (which is the representation that float uses). The solution is to format the result to the desired number of decimal places, which will cause it to be rounded and displayed "correctly" as a consequence.
Update: To format a float for display, take a look at this MSDN reference page and this page of examples.
For pure precision which is not provided by float use decimal instead.
See What is the difference between Decimal, Float and Double in C#?

to compare double and decimal should I cast double to decimal or decimal to double?

I need to compare two values.
One value is price which represents current price of something and so decimal because you actually can buy or sell something by this price.
Another value is estimatedPrice which is the result of mathematical calculations and so double because it's just estimation and you can not actually do any "operations" by this esitmatedPrice
now i want to buy if price < estimatedPrice.
So should i cast price to double or estimatedPrice to decimal?
I understand that after casting I will get "slighty another" numbers, but it seems I don't have other options.
It depends on the data. Decimal has greater precision; double has greater range. If the double could be outside the decimal range, you should cast the decimal to double (or indeed you could write a method that returns a result without casting, if the double value is outside the decimal range; see example below).
In this case, it seems unlikely that the double value would be outside the decimal range, so (especially since you're working with price data) you should cast the double to decimal.
Example (could use some logic to handle NaN values):
private static int Compare(double d, decimal m)
{
const double decimalMin = (double)decimal.MinValue;
const double decimalMax = (double)decimal.MaxValue;
if (d < decimalMin) return -1;
if (d > decimalMax) return 1;
return ((decimal)d).CompareTo(m);
}
decimal vs double! - Which one should I use and when?
If you're more concerned with precision, convert to decimal. If you're not, go with doubles.
I've never worked with prices before in software, but from what I've heard, many deal with integers. For example, for $1.23, store it as the integer 123. The conversion to a decimal is done at the very end when you output results to the user.
Similarly, for your estimated price, can you deal with numbers that are (say) 100 times larger?
I recommend you to convert to decimal. because it seems you want manipulate money values. but I can give this short answer : for accurate (manipulating money value specially for financial applications) application use decimal. and if you prefer less resource and more speed use double.

How to get floats value without including exponential notation

In C#, is it possible to perform ToString on a float and get the value without using exponentials?
For example, consider the following:
float dummy;
dummy = 0.000006F;
Console.WriteLine(dummy.ToString());
This gives the output
6E-06
However, what I was is
0.000006
The closest I could find was using the "F" qualifier, however I then need to specify the number of decimal places otherwise the value get rounded.
Is there actually a way of doing this automatically or do I need to do a load of funky logic to either trim zeroes or figure out the number of required decimals.
Thanks;
Richard Moss
Try this
Console.WriteLine(dummy.ToString("F"));
You can also specify number of decimal places. For example F5, F3, etc.
Also, you can check custom format specifier
Console.WriteLine(dummy.ToString("0.#########"));
string dum = string.Format("{0:f99}",dummy).TrimEnd('0');
if (dum.EndsWith(",")) dum = dum.Remove(dum.Length - 1);
Without some further background info, it's hard to tell - but it sounds like you want decimal semantics. So why not use the decimal type instead?
decimal dummy;
dummy = 0.000006M;
The decimal type is more accurate at representing decimal numbers than float or double, but it is not as performant. See here for more info.
Console.WriteLine(dummy.ToString("N5"));
where 5 its number of decimal places
float dummy = 0.000006F;
Console.WriteLine(dummy.ToString("0." + new string('#', 60)));
If you'll be doing this a lot then it makes sense to store the format string in a static field/property somewhere and re-use it, rather than constructing a new string every time:
private static readonly string _allFloatDigits = "0." + new string('#', 60);
// ...
float dummy = 0.000006F;
Console.WriteLine(dummy.ToString(_allFloatDigits));

Division in c# not going the way I expect

Im trying to write something to get my images to show correctly.
I have 2 numbers "breedtePlaatje" and "hoogtePlaatje". When i load those 2 vars with the values i get back "800" and "500" i expect "verH" to be (500 / 800) = 0,625. Tho the value of verH = 0..
This is the code:
int breedtePlaatje = Convert.ToInt32(imagefield.Width);
int hoogtePlaatje = Convert.ToInt32(imagefield.Height);
//Uitgaan van breedte plaatje
if (breedtePlaatje > hoogtePlaatje)
{
double verH = (hoogtePlaatje/breedtePlaatje);
int vHeight = Convert.ToInt32(verH * 239);
mOptsMedium.Height = vHeight;
mOptsMedium.Width = 239;
//Hij wordt te klein en je krijgt randen te zien, dus plaatje zelf instellen
if (hoogtePlaatje < 179)
{
mOptsMedium.Height = 179;
mOptsMedium.Width = 239;
}
}
Any tips regarding my approach would be lovely aswell.
Dividing int by int gives an int.
double verH = (hoogtePlaatje/breedtePlaatje);
The right hand side of the assignment is an integer value.
Change breedtePlaatje and/or hoogtePlaatje to double and you will get the answer you expect.
Integer division will result in an Integer being returned as the division result.
You need one of the parameters of the division to be a float in order for the result to be a float. You can do this by casting one of them to a float.
double verH = (double)hoogtePlaatje/breedtePlaatje;
Or
double verH = hoogtePlaatje/(double)breedtePlaatje;
See the C# spec regarding division.
When you divide two integers, C# uses integer division, where the fractional part is discarded. In your case you're getting:
500 / 800 = 0 + 5/8
Which, discarding the fractional part, gives:
500 / 800 = 0
To get floating point division, cast one of the arguments to either double, float or decimal depending on the level of precision you need, which will cause the other argument to be implicitly converted to the same type and the division carried out using floating point rules instead of integer rules, e.g.
double result = (double)breedtePlaatje / hoogtePlaatje ;
I have never used C#, but probably you will need to cast one of the variables to double, like this:
double verH = (double)hoogtePlaatje/breedtePlaatje;
Try this:
double verH = double (hoogtePlaatje) / breedtePlaateje;
If you divide an int by an int, you will get a truncated answer. Cast one of them up to a double, and the entire division will be done as double.

Categories