C# 为什么float.TryParse()接受;1.000e-45“;并将其四舍五入到1.401298E-45?

C# 为什么float.TryParse()接受;1.000e-45“;并将其四舍五入到1.401298E-45?,c#,floating-point,.net-framework-version,tryparse,C#,Floating Point,.net Framework Version,Tryparse,我尝试验证输入字符串是否为浮点。为了实现这一点,我传递输入字符串“1.000e-45”,它比c#float最小允许值(1.401298E-45)更接近0。我希望float.tryParse返回false。相反,它返回true,解析后的数字向上舍入到浮点最小值(1.401298E-45)。如果字符串包含更低的数字,则float.TryParse()似乎向下舍入为0 我错过什么了吗 我可以做些什么来验证像这样的低数字不被解释为浮动 var isFloat = float.TryParse("

我尝试验证输入字符串是否为浮点。为了实现这一点,我传递输入字符串“1.000e-45”,它比c#float最小允许值(1.401298E-45)更接近0。我希望float.tryParse返回false。相反,它返回true,解析后的数字向上舍入到浮点最小值(1.401298E-45)。如果字符串包含更低的数字,则float.TryParse()似乎向下舍入为0

我错过什么了吗

我可以做些什么来验证像这样的低数字不被解释为浮动

var isFloat = float.TryParse("1.000e-45", NumberStyles.Float, CultureInfo.InvariantCulture, out var number);
更新:用户输入必须是字符串中的浮点数。由于规格的原因,不允许具有更高的精度。把它想象成某种API,它给了我一个字符串,应该是一个浮点值。我必须验证它是否在浮动范围内

更新2:这不是关于浮点精度的问题。我知道你不可能有100%的精度,因为二进制方面和尾数的大小。正如我在问题中所说的,我知道浮点数最接近0的值。我只是没想到TryParse()在接近0时会这样舍入。我以为它会失败

更新3:我希望这能让事情变得更清楚。这是我必须遵循的规范

  • 输入是一个字符串。字符串表示一个数字。比如“3.45e12”
  • 该数字不允许超出“±3.4028235e+38”的范围
  • magnitute中的数字不得小于“±1.401298e-45”。这就是规范中所说的,“0”也是允许的,但不是像“1e-100”或“1e-46”这样的东西
  • 我要做的是验证用户输入(字符串)是否符合此规范。我不必将字符串数字转换成c#数字类型并用它进行计算。我只需要验证输入的字符串编号,然后将字符串编号发送到API。当字符串与规范不匹配时,此api将出现问题
  • 我尝试使用float.TryParse()进行此验证。它适用于最小/最大范围(.Net Framework)。但这似乎是错误的做法。float.TryParse()对于比实际表示更接近0的数字字符串,将始终返回true,并将结果四舍五入以适应浮点:它向下四舍五入到0(例如对于“1e-46”),或向上四舍五入到1.401298E-45(例如对于“1e-45”)。这在某种程度上是有意义的,因为当它无法处理像“9999999999999.9”这样不高于最大值且不太接近0的值的精度时,它也会这样做。它将其舍入为1e13

我错过了什么吗?你错过了浮点规范……如果你想获得更好的精度,请使用
double
如果你希望
TryPass
只在可以表示的数字上成功,你会期望它在
0.1
上也失败吗?@Sinatr不,这对接近零的数字不适用.我认为您的代码有输入错误(即,您使用了
MinValue
两次)。对不起,我有点仓促。这是一个合法的问题。@AronCederholm:实际的最小正浮点数不是1.401298e-45,而是1.4012984643248170923729583991613128026194187651577175706828388979910826858606014866381883621582203125E-45,所以其中的一半是7.00649232162240853518647644949580656401309709828878534141944895541342930300743319094181060791015625625E-46。