Что нового

[Математика] Как обсчитать факториал БОЛЬШИХ чисел... или почему 100!=0 ?

centaur

Новичок
Сообщения
12
Репутация
0
Возникла неободимость обсчитать факториал числа 100.
Соорудил нехитрый код, но вот при обсчете числа 100 (а надо и больше) получаю в результате 0!

Код:
MsgBox(0,'Факториал', 'Результат: ' & _Factorial(InputBox('Факториал','Введите число:')))

Func _Factorial($int)
    Local $i, $res=1
    For $i=1 To $int
        $res = $res * $i
    Next
    Return $res
EndFunc


Может кто-нибудь знает как решается данная задача?
 

madmasles

Модератор
Глобальный модератор
Сообщения
7 790
Репутация
2 319
centaur
Вы считаете, что должно отобразиться такое число: :laugh:
100!=93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
Проверьте Калькулятор Факториалов
 
Автор
centaur

centaur

Новичок
Сообщения
12
Репутация
0
madmasles сказал(а):
centaur
Вы считаете, что должно отобразиться такое число: :laugh:
100!=93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
Проверьте Калькулятор Факториалов

Мда... полезный ресурс... и число удивило... будем искать обходные пути вместо обчисления этого сумасшедшего числа.... такое и числом-то страшно называть :wacko:
 

shm_alex

Новичок
Сообщения
34
Репутация
4
А вот это решение- код сырой но простой, возможно правильный (писал я =) вроде считает что-то )
Я просто написал функции для сложения и умножения чисел в строком варианте :blum:
Код:
;вычисляет строку равную  произведению $sNumber на $iDigit 
;$sNumber- строка произвольной длинны, содержащая только цифры (целое положительное число с произвольным количеством знаков)
;$iDigit  - 0 или 1 или 2 или 3 или 4 или 5 или 6 или 7 или 8 или 9
;контроля входных праметров нет
Func Mul_By_Digit($sNumber,$iDigit)
	$iLen=StringLen($sNumber)
	$iCarry=0
	$iCurDigit=0
	$iMul=0
	$sRet=""
	for $i=$iLen To 1 step -1
		$iMul=(Int(StringMid($sNumber, $i, 1)))*$iDigit+$iCarry
		$iCarry= int($iMul/10)
		$iCurDigit=Mod($iMul,10)
		$sRet=$iCurDigit&$sRet
	next 	
	if $iCarry<>0 then 
		$sRet=$iCarry&$sRet 
	EndIf
	Return $sRet
EndFunc
;складывает два числа произвольной длинны
;$sNumber1,$sNumber2 - строки представляющие числа для сложения
func Add($sNumber1,$sNumber2)
	$iLen1=StringLen($sNumber1)
	$iLen2=StringLen($sNumber2)
	if $iLen2>$iLen1 Then
		local $iTemp=$iLen1
		$iLen1=$iLen2
		$iLen2=$iTemp
		local $sTemp=$sNumber1
		$sNumber1=$sNumber2
		$sNumber2=$sTemp
	EndIf
	;в $sNumber1- самая длинная строка. 
	$iCarry=0
	$iCurDigit=0
	$iSum=0
	$iCurNumber2Digit=0
	$sRet=""
	for $i=1 to $iLen1 step 1
	 if $i>	$iLen2 then
			$iCurNumber2Digit=0
		Else
			$iCurNumber2Digit=Int(StringMid($sNumber2, $iLen2-$i+1, 1))
		EndIf	
		$iSum=$iCurNumber2Digit+Int(StringMid($sNumber1,$iLen1- $i+1, 1))+$iCarry
		$iCarry=int($iSum/10);$iCarry=int($iSum > 9)
		$iCurDigit=Mod($iSum,10)
		$sRet=$iCurDigit&$sRet
	Next
	if $iCarry<>0 then
		$sRet="1"&$sRet 
		EndIf
	Return $sRet
EndFunc	

;умножает два целых числа произвольной длинны
;$sNumber1,$sNumber2 - строки представляющие числа для умножения

func Multiply($sNumber1,$sNumber2)
	$iLen1=StringLen($sNumber1)
	$iLen2=StringLen($sNumber2)
	if $iLen2>$iLen1 Then
		local $iTemp=$iLen1
		$iLen1=$iLen2
		$iLen2=$iTemp
		local $sTemp=$sNumber1
		$sNumber1=$sNumber2
		$sNumber2=$sTemp
	EndIf
	;в $sNumber1- самая длинная строка. 
	$sRet="0"
	$sTmpMul="0"
	$sPostfix=""
	for $i=$iLen2 to 1 step -1
		$sTmpMul=Mul_By_Digit($sNumber1,StringMid($sNumber2,$i, 1))
		$sRet=Add($sTmpMul&$sPostfix,$sRet)
		$sPostfix=$sPostfix&"0"
	Next
Return $sRet	
EndFunc	

;вычисляет факториал целого числа n 

func Fact($n)
	if $n<2 Then
		 return 1
	 EndIf
	 return Multiply(Fact($n-1),$n) 
EndFunc

ToolTip(Fact(100))

sleep(5000)
 
Верх