c#string to float conversion无效?

var x = dr["NationalTotal"].ToString(); 

给了我333333333

 var xxx = Convert.ToSingle(dr["NationalTotal"].ToString()); 

给了我333333344

有什么想法吗?

浮点规范表明浮点数的32位表示是

在此处输入图像描述

因此,可以在不损失(整数)精度的情况下表示的最大整数是16777216(0x1000000)。 一个简单的测试程序,以说服你这样做:

 #include  int main(void) { float x; unsigned long j; j = 0x00FFFFFC; int i; x = j; for(i=0; i<10;i++) printf("%ld + %d = %f\n", j, i, x+i); } 

输出:

 16777212 + 0 = 16777212.000000 16777212 + 1 = 16777213.000000 16777212 + 2 = 16777214.000000 16777212 + 3 = 16777215.000000 16777212 + 4 = 16777216.000000 16777212 + 5 = 16777216.000000 <<< from here on, adding one more doesn't give the right answer 16777212 + 6 = 16777218.000000 16777212 + 7 = 16777220.000000 16777212 + 8 = 16777220.000000 16777212 + 9 = 16777220.000000 

编辑根据问题下面的评论,我们慢慢收敛于你有两个问题,而不是一个问题。

第一个:“为什么会这样?” 回答以上问题。 单个浮点数根本无法准确表示333333333 ,因此您将获得最接近的可表示值,即333333344

第二个:“我该如何解决?” 最初由我在评论中回答 - 我将在这里重申我的答案:

您的数据库浮点数通常不是单精度 - 实际上,默认情况下它是双精度。 因此,您可以通过将字符串转换为double并将其分配给双精度变量来解决您的问题:

 double xxx = Convert.ToDouble(dr["NationalTotal"]); 

我想请你参考http://floating-point-gui.de/ - “每个程序员应该知道浮点数”。 实际上有很多指南都有相似的名字。 如果你偏离使用整数(大多数人会在他们的编程生涯中的某些时候),那么必要的阅读。

发生这种情况是因为Single没有足够的精度来存储您的完整数字。

Double精度更高。

System.Single的文档:

所有浮点数都具有有限的有效位数,这也决定了浮点值接近实数的精确程度。 Double值最多包含7个十进制数字的精度,但内部最多保留9位数。

它实际上意味着 Single而不是Double ,但重点是你试图将它用于9位有效数字,并且不能保证可用。 你可以很容易地看到这一点而无需任何解析:

 float f = 333333333f; Console.WriteLine("{0:r", f); // Prints 333333344 

(“r”是“往返”格式说明符。)

换句话说,最接近的精确十进制值333333333的float值是333333344。

如果您要使用Double ,那么可能会保留所有数字,但这并不意味着它必然是正确的方法。 这取决于价值。 它实际上总是一个整数吗? 也许你应该使用long 。 它是非整数,但是财务数据(或其他一些“人为”价值)? 如果是这样,请考虑使用decimal

另外,为什么你必须将它转换为字符串并解析它? 什么是dr["NationalTotal"]的执行时间类型? 您可能只需要强制转换 – 避免在不需要的地方使用字符串转换。