简体   繁体   English

C#字符串浮点转换无效?

[英]c# string to float conversion invalid?

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

gives me 333333333 给我333333333

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

gives me 333333344 给我333333344

Any ideas why? 有什么想法吗?

This happens because Single does not have enough precision to store your full number. 发生这种情况是因为Single精度不足以存储您的完整号码。

Double has more precision. Double精度更高。

From the docs for System.Single : System.Single的文档中:

All floating-point numbers have a limited number of significant digits, which also determines how accurately a floating-point value approximates a real number. 所有浮点数都有有限数量的有效数字,这也决定了浮点值逼近实数的精度。 A Double value has up to 7 decimal digits of precision, although a maximum of 9 digits is maintained internally. 尽管内部最多保留9位数字,但Double值的精度最高为7位十进制数字。

It actually means Single here rather than Double , but the point is that you're trying to use it for 9 significant digits, and that's not guaranteed to be available. 实际上,这里的意思是 Single而不是Double ,但要点是您要尝试将其用于9个有效数字,并且不能保证该数字可用。 You can see this very easily without any parsing: 您可以很容易地看到这一点,而无需任何解析:

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

("r" is the "round-trip" format specifier.) (“ r”是“往返”格式说明符。)

In other words, the closest float value to the exact decimal value of 333333333 is 333333344. 换句话说,最接近于十进制值333333333的最接近float值为333333344。

If you were to use Double instead, that would probably retain all the digits, but that doesn't mean it's the right approach necessarily. 如果要改用Double ,则可能会保留所有数字,但这并不意味着它一定是正确的方法。 It depends on the value. 这取决于值。 Is it actually always an integer? 实际上总是一个整数吗? Maybe you should be using long . 也许您应该使用long Is it a non-integer, but financial data (or some other "artificial" value)? 它是非整数但财务数据(或其他“人造”值)吗? If so, consider using decimal . 如果是这样,请考虑使用decimal

Also, why are you having to convert this to a string and parse it? 另外,为什么还要将其转换为字符串并进行解析? What's the execution time type of dr["NationalTotal"] ? dr["NationalTotal"]的执行时间类型是什么? You may be able to just cast - avoid using string conversions where you don't need to. 您也许可以进行转换-避免在不需要的地方使用字符串转换。

The floating point specification says that the 32 bit representation of a floating point number is 浮点规范指出,浮点数的32位表示为

在此处输入图片说明

Thus, the largest integer that can be represented without loss of (integer) accuracy is 16777216 (0x1000000). 因此,可以表示而不损失(整数)精度的最大整数是16777216(0x1000000)。 A simple test program to convince you that this is so: 一个简单的测试程序可以说服您:

#include <stdio.h>

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);
}

Output: 输出:

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

EDIT Based on the comments underneath the question, we slowly converged on the fact that you had two questions, not one. 编辑根据问题下方的评论,我们逐渐趋同于一个事实,即您有两个问题,而不是一个。

The first: "Why is this happening?" 第一个:“为什么会这样?” is answered with the above. 以上回答。 A single float simply is not able to represent 333333333 exactly, so you get the nearest representable value, which is 333333344 . 单个浮点数不能完全准确地表示333333333 ,因此您获得了最接近的可表示值333333344

The second: "How do I fix it?" 第二个:“我该如何解决?” was initially answered by me in the comments - I will reprise my answer here: 最初由我在评论中回答-我将在这里重新回答我的问题:

Your database floating point number is not typically single precision - in fact, by default it is double precision. 数据库浮点数通常不是单精度的-实际上,默认情况下是双精度的。 Thus, you solve your problem by converting the string to double, and assigning it to a double precision variable: 因此,您可以通过将字符串转换为double并将其分配给double precision变量来解决问题:

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

I would like to refer you to http://floating-point-gui.de/ - "what every programmer should know about floating point". 我想向您推荐http://floating-point-gui.de/- “每个程序员都应了解的浮点知识”。 There are actually many guides out there with similar names. 实际上,那里有许多名称相似的指南。 Essential reading if you ever stray from using just integers (and most people will, at some point in their programming career). 如果您不喜欢仅使用整数,那么这是必不可少的阅读内容(大多数人在编程生涯的某个时候会使用它)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM