StringBuilder.Append with float

时间:2010-01-12 20:26:30

标签: c# asp.net

使用StringBuilder.Append

float正在截断该值。它转换为什么以及如何阻止它被截断?

AttributeOrderfloat类型,在构建字符串时我会失去精确度。

if ( AttributeOrder != 0 ) 
{ 
    if ( Result.Length > 0 ) 
    { 
        Result.Append( " AND " ); 
    } 
    Result.Append( COLUMN_ATTRIBUTE_ORDER ); 
    Result.Append( "=" ); 
    Result.Append( AttributeOrder ); 
} 
编辑:这是遗留代码,我无法更改基础数据类型。 SQL Server中的列是实数,数据类型是float。我需要在填充时提供float作为字符串用于其他目的而不是松散的精度。

5 个答案:

答案 0 :(得分:4)

您可以使用format stringfloat转换为字符串,如下所示:

Result.Append(AttributeOrder.ToString("G9"))

或者,或者,

Result.AppendFormat("{0}={1:G9}", COLUMN_ATTRIBUTE_ORDER, AttributeOrder)

但是,float您将无法获得超过9位数的精度,而数字8和9将不准确。


float datatype只能保持七位精度。只要将值放入float变量,就会无法精确地丢失精度。要从SQL Server存储所有24位数的精度,您需要使用decimal datatype

将变量更改为decimal后,Append会为您提供尽可能多的数字。

答案 1 :(得分:2)

如果您需要提供浮点数的表示,那么您应该使用System.Decimal - System.Single无法准确表示您要显示的精度。< / p>

这个简单的例子说明了不同之处:

using System;   

class Test
{
    static void Main()
    {
        Single s = 1.23456789f;
        Decimal d = 1.23456789m;

        Console.WriteLine(s);
        Console.WriteLine(d);
    }
}

答案 2 :(得分:2)

让我们对花车有一些乐趣,看看为什么这不起作用。

假设24位数字1.23456789012345678901234从SQL real读取到.Net float

浮点值在二进制文件中如下所示:0 01111111 00111100000011001010010

第一个0是符号位,表示该数字为正数。 01111111是偏差指数,表示有效数乘以2 ^ 0(或1)。 00111100000011001010010是数字的数字,减去第一位。

所以float变量现在以二进制编码1.00111100000011001010010。

让我们看看当我们将浮动转换为十进制时会发生什么。

1 * 1 =                         1
.
0 * 0.5 =                       0
0 * 0.25 =                      0
1 * 0.125 =                     0.125
1 * 0.0625 =                    0.0625
1 * 0.03125 =                   0.03125
1 * 0.015625 =                  0.015625
0 * 0.0078125 =                 0
0 * 0.00390625 =                0
0 * 0.001953125 =               0
0 * 0.0009765625 =              0
0 * 0.00048828125 =             0
0 * 0.000244140625 =            0
1 * 0.0001220703125 =           0.0001220703125
1 * 0.00006103515625 =          0.00006103515625
0 * 0.000030517578125 =         0
0 * 0.0000152587890625 =        0
1 * 0.00000762939453125 =       0.00000762939453125
0 * 0.000003814697265625 =      0
1 * 0.0000019073486328125 =     0.0000019073486328125
0 * 0.00000095367431640625 =    0
0 * 0.000000476837158203125 =   0
1 * 0.0000002384185791015625 =  0.0000002384185791015625
0 * 0.00000011920928955078125 = 0
                                ------------------------
                                1.2345678806304931640625

因此,如果我们显示所有的浮点数位数,我们得到1.2345678806304931640625。 那么这不是我们要显示的数字吗?为什么要将这个数字四舍五入?为什么这个值与我们开始时的数量不同?

要了解原因,让我们逐步查看几个相邻的浮点值:

binary floating point representation   decimal representation
------------------------------------   ----------------------
0 01111111 00111100000011001010000   = 1.2345676422119140625
0 01111111 00111100000011001010001   = 1.23456776142120361328125
0 01111111 00111100000011001010010   = 1.2345678806304931640625
0 01111111 00111100000011001010011   = 1.23456799983978271484375
0 01111111 00111100000011001010100   = 1.234568119049072265625

如您所见,完全相同的浮点数用于表示此范围内的所有值:[1.234567821025848388671875,1.234567940235137939453125]

因此,在转换为float期间,第八个之后的任何十进制数字都会丢失,并且任何可能显示的十进制数字都是完全没有意义的,并且与正在表示的实际值无关。

超过第八个的所有十进制数字都是四舍五入到二进制并转换为十进制的工件,它们没有实际意义。

答案 3 :(得分:0)

您可以随时在浮动上使用ToString()方法,如下所示:

if ( AttributeOrder != 0 ) 
{ 
    if ( Result.Length > 0 ) 
    { 
        Result.Append( " AND " ); 
    } 
    Result.Append( COLUMN_ATTRIBUTE_ORDER ); 
    Result.Append( "=" ); 
    Result.Append( AttributeOrder.ToString("0.000000") ); 
} 

例如,上面的格式说明符显示了6位小数。如果您不想显示尾随零,请将0替换为#

答案 4 :(得分:0)

你可以用string.Format()杀死多只鸟。减少代码行,并将数字显示为任意精度。

Result.Append(string.Format("{0}={1:0.000000}", COLUMN_ATTRIBUTE_ORDER, AttributeOrder));