.net 如何实现单精度到双精度的转换
这个小小的代码简介.net 如何实现单精度到双精度的转换,.net,floating-point,.net,Floating Point,这个小小的代码简介 Dim s As Single = 1.15 Dim d As Double = CDbl(s) Console.WriteLine(s) Console.WriteLine(d) 收益率: 1.15 1.14999997615814 这完全出乎意料。为什么会发生这种情况?我如何解决 预计到达时间: 这不是我的代码,原来的输入是以字符串“1.15”的形式输入的,所以他们将其转换为单精度,然后是双精度。删除单个部分使每个人都感到高兴。在计算机
Dim s As Single = 1.15
Dim d As Double = CDbl(s)
Console.WriteLine(s)
Console.WriteLine(d)
收益率:
1.15
1.14999997615814
这完全出乎意料。为什么会发生这种情况?我如何解决
预计到达时间:
这不是我的代码,原来的输入是以字符串“1.15”的形式输入的,所以他们将其转换为单精度,然后是双精度。删除单个部分使每个人都感到高兴。在计算机科学语言中,精度是根据尾数和指数的大小给出的。这与“重要数字”无关。也许最令人困惑的是,您正在查看基10中的基2浮点数 如果查看这两个值的基2表示形式,您会发现它们相距不远 小数点1.15的二进制值为1.00100110011001…无穷大。使用
单个
得到23位尾数,使用双
得到52位尾数。显然,以有限的精度,尾数的重复将在不同的地方被切断
如果您希望数字以相同的10为基数显示,则必须使用一点斜率,除非您通知字符串转换例程以更好的方式对其进行格式化。尽管
s
和d
包含完全相同的数值,由于将单数
和双数
转换为文本时使用的位数不同,因此会为它们显示不同的数字
Console.WriteLine
调用Console.WriteLine(Single)
,它使用Single.ToString
生成s
的文本表示形式,并使用文档中的格式说明符“G”进行转换。类似地,Console.Writeline(d)
调用Double.ToString
根据文档,使用的最大位数为Single
的7位和Double
的15位。我没有看到指定实际使用位数的文档,只是最大值
语句Dim s As Single=1.15
将s
设置为值1.149999761581428984375,因为这是最接近1.15的Single
值。(第二个最接近的值是1.150000953674360625。)将该值四舍五入到七位小数时,结果为“1.150000”。我认为.NET省略了尾随的零,得到了“1.15”
当d
设置为相同值并打印时,使用15位数字。当1.1499999761581420894375四舍五入为15位时,结果为“1.14999997615814”
因此,将单次
转换为双次
时没有错误。这只是一种展示的错觉
请注意,
Double
转换为Single
时通常会出现错误。如果您将Dim d写成Double=1.15
,那么d
将被设置为1.149999999999111821580987476766109466552734375,我希望控制台。WriteLine(d)
将产生“1.15”。将d
转换为Single
将产生1.14999979615814208984375。二进制浮点系统不容易满足工程术语中的十进制“精度”。也许你的意思是显示四舍五入?你所看到的“不精确”完全在你的脑海中。如果你需要非整数数学的精确性,那么最好使用十进制类型。或者使用有理数类型。或者知道需要保留多少sig数字,并在计算之后,在更改类型之前,始终四舍五入到该数字。顺便说一句,这里是C版本。这个答案无法解释为什么相同的数值打印方式不同。@EricPostChil:如果你认为这个答案令人困惑,我可以补充更多细节。然而,给出的信息足够了。当分配给单个
和双
时,“1.15”的四舍五入方式会有所不同,因为它们的有效位长度不同,这一事实并不是问题的原因,并且这个答案不正确,表明它是。在这个问题中,s
和d
的数值是完全相同的,因为d
被分配了Dim d作为Double=CDbl(s)
,因此它在已经被四舍五入到较短的单个有效位后收到了值。此外,Single
和Double
的有效位分别为24位和53位。它们部分用23位和52位字段编码,但有效位包括从指数字段派生的附加位。(“有效位”是首选术语;有效位是线性的,但尾数是对数的。)