找回密码
 加入
搜索
查看: 3199|回复: 2

[效率算法] 关于计算结果为2.83096982349988e+017怎么解决。

[复制链接]
发表于 2011-10-26 11:06:00 | 显示全部楼层 |阅读模式
悬赏100金钱已解决
本帖最后由 ac5474012 于 2011-12-20 14:36 编辑

MsgBox(0,"",Number(1981678876449912983 / 7))

结果为:“2.83096982349988e+017”
为什么结果是这个呢?我想用这个做个注册码的东西,但是这样了还怎么叫对方告送我注册号呢?
用计算器计算得出的结果为:283096982349987569
我想问问这个要怎么解决?怎么让他返回整数?

最佳答案

查看完整内容

有个BigNum udf http://www.autoitscript.com/forum/topic/83529-bignum-udf/page__p__597491#entry597491 如果只需要计算除法,以下已提出该部分
发表于 2011-10-26 11:06:01 | 显示全部楼层
有个BigNum udf http://www.autoitscript.com/foru ... _597491#entry597491
如果只需要计算除法,以下已提出该部分
MsgBox(0, '计算结果', _BigNum_Div(1981678876449912983, 7))

Func _BigNum_Div($sX, $sY, $iD = -1)
        If Not __BigNum_IsValid($sX, $sY) Then Return SetError(1, 0, 0)
        Local $iNeg = __BigNum_CheckNegative($sX, $sY), $sNeg = ''
        If $iD = -1 Then $iD = StringLen($sX) + StringLen($sY)
        Local $iDec = __BigNum_StringIsDecimal($sX, $sY), $sMod
        If $sX = 0 Or $sY = 0 Then Return '0'
        If $sY = '1' Then Return $sNeg & $sX
        While StringLeft($sX, 1) = '0'
                $sX = StringTrimLeft($sX, 1)
                $iDec += 1
        WEnd
        While StringLeft($sY, 1) = '0'
                $sY = StringTrimLeft($sY, 1)
                $iDec += 1
        WEnd
        Local $sRet = '', $iLnX = StringLen($sX), $iLnY = StringLen($sY), $iTmp, $iCnt, $sTmp, $iDe1 = 0
        If $iD > 0 Then $iDe1 += $iD
        If $iNeg = 1 Or $iNeg = 2 Then $sNeg = '-'
        $iTmp = _BigNum_Compare($sX, $sY)
        If $iTmp = -1 Then
                For $iCnt = $iLnX To $iLnY
                        $sX &= 0
                        $iDe1 += 1
                Next
        EndIf
        If $iTmp = 0 Then Return $sNeg & '1'
        If $iD = -1 Then $iD = $iDec * 2
        For $iCnt = 1 To $iD
                $sX &= '0'
        Next
        If $iLnY > 14 Then
                $sRet = __BigNum_Div_DivisorGreater14($sX, $sY, $sMod)
        Else
                $sRet = __BigNum_Div_DivisorMaxLen14($sX, $sY, $sMod)
        EndIf
        If $iDe1 > 0 Then $sRet = __BigNum_InsertDecimalSeparator($sRet, $iDe1, $iD)
        If $sRet = '0' Then
                Return '0'
        Else
                Return $sNeg & $sRet
        EndIf
EndFunc   ;==>_BigNum_Div
Func _BigNum_Compare($sX, $sY)
        Local $iNeg = __BigNum_CheckNegative($sX, $sY)
        Switch $iNeg
                Case 1
                        Return -1
                Case 2
                        Return 1
                Case 3
                        __BigNum_Swap($sX, $sY)
        EndSwitch
        __BigNum_CompEqualizeLength($sX, $sY)
        Return StringCompare($sX, $sY)
EndFunc   ;==>_BigNum_Compare
Func __BigNum_CompEqualizeLength(ByRef $sX, ByRef $sY)
        Local $iXDotPos = StringInStr($sX, '.')
        Local $iYDotPos = StringInStr($sY, '.')
        Local $iXLen = StringLen($sX)
        Local $iYLen = StringLen($sY)
        Local $iLeading, $iTrailing
        If $iXDotPos == 0 And $iYDotPos <> 0 Then
                $iLeading = $iXLen - ($iYDotPos - 1)
                $iTrailing = -1 * ($iYLen - $iYDotPos)
                $sX &= '.'
        ElseIf $iXDotPos <> 0 And $iYDotPos == 0 Then
                $iLeading = ($iXDotPos - 1) - $iYLen
                $iTrailing = $iXLen - $iXDotPos
                $sY &= '.'
        ElseIf $iXDotPos == 0 And $iYDotPos == 0 Then
                $iLeading = $iXLen - $iYLen
        Else
                $iLeading = $iXDotPos - $iYDotPos
                $iTrailing = ($iXLen - $iXDotPos) - ($iYLen - $iYDotPos)
        EndIf
        If $iLeading < 0 Then
                $sX = __BigNum_CompStringAddZeroes($sX, -1 * $iLeading, 0, 0)
        ElseIf $iLeading > 0 Then
                $sY = __BigNum_CompStringAddZeroes($sY, $iLeading, 0, 0)
        EndIf
        If $iTrailing < 0 Then
                $sX = __BigNum_CompStringAddZeroes($sX, -1 * $iTrailing, 1, 0)
        ElseIf $iTrailing > 0 Then
                $sY = __BigNum_CompStringAddZeroes($sY, $iTrailing, 1, 0)
        EndIf
EndFunc   ;==>__BigNum_CompEqualizeLength
Func __BigNum_CompStringAddZeroes($sString, $iCount, $bTrailing = 0, $bToLength = 1)
        If $bToLength Then
                $iCount -= StringLen($sString)
        EndIf
        Local $i = 0
        Local $s = ''
        While $i < $iCount
                $s &= '0'
                $i += 1
        WEnd
        If $bTrailing Then
                Return $sString & $s
        EndIf
        Return $s & $sString
EndFunc   ;==>__BigNum_CompStringAddZeroes
Func __BigNum_Swap(ByRef $sX, ByRef $sY)
        Local $sSwap = $sX
        $sX = $sY
        $sY = $sSwap
        Return True
EndFunc   ;==>__BigNum_Swap
Func __BigNum_Div_DivisorGreater14($sX, $sY, ByRef $sM)
        $sM = '0'
        If $sY = '1' Then Return $sX
        If $sX = '0' Or $sY = '0' Or $sX = '' Or $sY = '' Then Return '0'
        Local $iLnY = StringLen($sY), $bRed = False
        Local $sRet = '', $sRem = StringLeft($sX, $iLnY), $sTmp = '', $sTm2 = '', $iCnt, $iLen = 1
        $sX = StringTrimLeft($sX, $iLnY)
        Do
                If __BigNum_DivComp($sRem, $sY) = -1 Then
                        $sTmp = StringLeft($sX, 1)
                        $sRem &= $sTmp
                        $sX = StringTrimLeft($sX, 1)
                        If StringLen($sTmp) > 0 Then $iLen += 1
                EndIf
                $sTmp = $sY
                $sTm2 = '0'
                If __BigNum_DivComp($sRem, $sY) >= 0 Then
                        For $iCnt = 1 To 9
                                $sTm2 = $sTmp
                                $sTmp = __BigNum_DivAdd($sTmp, $sY)
                                If __BigNum_DivComp($sRem, $sTmp) < 0 Then ExitLoop
                        Next
                Else
                        $iCnt = 0
                EndIf
                If StringLen($sX) = 0 Then $bRed = True
                $sM = $sRem
                $sRem = __BigNum_DivSub($sRem, $sTm2)
                If $iCnt > 0 Then $sM = $sRem
                $sRet &= StringFormat('%0' & String($iLen) & 'u', $iCnt)
                $iTrm = $iLnY - StringLen($sRem)
                $sTmp = StringLeft($sX, $iTrm)
                $sX = StringTrimLeft($sX, $iTrm)
                $iLen = StringLen($sTmp)
                $sRem &= $sTmp
        Until $bRed
        $sM = StringRegExpReplace($sM, '^0+([^0]|0$)', '\1', 1)
        Return StringRegExpReplace($sRet, '^0+([^0]|0$)', '\1', 1)
EndFunc   ;==>__BigNum_Div_DivisorGreater14
Func __BigNum_Div_DivisorMaxLen14($sX, $sY, ByRef $sM)
        $sM = '0'
        If $sY = '1' Then Return $sX
        If $sX = '0' Or $sY = '0' Or $sX = '' Or $sY = '' Then Return '0'
        Local $sRet = '', $iRem = StringLeft($sX, 15), $iTmp = 0, $iTrm = 6, $iLen
        $sX = StringTrimLeft($sX, 15)
        $iTmp = Floor($iRem / $sY)
        $sRet &= $iTmp
        $iRem -= $iTmp * $sY
        While StringLen($sX) > 0
                $iTrm = 15 - StringLen($iRem)
                $iTmp = StringLeft($sX, $iTrm)
                $iLen = StringLen($iTmp)
                $iRem &= $iTmp
                $sX = StringTrimLeft($sX, $iTrm)
                $iTmp = Floor($iRem / $sY)
                $iTmp = StringRight('000000000000000' & $iTmp, $iLen)
                $sRet &= $iTmp
                $iRem -= $iTmp * $sY
        WEnd
        $sM = String($iRem)
        Return StringRegExpReplace($sRet, '^0+([^0]|0$)', '\1', 1)
EndFunc   ;==>__BigNum_Div_DivisorMaxLen14
Func __BigNum_DivComp($sX, $sY)
        $sX = StringRegExpReplace($sX, '^0+([^0]|0$)', '\1', 1)
        $sY = StringRegExpReplace($sY, '^0+([^0]|0$)', '\1', 1)
        Local $iLnX = StringLen($sX), $iLnY = StringLen($sY)
        If $iLnX < $iLnY Then
                Return -1
        ElseIf $iLnX > $iLnY Then
                Return 1
        Else
                If $sX < $sY Then
                        Return -1
                ElseIf $sX > $sY Then
                        Return 1
                Else
                        Return 0
                EndIf
        EndIf
EndFunc   ;==>__BigNum_DivComp
Func __BigNum_DivAdd($sX, $sY)
        Local $iTmp = StringLen($sX), $iLen = StringLen($sY), $iCar = 0, $sRet = ''
        If $iLen < $iTmp Then $iLen = $iTmp
        For $i = 1 To $iLen Step 18
                $iTmp = Int(StringRight($sX, 18)) + Int(StringRight($sY, 18)) + $iCar
                $sX = StringTrimRight($sX, 18)
                $sY = StringTrimRight($sY, 18)
                If ($iTmp > 999999999999999999) Then
                        $sRet = StringRight($iTmp, 18) & $sRet
                        $iCar = 1
                Else
                        $iTmp = StringRight('000000000000000000' & $iTmp, 18)
                        $sRet = $iTmp & $sRet
                        $iCar = 0
                EndIf
        Next
        $sRet = StringRegExpReplace($iCar & $sRet, '^0+([^0]|0$)', '\1', 1)
        Return $sRet
EndFunc   ;==>__BigNum_DivAdd
Func __BigNum_DivSub($sX, $sY)
        Local $iTmp = StringLen($sX), $iLen = StringLen($sY), $iCar = 0, $sRet = ''
        If $iLen < $iTmp Then $iLen = $iTmp
        For $i = 1 To $iLen Step 18
                $iTmp = Int(StringRight($sX, 18)) - Int(StringRight($sY, 18)) - $iCar
                $sX = StringTrimRight($sX, 18)
                $sY = StringTrimRight($sY, 18)
                If $iTmp < 0 Then
                        $iTmp = 1000000000000000000 + $iTmp
                        $iCar = 1
                Else
                        $iCar = 0
                EndIf
                $sRet = StringRight('0000000000000000000' & $iTmp, 18) & $sRet
        Next
        $sRet = StringRegExpReplace($iCar & $sRet, '^0+([^0]|0$)', '\1', 1)
        Return $sRet
EndFunc   ;==>__BigNum_DivSub
Func __BigNum_IsValid($sX, $sY)
        If StringRegExp($sX, '[^0-9.-]') Or StringRegExp($sY, '[^0-9.-]') Then Return False
        Return True
EndFunc   ;==>__BigNum_IsValid
Func __BigNum_InsertDecimalSeparator($sX, $iDec, $iD = 18)
        If $iD = 0 And $iDec = 0 Then Return $sX
        Local $sRet = StringRegExpReplace(StringRight(StringFormat('%0' & String($iDec) & 'u', '') & $sX, $iDec), '0+$', '\1', 1)
        $sX = StringTrimRight($sX, $iDec)
        If $sX = '' Then $sX = '0'
        $sRet = StringLeft($sRet, $iD)
        If $sRet = '' Or $sRet = '0' Then Return $sX
        Return $sX & '.' & $sRet
EndFunc   ;==>__BigNum_InsertDecimalSeparator
Func __BigNum_StringIsDecimal(ByRef $sX, ByRef $sY)
        If StringLeft($sX, 1) = '.' Then $sX = '0' & $sX
        If StringLeft($sY, 1) = '.' Then $sY = '0' & $sY
        Local $iPsX = StringInStr($sX, '.', 0, 1) - 1, $iPsY = StringInStr($sY, '.', 0, 1) - 1
        $sX = StringRegExpReplace($sX, '\D', '')
        $sY = StringRegExpReplace($sY, '\D', '')
        Local $iLnX = StringLen($sX), $iLnY = StringLen($sY)
        If $iPsX <= 0 Then $iPsX = $iLnX
        If $iPsY <= 0 Then $iPsY = $iLnY
        If $iLnX - $iPsX > $iLnY - $iPsY Then
                For $iCnt = $iLnY - $iPsY To $iLnX - $iPsX - 1
                        $sY &= '0'
                Next
                Return $iLnX - $iPsX
        ElseIf $iLnX - $iPsX < $iLnY - $iPsY Then
                For $iCnt = $iLnX - $iPsX To $iLnY - $iPsY - 1
                        $sX &= '0'
                Next
                Return $iLnY - $iPsY
        EndIf
        Return $iLnX - $iPsX
EndFunc   ;==>__BigNum_StringIsDecimal
Func __BigNum_CheckNegative(ByRef $sX, ByRef $sY)
        Local $bNgX = False, $bNgY = False
        While StringLeft($sX, 1) = '-'
                $bNgX = Not $bNgX
                $sX = StringTrimLeft($sX, 1)
        WEnd
        While StringLeft($sY, 1) = '-'
                $bNgY = Not $bNgY
                $sY = StringTrimLeft($sY, 1)
        WEnd
        $sX = StringRegExpReplace($sX, '^0+([^0]|0$)', '\1', 1)
        $sY = StringRegExpReplace($sY, '^0+([^0]|0$)', '\1', 1)
        If $sX = '' Then $sX = '0'
        If $sY = '' Then $sY = '0'
        If $bNgX = True And $bNgY = True Then
                Return 3
        ElseIf $bNgX = True And $bNgY = False Then
                Return 1
        ElseIf $bNgX = False And $bNgY = True Then
                Return 2
        Else
                Return 0
        EndIf
EndFunc   ;==>__BigNum_CheckNegative
发表于 2011-10-26 18:05:57 | 显示全部楼层
回复 2# afan


    曾经也为这个问题困扰过,谢谢分享!
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|手机版|小黑屋|AUTOIT CN ( 鲁ICP备19019924号-1 )谷歌 百度

GMT+8, 2024-4-29 19:02 , Processed in 0.083354 second(s), 22 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

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