检查一下:这个小的.NET控制台程序会产生有趣的结果......请注意我是如何以两种不同的方式将浮点数转换为整数:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace CastVsConvert
{
class Program
{
static void Main(string[] args)
{
int newWidth = 0;
CalculateResizeSizes(600, 500, out newWidth);
}
static void CalculateResizeSizes(int originalWidth, int maxWidth, out int newWidth)
{
float percentage = 1.0F;
percentage = maxWidth / (float)originalWidth;
newWidth = (int)((float)originalWidth * percentage);
int newWidthConvert = Convert.ToInt32((float)originalWidth * percentage);
Console.Write("Percentage: {0}\n", percentage.ToString());
Console.Write("Cast: {0}\n", newWidth.ToString());
Console.Write("Convert: {0}\n", newWidthConvert.ToString());
}
}
}
我希望“Cast”和“Convert”的输出相同,但它们不是......这是输出:
C:\Documents and Settings\Scott\My Documents\Visual Studio 2008\Projects\CastVsC
onvert\CastVsConvert\bin\Debug>CastVsConvert.exe
Percentage: 0.8333333
Cast: 499
Convert: 500
有人知道为什么.NET会在这里返回不同的值吗?
答案 0 :(得分:14)
它不是一个错误,cast
截断,convert
轮。
请参阅this
答案 1 :(得分:5)
当转换为四舍五入时,演员正在切掉小数点后面的数字部分。
答案 2 :(得分:5)
来自Convert.ToInt32的返回值的文档:
value 四舍五入为最接近的32位有符号整数。如果价值是中途 在两个整数之间,偶数 号码被退回;也就是说,4.5是 转换为4,转换为5.5 到6。
投射不会向上舍入 - 它只是截断。乘法的结果略低于500,因此转换将截断为499,而Convert.ToInt32将其舍入为500。
答案 3 :(得分:1)
有一个额外的,隐藏的演员可能会导致这个。例如,如果您使用此而不是重新计算:
int newWidthConvert = Convert.ToInt32(newWidth);
你会得到相同的结果。当您使用Reflector查看Convert.ToInt32(float)
:
public static int ToInt32(float value)
{
return ToInt32((double) value);
}
Double
有一个隐藏的演员。
如果您添加几行进行调查,请使用调试器来查看,您会看到会发生什么:
float newWidth1 = ((float)originalWidth * percentage);
double newWidth2 = ((float)originalWidth * percentage);
double
更精确,并将值保存为499.999999和更多的十进制数字。 float
不太精确,存储500.0。整数转换会截断小数部分,因此基于中间强制转换最终会得到500或499。当您致电Convert.ToInt32()
时,结果已投放到float
,因此您获得了500.0的Double
表示。我个人更喜欢在可以的时候总是使用double
。