超过30位的数字作 Mod 运算,溢出。如何处理?在线请求速解决,感谢!!例如:Dim A As Double
Dim B As DoubleA = 1.23456865645646E+25
B = 24MsgBox CStr(A Mod B)
以前有一贴,不知道后来高手们如何解决的?自己如何写算法?
http://community.csdn.net/Expert/topic/3898/3898829.xml?temp=.3413965

解决方案 »

  1.   

    Public Function Vmod(ByVal X1 As Variant, X2 As Variant) As Boolean
            Dim temp_str As String
            
            temp_str = Format(CDec(X1) / CDec(X2), "0.0000000000")
            
            If Right(temp_str, 11) = ".0000000000" Then
                Vmod = True
            Else
                Vmod = False
            End IfEnd Function
      

  2.   

    Dim A As Double
    Dim B As DoubleA = 1.23456865645646E+25
    B = 24MsgBox CStr(A Mod B)
    ===================================
    大数求余溢出,可以用a-int(a/b)*b的替代方法解决,
    但用上面这种记数法来求余基本上没有什么实际意义。。自己写算法吧。
      

  3.   

    To Lsftest :前辈,请教真正高效的算法如何写呢?感谢
      

  4.   

    说用上面那种记数法求余没有实际意义,是因为double只会保留最多15位有效数字,以后的会四舍五入即123456789011121314和123456789011121315都会变成1.23456789011121E+17,求余结果都是一样的。。
    要解决,据我所知有两种:
    1.用数组保存原数与中间结果、进位等等。
    2.用字符串保存原数,再做分析处理。。
    第一种方法在网上相关资料很多,搜一下吧
      

  5.   

    to lingll :手动求模?能说明一下方法么?to lsftest:谢谢您的说明,有现成的实例参考么?
      

  6.   

    .Net 中我也尝试过,使用 Double 或 int64 结果都是溢出;
    示例:A = 1133330503120100504160020001
    B = 24C = A mod B楼上的朋友么有比较实用的写法么?感谢,急。
      

  7.   

    lsftest()说的没错,用字符串或数组,VB中不知可否分配内存,在C下可以分配内存计算,很高效的,我在C下就用字符串做了一个阶乘的例子,可以运算的阶乘数很大的,现把C下的例子给你参考:#include <stdio.h>
    #include <math.h>
    #include <stdlib.h>
    int n;//阶乘数
    int getBitlen(int n);//n!的总位数
    void calc(char *a,int n);//计算n!
    void main(){
    int len;//n!的总位数
    printf("请输入阶乘数:");
    scanf("%d",&n);
    len=getBitlen(n);
    printf("%d!共有%d位数,n!的值是:\n",n,len);
    //通过字符数组存放结果
    char *pa;
    pa=(char *)calloc(len,sizeof(char));
    pa[0]=1;//处始化字符数组,令其开始为0000000....1
    calc(pa,n); 
    FILE *fp;
    for(int i=len-1;i>=0;i--)
    printf("%d",pa[i]);
    printf("\n");
    }
    int getBitlen(int n){//获得总位数
    double sum=1.0;
    for(int i=1;i<=n;i++)
    sum=sum+log10((long double)i);
    return (int)sum;
    }
    void calc(char *a,int n){
    double bitcount=1;
    for(int i=2; i<=n; ++i) { 
            long add = 0;  
    bitcount += log10((long double)i);//当前所在位数 
            for(int j=0; j<int(bitcount); ++j) { 
                add += (i*a[j]); 
                a[j] = char(add % 10); //低位存入数组
                add /= 10; //高位参与下一轮运算
            } 
        } }
      

  8.   

    Dim A As Double
    Dim B As Long
    Dim strA As String
    Dim strX() As String
    Dim i As Integer, tmp As Long
    Dim strResult As StringA = 1.23456865645646E+25
    B = 24strX = Split(CStr(A), "E")
    strA = Replace(strX(0), ".", "") & String(Val(strX(1)) - Len(strX(0)) + 2, "0")For i = 1 To Len(strA)
    strResult = strResult & Mid(strA, i, 1)
    tmp = Val(strResult)
    Do Until tmp < B
    tmp = tmp - B
    Loop
    strResult = CStr(tmp)
    Next iMsgBox strResult
      

  9.   


    To of123() :非常感谢您的算法,
    但是有一个数据截断的问题。例如:A= 1133330503120100504160020001
    但是 Double 后自动变为 1.1333305031201E+27
    这样 Mod 24 后就有差异了:1133330503120100504160020001 Mod 24  = 9
    1.1333305031201E+27 Mod 24 = 8有办法修正这样的弊端吗?非常感谢
      

  10.   

    例如:A= 1133330503120100504160020001
    但是 Double 后自动变为 1.1333305031201E+27
    这样 Mod 24 后就有差异了:1133330503120100504160020001 Mod 24  = 9
    1.1333305031201E+27 Mod 24 = 8有办法修正这样的弊端吗?非常感谢
    =======================
    上面已经说过不要用这种记数法了。。
    1.用数组:
    1133330503120100504160020001 
    a(0)=1
    a(1)=1
    a(2)=3
    .
    .
    a(6)=0
    a(7)=5
    .
    .
    .
    .
    a(27)=12.字符串:
    dim a as string
    a="1133330503120100504160020001"
      

  11.   

    中午自己搞定了。现在把方法分享给需要的朋友:'  大数 取模函数
    Function BigMod(mul1 As String, mul2 As String) As String
         
      
        astr1 = mul1
        nlen = Len(astr1)
        astr2 = mul2
        lasturn = "" 
        laststr = "" 
        
        k = 1
        For i = 1 To nlen
            strtmp = lasturn + Mid(astr1, i, 1)
            sumtmp = CLng(strtmp)
            If sumtmp < CLng(astr2) Then
                lasturn = CStr(strtmp)
                If k = 2 Then laststr = laststr & "0"
            Else
                laststr = laststr & CStr(Int(sumtmp / CLng(astr2)))
                lasturn = CStr(sumtmp Mod CLng(astr2))
                k = 2
            End If
        Next
        
        BigMod = lasturn
        
    End Function
      

  12.   

    楼上没有处理好大数。CLng(strtmp)这里还是可以溢出的。99999999999999999999999999999 MOD 99999999999999999999999999998 = 1这样就不可以。
    想想通过移位操作看能否实现。
      

  13.   

    http://community.csdn.net/Expert/TopicView1.asp?id=417
      

  14.   

    to  jjkk168(老加班的人--好好学习,天天吃饭) :通常 第二个数字不会很大的,
    出现您这样的情况我倒是很少有可能会遇到,
    需要再改进一下算法了,
    谢谢提醒。
    to  wosirius(一日就是一天) 网页打不开,能贴一下内容么?感谢
      

  15.   

    在进行 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 处理。