ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 Excel Home精品图文教程库
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
300集Office 2010微视频教程 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
12
返回列表 发新帖
楼主: 针锦菜

[分享] 危险的MOD函数,我上当得很厉害呀!

[复制链接]

TA的精华主题

TA的得分主题

发表于 2010-6-9 14:54 | 显示全部楼层
问题研究的真细。

TA的精华主题

TA的得分主题

发表于 2010-6-9 17:03 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2010-6-9 22:54 | 显示全部楼层
(0.95*10.0) mod 10.0  

看看,vb里的数据类型强制转换

[ 本帖最后由 coby001 于 2010-6-9 22:55 编辑 ]

TA的精华主题

TA的得分主题

发表于 2010-6-9 23:02 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
跟着两位版版和高手们学习。

TA的精华主题

TA的得分主题

发表于 2010-6-9 23:20 | 显示全部楼层
Sub testMod()
    Dim a#
    Dim b#
    a = 0.95
    b = 10
    Debug.Print (a * b) Mod b
End Sub


必须所有参与计算的变量都显式的声明为双精度类型,结果就正确,否则,就有可能在类型转换的时候“失真”。

TA的精华主题

TA的得分主题

发表于 2010-6-9 23:48 | 显示全部楼层
还真没听说过用长,知道浮点运算,不知其所以然

TA的精华主题

TA的得分主题

发表于 2010-6-10 08:33 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2010-6-10 10:39 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
原帖由 coby001 于 2010-6-9 23:20 发表
Sub testMod()
    Dim a#
    Dim b#
    a = 0.95
    b = 10
    Debug.Print (a * b) Mod b
End Sub


必须所有参与计算的变量都显式的声明为双精度类型,结果就正确,否则,就有可能在类型转换的时候“ ...


刚看了mod的帮助,
Mod 运算符Mod 运算符
用来对两个数作除法并且只返回余数。
语法
result = number1 Mod number2
Mod 的语法具有以下几个部分:
部分描述
result必需的;任何数值变量。
number1必需的;任何数值表达式。
number2必需的;任何数值表达式。


说明
在进行 Mod 运算或求余数运算时,该运算符将 number1 number2 除(将浮点数字四舍五入成整数),并把余数作为 result 的值返回。例如,在下列表达式中,A (result) 等于 5。
A = 19 Mod 6.7一般说来,不管 result 是否为一个整数,result 的数据类型为 Byte,Byte 变体、Integer、Integer 变体、Long 或一个包含 Long 的Variant。任何小数部分都被删除。但是,如果任何一个 Null,类型的表达式出现时,result 都将是 Null。任何 Empty 类型表达式都作为 0 处理。


从mod运算的帮助来看,楼主的问题其实可以回答得很明确了。0.95*10=9.5,在进行mod运算前会将9.5进行四舍五入,这里就变成了10 mod 10,这样答案当然为0,这是正确的。
在这里我们需要注意一点就是VBA中的四舍五入采用的是银行家算法,也就是“四舍六入五判断,五后非零则进入,五后为零看奇偶,奇进偶不进”,因为如果用0.85来计算的话会得到8而不是9。具体可看我以前的一个贴子。http://club.excelhome.net/viewthread.php?tid=264823&replyID=&skin=0


楼主的问题到这里应该已经解决了。

但山菊花老是的示例又带来了一个新的问题,就是我前面已经描述过的问题。前面可能描述得不清楚,这里再重新描述一下。
示例1(山菊花老师提供的例子)

  1. Sub ex1()
  2.     Dim a As Variant
  3.     a = 0.95
  4.     Debug.Print (a * 10) Mod 10

  5.     Dim b As Double
  6.     b = 0.95
  7.     Debug.Print (b * 10) Mod 10
  8. End Sub
复制代码

得到的结果为 0 和 9

同样的例子,将数值改为0.75

  1. Sub ex2()
  2.     Dim a As Variant
  3.     a = 0.75
  4.     Debug.Print (a * 10) Mod 10

  5.     Dim b As Double
  6.     b = 0.75
  7.     Debug.Print (b * 10) Mod 10
  8. End Sub

复制代码


得到的结果却全是8。

也就是说浮点数中实际存放的值只是近似于真被值的一个数,但可能比真被值大,也可能比真实值小。而不是我以前理解为要么全部大于真实值,要么全部小于真实值。如果真的如我上面的说法一样的话,那么在涉及浮点数运算过程中,真的得小心小心再小心了。有点怕怕。

[ 本帖最后由 lbpp 于 2010-6-10 12:12 编辑 ]
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-6-3 00:54 , Processed in 0.043467 second(s), 12 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表