C# StringBuilder.Append与float
C# StringBuilder.Append与float,c#,asp.net,C#,Asp.net,StringBuilder.Append使用float将截断该值。它转换为什么?如何阻止它截断 AttributeOrder是类型float,我在构建字符串时会丢失精度 if ( AttributeOrder != 0 ) { if ( Result.Length > 0 ) { Result.Append( " AND " ); } Result.Append( COLUMN_ATTRIBUTE_ORDER ); Re
StringBuilder.Append
使用float
将截断该值。它转换为什么?如何阻止它截断
AttributeOrder
是类型float
,我在构建字符串时会丢失精度
if ( AttributeOrder != 0 )
{
if ( Result.Length > 0 )
{
Result.Append( " AND " );
}
Result.Append( COLUMN_ATTRIBUTE_ORDER );
Result.Append( "=" );
Result.Append( AttributeOrder );
}
编辑:这是遗留代码,我无法更改基础数据类型。SQL Server中的列是实数,数据类型为
float
。我需要在填充时将浮点数
表示为字符串,以用于其他目的,而不是像现在这样精度不高。您可以使用a将浮点数
转换为字符串,如下所示:
Result.Append(AttributeOrder.ToString("G9"))
if ( AttributeOrder != 0 )
{
if ( Result.Length > 0 )
{
Result.Append( " AND " );
}
Result.Append( COLUMN_ATTRIBUTE_ORDER );
Result.Append( "=" );
Result.Append( AttributeOrder.ToString("0.000000") );
}
或者,或者
Result.AppendFormat("{0}={1:G9}", COLUMN_ATTRIBUTE_ORDER, AttributeOrder)
但是,您将无法从浮点
中获得超过9位的精度,并且数字8和9将不准确
这个数字只能容纳七位数的精度。一旦将该值放入
float
变量中,就无法恢复精度。为了存储来自SQL Server的所有24位精度,您需要使用
一旦您将变量更改为
十进制
,Append
将为您提供输入的位数。您始终可以在浮点上使用ToString()
方法,如下所示:
Result.Append(AttributeOrder.ToString("G9"))
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
替换为
。如果需要提供浮点数的表示形式,则应使用系统。十进制
-系统。单个
无法准确表示要显示的精度
这个简单的例子显示了不同之处:
using System;
class Test
{
static void Main()
{
Single s = 1.23456789f;
Decimal d = 1.23456789m;
Console.WriteLine(s);
Console.WriteLine(d);
}
}
您可以使用
string.Format()
杀死多只鸟。减少代码行数,并以任意精度显示数字
Result.Append(string.Format("{0}={1:0.000000}", COLUMN_ATTRIBUTE_ORDER, AttributeOrder));
让我们玩一些花车的乐趣,看看为什么这不起作用 假设24位数字1.2345678901234567801234从SQL
real
读入.Netfloat
浮点值在二进制中如下所示:0 01111111 00111100000011001010010
第一个0
是符号位,表示数字为正数。
0111111
是有偏指数,表示有效位乘以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)
因此,在转换为浮点的过程中,第八位之后的任何十进制数字都会丢失,任何可能显示的数字都完全没有意义,并且与所表示的实际值无关
所有超过8位的十进制数字都是舍入到24位二进制并转换为十进制的产物,它们没有实际意义。这是SQL Server real底层数据类型的遗留代码。格式化程序是否有最大精度?如果使用
十进制
类型,则无需担心spe指定精度-表示精度(即数字显示为字符串)正是您设置的值。@Andrew Hare-小数点将显示存储值的精确值,但这不一定就是您设置的值!@rick schott-我认为格式设置程序的精度不值得关注,而是变量的精度。如果您想要更高的精度,那么您应该切换到double
@Jeffrey L Whitledge我的问题不在于变量,而在于何时需要将其表示为字符串。即使您指定这样的格式,您的解决方案也会受到float无法以高精度表示浮点数的影响。是的。出于某种原因,我假设他知道真实的数据类型与float(24)相同——一种小数点右边有24位数字的浮点数据类型。那么,我可以安全地使用“G24”吗作为我的格式,永远不会失去精度?不。一旦你将值放入浮点
,你就会失去精度。你需要将数据放入十进制
,而不是浮点
。明白,这不是我的问题,只需要按原样显示浮点,但它作为字符串出现,不再失去精度。如果你不能改变对于数据类型,您无法解决此问题。我不能采用float.NET数据类型并将其表示为字符串?您不能采用float
并将其转换为24位字符串。如果您愿意接受9位数字,您可以;请参阅我答案的第一部分。您应该调用AppendFormat
。调用Append(string.Format(…)
违背了StringBuilder
的目的。您仍然无法显示比浮点值所能包含的精度更高的精度。