Vb6 visualbasic6.0中的自动类型转换

Vb6 visualbasic6.0中的自动类型转换,vb6,types,Vb6,Types,在VisualBasic6.0中将浮点转换为整数时,它如何舍入小数部分?我说的是自动类型转换 如果我们喜欢 Dim i as Integer i=5.5 msgbox i 它会打印什么?5还是6 几个月前我得了5分。有一天它开始给我6分! 知道怎么回事吗?微软发布了一些补丁来修复一些问题吗 更新:5.5转换为6,但8.5转换为8 更新2:添加CInt没有任何区别。CInt(5.5)给出6,CInt(8.5)给出8!!有点古怪的行为。我应该试试地板(x+0.49) 改变的行为听起来确实令人担忧,

在VisualBasic6.0中将浮点转换为整数时,它如何舍入小数部分?我说的是自动类型转换

如果我们喜欢

Dim i as Integer
i=5.5
msgbox i
它会打印什么?5还是6

几个月前我得了5分。有一天它开始给我6分! 知道怎么回事吗?微软发布了一些补丁来修复一些问题吗

更新:5.5转换为6,但8.5转换为8


更新2:添加CInt没有任何区别。CInt(5.5)给出6,CInt(8.5)给出8!!有点古怪的行为。我应该试试地板(x+0.49)

改变的行为听起来确实令人担忧,然而正确的答案是surley是6。向下滚动至上一页的“取整至平衡方法”以获取解释。

更新:在谷歌搜索之后,我发现:

这不是一个“bug”,而是VB的方式 为工作而设计的。它使用了一些东西 被称为银行家四舍五入,如果 数字正好以5结尾,而你 想转到前面的位置吗 在这5个数字中,如果 5前面的数字 位置是均匀的,向上取整 否则。它应该保护 防止重复计算使用 四舍五入的数字,所以答案是不正确的 总是向上倾斜。更多关于这个的信息 你可能不想知道的问题, 请参阅此链接

这就解释了(明显的)奇怪行为:

Cint(5.5) 'Should be 6'
Cint(8.5) 'Should be 8'
旧更新: 也许您应该更明确一些:使用
CInt
,而不是简单地将浮点赋给整数。例如:

Dim i as Integer
i = CInt(5.5)
MsgBox i
VB6 Round()函数使用一个方法。MS KB Article 225330()通过将Office 2000中的VBA与Excel的本机行为进行比较,间接地讨论了这一点,并对其进行了如下描述:

当带有偶数整数的数字以.5结尾时,Visual Basic将该数字(向下)舍入为最接近的偶数整数。[…]对于以.5结尾的数字,[VBA和Excel之间]的这种差异是的,与其他分数相同


如果您需要不同的行为,恐怕您必须自己指定。

正如其他人已经指出的,您看到的“奇怪行为”是由于VB6在舍入分数值时使用的事实

更新2:添加CInt不会导致 差别。CInt(5.5)给出了6和 Cint(8.5)给出8

这也是正常的
CInt
在执行转换之前,始终进行四舍五入(再次使用银行舍入法)

如果您有一个带有小数部分的数字,并且只想截断它(忽略小数点后的部分),则可以使用
Fix
Int
函数:

Fix(1.5) = 1
Fix(300.4) = 300
Fix(-12.394) = -12
Int
的工作方式与
Fix
相同,只是它将负数向下舍入到下一个最低负数:

Int(1.5) = 1
Int(300.4) = 300
Int(-12.394) = -13
如果你真的想按照大多数人熟悉的规则对一个数字进行四舍五入,你就必须编写自己的函数来完成。下面是一个舍入示例,当分数部分大于或等于.5时,舍入将向上舍入,否则舍入将向下舍入:


编辑:有关此函数更简单(可能更快)的版本,请参阅

 'Function corrected, now it works. 
Public Function RoundNumber(ByVal value As Currency, Optional PlacesAfterDecimal As Integer = 0) As Currency
  Dim nMultiplier As Long
  nMultiplier = 10 ^ PlacesAfterDecimal
  RoundNumber = Fix(0.5 * Sgn(value) + value * nMultiplier) / CDbl(nMultiplier)
End Function

示例

Debug.Print RoundNumber(1.6)       '2'
Debug.Print RoundNumber(-4.8)      '-5'
Debug.Print RoundNumber(101.7)     '102'
Debug.Print RoundNumber(12.535, 2) '12.54'

VB6帮助中有部分内容:主题类型转换函数。不幸的是,这是MSDN网站上没有的主题之一,但是如果您安装了VB6帮助,它就会出现在那里

当小数部分正好为0.5时,CIntCLng始终将其四舍五入到最接近的偶数。例如,0.5轮到0,1.5轮到2CIntCLng不同于FixInt函数,它们截断而不是取整数字的小数部分。另外,FixInt始终返回与传入的值类型相同的值

隐式类型强制-也称为-从浮点数到整数使用与CIntCLng相同的舍入规则。手册中似乎没有记录这种行为

如果要在小数部分大于等于0.5时向上取整,否则向下取整,一种简单的方法是

 n = Int(x + 0.5)
在我脑海中,这是我的简短版本,它是VB6 Round函数的替代品

 'Function corrected, now it works. 
Public Function RoundNumber(ByVal value As Currency, Optional PlacesAfterDecimal As Integer = 0) As Currency
  Dim nMultiplier As Long
  nMultiplier = 10 ^ PlacesAfterDecimal
  RoundNumber = Fix(0.5 * Sgn(value) + value * nMultiplier) / CDbl(nMultiplier)
End Function
样本输出:

Debug.Print RoundNumber(1.6)       '2'
Debug.Print RoundNumber(-4.8)      '-5'
Debug.Print RoundNumber(101.7)     '102'
Debug.Print RoundNumber(12.535, 2) '12.54'

没什么区别。CInt(5.5)给出6,CInt(8.5)给出8!!有点古怪的行为。我想我应该试试地板(x+0.49);这是正常的。类型转换函数(CInt、CLng等)在转换之前循环。不要说“cast”。这根本不是类型转换,而是类型转换。这是一个很大的不同。我的错。感谢您更正broTuxist,所以您应该编辑您的问题,并将“cast”和“casting”更改为“convert”和“conversion”。使用Int(0.5+值)四舍五入到最接近的整数更简洁,可能运行更快。请参阅我的答案,了解我的RoundNumber函数版本。顺便说一句,轮号(-4.8)大概应该是-5,而不是5@MarkJ:是的,那肯定更简单。我一直在想,“哇,一定有一个简单明了的方法来做到这一点”:-)我会把OP和你的答案联系起来,为你+1,好先生。干杯!有人向我展示了这个技巧,嗯,我相信ZX频谱基本,大约在20多年前的某个时候……在
RoundNumber
中,首先你必须乘法,然后除法:
RoundNumber=Int(0.5+值*nMultiplier)/CDbl(nMultiplier)
而不是相反。最有趣的是
Int
函数实际上返回了一个
Double
(retval与param的类型相同),因此它也适用于大数字/大精度。可能
CDec(0.5)+……
也会显著提高精度。在函数
RoundNumber
中,我们需要
Sgn(value)
Fi