I have a problem with conversion from double to decimal:
public class CartesianCoordinates
{
public int LatitudeHours { get; set;}
public int LatitudeMinutes { get; set; }
public int LatitudeSeconds { get; set; }
public GeoDirectionLongtitude LongitudeDirection { get; set; }
public int LongitudeHours { get; set; }
public int LongitudeMinutes { get; set; }
public int LongitudeSeconds { get; set; }
public GeoDirectionLatitude LatitudeDirection { get; set; }
}
public class DecimalCoordinates
{
public decimal Latitude { get; set; }
public decimal Longitude { get; set; }
}
CartesianCoordinates CartesianCoordinates=new CartesianCoordinates(){LatitudeHours =12,LatitudeMinutes =34,LatitudeSeconds=56 }
converterDecimalCoordinates.Latitude = CartesianCoordinates.LatitudeHours + (Cartesia开发者_C百科nCoordinates.LatitudeMinutes + (CartesianCoordinates.LatitudeSeconds / 60)) / 60;
Why I get 12 ? I want 12,55
All your calculations are integer ones and are being rounded (ore more accurately, truncated). Try replacing your literal values of 60 with 60m
to force a decimal calculation, or 60.0
to force a double calculation (in which case you'll need to convert to a decimal at the end).
Int32 x = 10;
Decimal y = x / 4; // Performs an integer devision - result is 2.0
Decimal z = x / 4M; // Performs a decimal devision - result is 2.25
You get an integer devision if both operands are integers. By adding the suffix M
to a number you can explicitly state that the number should be interpreted as a decimal number and therefore you will get a decimal devision.
As a byproduct of my discussion with David M and Daniel Brückner under this answer and the partially wrong statement by myself under this answer by Adam, it has become clear that, sorry to say, all answers are only partially correct. What is happening is this:
// example (all x, y, z ar ints):
Decimal d = x + y + z / 60M;
// is left to right evaluated as
Decimal d = x + y + (((Decimal) z) / 60M);
// when doing addition, this is what happens when you add integers and something else:
Decimal d = x + y + (int) (((Decimal) z) / 60M);
// which will yield a truncated result.
The result is: that just adding a 60M
or 60.0
to the whole statement, as has been suggested, will not (or may not) yield the wanted result, depending on execution order of the statement and/or the existence of addition / subtraction, as is the case in the OP's question.
To fix this, follow Adam's advice and convert each addition / subtraction step to decimals, use decimals all along (not very clear) or place the calculation in a little function that takes decimals as parameters, forcing implicit conversion:
Decimal GetDecimalLatitude(Decimal latitudeHours, Decimal latitudeMinutes, Decimal latitudeSeconds)
{
return latitudeHours + (latitudeMinutes + (latitudeSeconds / 60)) / 60;
}
which, as a bonus, is shorter and adds to readability. Call this with the following statement:
converterDecimalCoordinates.Latitude = GetDecimalLatitude(
CartesianCoordinates.LatitudeHours,
CartesianCoordinates.LatitudeMinutes,
CartesianCoordinates.LatitudeSeconds);
You get 12 because the calculation is operating on int
types for certain parts of it and thus isn't able to contain the precision - the value gets truncated to an int
. I would convert all your values into decimals prior to calculating - or as other answers have suggested, specify your literals as decimal numbers.
Update: as highlighted in other posts, this is currently performing an integer division - I wasn't aware of the technical term, so like you, I've learnt something today lol
As the others already mentioned you have on both sides of your division an integer. So the result is also an integer (which will then implicit converted to a decimal for the left hand side). To solve this problem, one side of your division has to be an decimal, causing that the decimal division is taken. So simply try this line of code:
converterDecimalCoordinates.Latitude = CartesianCoordinates.LatitudeHours + (CartesianCoordinates.LatitudeMinutes + (CartesianCoordinates.LatitudeSeconds / 60)) / (decimal)60;
精彩评论