我有一个浮点数,比如1.2999
,当放入Convert.ToDecimal
时会返回1.3
。我想将数字转换为小数的原因是加法和减法时的精度,而不是舍入。我确信十进制类型可以保存该数字,因为它可以容纳大于浮点数的数字。
为什么要将数字四舍五入?反正有没有阻止它四舍五入?
编辑:我不知道为什么我的是四舍五入而你的不是,这是我的确切代码:
decNum += Convert.ToDecimal((9 * 0.03F) + 0);
我现在很困惑。当我进入调试器并查看(9 * 0.03F) + 0
部分的输出时,它将0.269999981
显示为float,但随后将其转换为0.27十进制。但我知道9%的3%是0.27。那么这是否意味着原始计算不正确,转换只是修复它?
该死的我非常讨厌数字哈哈!
答案 0 :(得分:7)
你说的话似乎没有发生。
这个程序:
using System;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
float f = 1.2999f;
Console.WriteLine(f);
Decimal d = Convert.ToDecimal(f);
Console.WriteLine(d);
}
}
}
打印:
1.2999
1.2999
我认为将值转换为字符串时可能会遇到问题。
或者,正如ByteBlast在下面所说,也许你给了我们错误的测试数据。
使用float f = 1.2999999999f;
打印1.3
原因是浮点值不够精确,无法准确表示1.299999999f
。该特定值最终被舍入为1.3
- 但请注意, float 值在转换为小数之前被舍入。
如果您使用的是double
而不是float
,除非您获得更多的精度数字(当您到达1.299999999999999
时),否则不会发生这种情况。
[编辑] 根据您修改后的问题,我认为这只是预期的舍入错误,所以请务必阅读以下内容:
有关详细信息,请参阅"What Every Computer Scientist Should Know About Floating-Point Arithmetic"。
Also see this link(Tim Schmelter在下面的评论中推荐)。
另一件需要注意的事情是,调试器可能会将数字显示为与默认double.ToString()
(或等效)不同的精度级别,这样可能会导致您看到的数字略有不同。
除了:
您可能会对“往返”格式说明符运气不错:
Console.WriteLine(1.299999999999999.ToString());
Prints 1.3
可是:
Console.WriteLine(1.299999999999999.ToString("r"));
Prints 1.2999999999999989
(请注意,倒数第二位的偷偷摸摸的小8!)
为获得最高精确度,您可以使用the Decimal
type,就像您已经在做的那样。这针对基数为10的数字进行了优化,并提供了更多的精确数字。
但请注意,它比float
或double
慢了几百倍,并且它也会受到舍入错误的影响,尽管要少得多。