字符串转float的精度疑问:为何转换后末位为8而非7?
float.Parse("0,0001234567890") return 0,0001234568 instead of 0,0001234567? Great question! Let's break this down step by step—this behavior ties directly into how IEEE 754 single-precision float works under the hood, and it's a common point of confusion with floating-point types.
First, the critical detail to wrap your head around: float stores numbers in binary, not decimal. When we say float has ~7 decimal significant digits, that's an approximation of its binary precision—it doesn't mean every 7-digit decimal number can be stored exactly.
Let's walk through your example:
- Your input string
0,0001234567890(assuming the comma is a locale-specific decimal separator, equivalent to0.0001234567890in standard notation) translates to1.234567890 × 10^-4in scientific notation, with significant digits:1,2,3,4,5,6,7,8,9,0.
What happens during conversion?
When you run float.Parse(), the runtime has to find the closest valid binary float value to your input decimal number. Since 0.0001234567890 can't be represented exactly in binary floating-point (most decimal fractions can't), it picks the nearest possible float value.
The closest float to your input is actually a tiny bit larger than 0.0001234567890. When we convert this binary value back to a decimal string with 7 significant digits, the 8th digit in your original number (9) triggers a round-up:
- The first 7 significant digits of your input are
1234567, but the approximatedfloatvalue is close enough to1.234568 × 10^-4(aka0.0001234568) that rounding to 7 significant digits pushes the 7th digit from7to8.
Why does this rounding happen?
IEEE 754 single-precision float uses 24 bits of mantissa (23 stored + 1 implicit leading bit). This translates to approximately 7.22 decimal significant digits. For your input value (~1e-4), this means:
- The smallest increment a
floatcan represent is roughly1e-4 × 1e-7 = 1e-11. - The 8th significant digit in your original number contributes
8 × 10^-11to the total value—this is larger than thefloat's smallest increment, so the conversion has to choose between rounding up or down. In this case, rounding up gives the closer match to your input.
If you printed the exact decimal representation of the float you get, you'd see something like 0.00012345679931640625 (the exact value varies slightly by runtime). Truncating this to 7 significant digits naturally rounds to 0.0001234568.
内容的提问来源于stack exchange,提问作者T.Tomilos

