超过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
If Right(temp_str, 11) = ".0000000000" Then Vmod = True Else Vmod = False End IfEnd Function
Dim A As Double Dim B As DoubleA = 1.23456865645646E+25 B = 24MsgBox CStr(A Mod B) =================================== 大数求余溢出,可以用a-int(a/b)*b的替代方法解决, 但用上面这种记数法来求余基本上没有什么实际意义。。自己写算法吧。
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
To of123() :非常感谢您的算法, 但是有一个数据截断的问题。例如:A= 1133330503120100504160020001 但是 Double 后自动变为 1.1333305031201E+27 这样 Mod 24 后就有差异了:1133330503120100504160020001 Mod 24 = 9 1.1333305031201E+27 Mod 24 = 8有办法修正这样的弊端吗?非常感谢
例如: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"
中午自己搞定了。现在把方法分享给需要的朋友:' 大数 取模函数 Function BigMod(mul1 As String, mul2 As String) As String
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
楼上没有处理好大数。CLng(strtmp)这里还是可以溢出的。99999999999999999999999999999 MOD 99999999999999999999999999998 = 1这样就不可以。 想想通过移位操作看能否实现。
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
Dim B As DoubleA = 1.23456865645646E+25
B = 24MsgBox CStr(A Mod B)
===================================
大数求余溢出,可以用a-int(a/b)*b的替代方法解决,
但用上面这种记数法来求余基本上没有什么实际意义。。自己写算法吧。
要解决,据我所知有两种:
1.用数组保存原数与中间结果、进位等等。
2.用字符串保存原数,再做分析处理。。
第一种方法在网上相关资料很多,搜一下吧
示例:A = 1133330503120100504160020001
B = 24C = A mod B楼上的朋友么有比较实用的写法么?感谢,急。
#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; //高位参与下一轮运算
}
} }
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
To of123() :非常感谢您的算法,
但是有一个数据截断的问题。例如:A= 1133330503120100504160020001
但是 Double 后自动变为 1.1333305031201E+27
这样 Mod 24 后就有差异了:1133330503120100504160020001 Mod 24 = 9
1.1333305031201E+27 Mod 24 = 8有办法修正这样的弊端吗?非常感谢
但是 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"
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
想想通过移位操作看能否实现。
出现您这样的情况我倒是很少有可能会遇到,
需要再改进一下算法了,
谢谢提醒。
to wosirius(一日就是一天) 网页打不开,能贴一下内容么?感谢