2010-07-14 73 views
3

我有一个转换的问题,从双到小数点:双转换为十进制

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 + (CartesianCoordinates.LatitudeMinutes + (CartesianCoordinates.LatitudeSeconds/60))/60; 

为什么我得到12?我想要12,55

回答

3

由于我同大卫·M和丹尼尔·布鲁克纳under this answerthis answer by Adam下的部分错误声明自己讨论的副产品,它已成为明确表示,抱歉地说,所有的答案只是部分正确。正在发生的事情是这样的:

// 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. 

结果是:这只是增加一个60M60.0整个语句,has been suggested,不会(或可能不会)产生想要的结果,这取决于执行顺序声明和/或加/减的存在,就像OP的问题一样。

为了解决这个问题,请按照亚当的建议,将每个加法/减法步骤小数,使用小数一直(不是很清楚),或放置在一个小函数,它的小数位参数的计算,迫使隐式转换:

Decimal GetDecimalLatitude(Decimal latitudeHours, Decimal latitudeMinutes, Decimal latitudeSeconds) 
{ 
    return latitudeHours + (latitudeMinutes + (latitudeSeconds/60))/60; 
} 

作为奖励,它更短,并增加了可读性。用下面的语句调用它:

converterDecimalCoordinates.Latitude = GetDecimalLatitude(
    CartesianCoordinates.LatitudeHours, 
    CartesianCoordinates.LatitudeMinutes, 
    CartesianCoordinates.LatitudeSeconds); 
+0

+1隐式铸造//高尔夫拍手 – 2010-07-14 10:48:57

9

所有的计算都是整数,并且被四舍五入(更准确地说,被截断)。尝试用60m替换60的文字值以强制十进制计算,或者60.0强制进行双重计算(在这种情况下,您需要在最后转换为小数)。

+4

只是一个注释,在预期的意义上这些值不是四舍五入的 - 更多的截断。 1.99将投1为一个整数。 – 2010-07-14 10:01:50

3

您得到12是因为计算在int类型上对其某些部分进行操作,因此无法包含精度 - 将值截断为int。在计算之前,我会将所有值转换为小数 - 或者如其他答案所示,将文字指定为十进制数。

更新:在其他职位强调,这是目前执行整数除法 - 今天的东西LOL我不知道技术术语,所以喜欢你,我已经学会

+1

它只需要一位小数在计算中做小数计算。转换所有这些都有点麻烦。 – Abel 2010-07-14 10:07:02

+0

说实话,我没有太在意计算本身的细节 - 但我确实明白由于整数除法引入的精度损失 - 其他答案自澄清了这一点。此外,像这样的计算通常会增加可读性,代价是麻烦一点,这是一个很好的权衡IMO。我没有爱:-) – 2010-07-14 10:10:26

+0

我错了,部分地,你确实得到了你应得的爱(和积分+1),我扩大了评论线程的答案;-) – Abel 2010-07-14 10:47:13

7
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 

如果两个操作数都是整数,则会得到整数分解。通过将后缀M添加到数字中,您可以明确指出该数字应该被解释为十进制数,因此您将得到一个十进制数。

+1

我经常碰到'Decimal x = 1M * [.. your calculation ..]'这是一种快速简单的方法,通过将转换字面置于前面来提高可读性和健壮性,防止无意编辑。 – Abel 2010-07-14 10:10:55

+0

@Abel - 没有帮助,在这种情况下,计算仍将以整数除法执行。通过乘法后转换为小数不会影响结果。 – 2010-07-14 10:12:02

+0

@大卫M:它确实有效。试试这个语句,它会在'x'中产生2.5M:'Decimal x = 1M * 5/2;'*(PS:我现在明白你的意思:它取决于计算和执行顺序,可能并不总是一个好主意然后)*。 – Abel 2010-07-14 10:14:28

1

正如其他人已经提到,你的部门双方都有一个整数。所以结果也是一个整数(然后隐式转换为左边的小数)。为了解决这个问题,你的部门的一方必须是一个小数,导致十进制除法。所以,简单地尝试这行代码:

converterDecimalCoordinates.Latitude = CartesianCoordinates.LatitudeHours + (CartesianCoordinates.LatitudeMinutes + (CartesianCoordinates.LatitudeSeconds/60))/(decimal)60;