函数 MOD 上的 Excel 错误
Posted
技术标签:
【中文标题】函数 MOD 上的 Excel 错误【英文标题】:Excel error on function MOD 【发布时间】:2016-06-22 11:13:32 【问题描述】:我想在我的 excel 文件中输入这个公式(最好是 VBA)。但是由于某种原因,当我将此函数放在我的公式栏中时出现错误:
#NUM! - Number Error
我的功能是:
=98-mod(2000000000123456*100;97))
但是当我只输入 10 位数字时,它就可以工作了。我需要使用 16 位数字。 我基本上是在尝试根据 ISO 7064 Mod 97,10 公式验证数字 提前致谢。
感谢大家的努力,但我尝试了@Robyn 编写的代码,但出现溢出错误。这是我的代码(我将只写函数部分): '注:输入参数为:3259300700853850和97
Function DblMod(Dividend, Divisor)
' Declare two double precision variables
Dim D1 As Double
Dim D2 As Double
' Copy function arguments to local variables
D1 = Dividend
D2 = Divisor
DblMod = D1 Mod D2
End Function
【问题讨论】:
但 Excel 只能处理 15 位数字。 @Gary'sStudent 我倾向于指定:你可以enter and use much larger numbers。但如果超过 15 位的精度很重要,则不应使用 Excel:superuser.com/questions/373997/… 我相信我的解决方案会适用于您的情况。 你能说出3259300700853850(除数)和97(除数)的正确答案吗? 赏金描述中的所有例子都有错误的结果。98-mod(3100400300327166;97)=50
但是 98-mod(3100400300327166*100;97)=51
,你有来自@RonRosenfeld 的正确答案,如果它不起作用 - 你必须详细描述原因。
【参考方案1】:
如前所述,Excel 有 15 位精度的限制。因此,当您输入上面的公式时,您的 16 位数字将被更改:
2000000000123456
变为 2000000000123460
解决此限制的一种方法是使用 VBA 并更改您的公式。
不要写16 digit number * 100
,而是输入整个值作为字符串:
“200000000012345600”
例如:
=98-xMOD("200000000012345600";97)
然后使用这个 UDF,它利用 VBA 的 Decimal 数据类型提供的更高精度:
Option Explicit
Function xMOD(Num As Variant, Div As Long)
Dim x As Variant, y As Variant
x = CDec(Num)
y = CDec(Div)
xMOD = x - Int(x / y) * y
End Function
如果您要在某个单元格中输入 16 位数字(作为字符串),并且始终乘以 100,则可以使用以下公式:
=98-xMOD(C1&"00";97)
或者,您可以将 18 位数字作为字符串输入某个单元格并在公式中引用它,省略 &"00"
部分。
如果你能找到它,另一个选项是一个不受支持的免费插件,名为xNumbers
。最新版本6.0
仍然适用于 Excel 2016,尽管不存在与功能区的集成,因此无法使用某些配置选项。
编辑既然你写到你无法让这个 UDF 在你的系统中工作,我将发布一个屏幕截图,显示它在我的系统中工作,并且它与结果一致您已在赏金说明中发布。 (来自 xNumbers 的 xIntMod 也返回相同的结果)
【讨论】:
不幸的是它不允许我运行这个函数,“你输入的公式包含错误”。 @Stefan0309 您是否为您的区域设置使用了正确的系统分隔符信号。分号与逗号句号 @Stefan0309 您是否检查过您的系统分隔符,您使用的分隔符是否适合您的语言环境?如果正确,请复制并粘贴(不要输入)您的确切公式和公式所引用的数据,或者最好上传显示问题的工作簿并在此处发布链接。 智能解决方案,您甚至可以将函数精简到一行,即 'xMOD = CDec(Num) - Int(CDec(Num) / CDec(Div)) * CDec(Div)' @EEM 谢谢。一个班轮很有趣,但它们有时会使算法更难破译。我从未测试过一种方式是否比另一种方式有任何速度优势。【参考方案2】:对于 abs() 小于或等于 2,147,483,647 的数字
这是 Microsoft 支持文章 XL: MOD() Function Returns #NUM! Error Value 中的一个已知问题。
请注意,这篇文章已经过时了 - 因此这可能不是您的实例的真正根本原因。
文章建议以下解决方法:
不要使用这个公式
=MOD(J13,K13)
,而是使用这个公式:=J13-(INT(J13/K13)*K13)
或者,this article 建议使用 VBA 等效项:
Function DblMod(Dividend, Divisor)
' Declare two double precision variables
Dim D1 As Double
Dim D2 As Double
' Copy function arguments to local variables
D1 = Dividend
D2 = Divisor
DblMod = D1 Mod D2
End Function
对于 abs() 大于 2,147,483,647 的数字
在这种情况下,VBA MOD 函数溢出Run Time Error '6': Overflow
。这在 Microsoft 支持文章 PRB: "Overflow" with Integer Division and MOD Operator 中得到解决。这篇文章在 VBA 中提出了以下解决方案,我已经测试过它可以使用 OP 的给定数字按预期工作:
Sub Main()
Call DblMod2(3259300700853850, 97)
' returns 46, which matches the Big Integer Calculator at http://www.javascripter.net/math/calculators/100digitbigintcalculator.htm suggested by Ron
End Sub
Function DblMod2(Dividend, Divisor)
Dim dblX As Double
Dim dblY As Double
dblX = Dividend ' numerator
dblY = Divisor ' denominator
' round off the numerator and denominator (ensure number is .0)
dblX = Int(dblX + 0.5)
dblY = Int(dblY + 0.5)
' Emulate integer division with: Fix(dblX / dblY)
' Emulate modulo arithmetic with: dblX - (dblY * Fix(dblX / dblY))
DblMod2 = dblX - (dblY * Fix(dblX / dblY))
Debug.Print DblMod2
End Function
【讨论】:
我试过这个 vba 代码,但它返回一个溢出错误。我不确定这是否正确? 由于 OP 想要处理 16 位数字,您的解决方案都无法正常工作 我认为 Excel 可以处理非常长的数字 - 只是需要注意不精确 - 所以我进一步挖掘。我会尽快更新我建议的解决方案。 嗨@Stefan0309,我建议的解决方案已在上面更新。这给了我预期的数字(在 Excel 2013 中)。 但是您正在测试的号码是200,000,000,012,346,000
,而OP帖子中的号码是200,000,000,012,345,600
【参考方案3】:
MOD函数here有一个替代方法
a - (b * (a / b))
=98-((2000000000123450*100)-(97*((2000000000123450*100)/97)))
编辑 1
试试下面,它会返回 46
Function DblMod(Dividend, Divisor)
' Declare two double precision variables
Dim D1 As Double
Dim D2 As Double
Dim D3 As Double
Dim str1
Dim Str2
' Copy function arguments to local variables
D1 = CDbl(Dividend)
D2 = Divisor
DblMod = CDec(D1) - (Round(CDec(D1) / D2) * D2)
End Function
Sub test()
test = DblMod("3259300700853850", 97)
End Sub
【讨论】:
请注意,OP 的 16 位数字中的最后一位已更改【参考方案4】:不要处理非常大的数字,只需像这样拆分它们:
Public Function ExtMod(Dividend As String, Divisor As Long) As Double
Dim i As Long, j As Double
For i = 1 To Len(Dividend)
If Not IsNumeric(Mid(Dividend, i, 1)) Then
j = j & Mid(Dividend, i)
Exit For
End If
j = j * 10 + Mid(Dividend, i, 1)
While j >= Divisor
j = j - Divisor
Wend
Next
ExtMod = j
End Function
也适用于小数,区域设置无关紧要。唯一的限制是您可能永远不会遇到的字符串的最大长度。
使用“123456789012345678901234567890.3241543”和 643(即 435.3241543)对其进行了测试。
如果你有任何问题,尽管问;)
【讨论】:
以上是关于函数 MOD 上的 Excel 错误的主要内容,如果未能解决你的问题,请参考以下文章
403 错误禁止您无权访问此服务器 mod_wsgi 和 apache 上的 /myapp
Excel mod函数的使用方法 Excel mod函数的使用步骤