|
Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » AutoIt » [решено] Как обсчитать факториал БОЛЬШИХ чисел... или почему 100!=0 ? |
|
|
[решено] Как обсчитать факториал БОЛЬШИХ чисел... или почему 100!=0 ?
|
Новый участник Сообщения: 24 |
Возникла неободимость обсчитать факториал числа 100.
Соорудил нехитрый код, но вот при обсчете числа 100 (а надо и больше) получаю в результате 0! Может кто-нибудь знает как решается данная задача? |
|
Отправлено: 01:58, 17-03-2010 |
Ветеран Сообщения: 812
|
Профиль | Отправить PM | Цитировать centaurvv,
Здесь посмотрите: Проверка переполнения стека в операциях с вещественными числами |
Отправлено: 02:57, 17-03-2010 | #2 |
Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети. Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля. |
Новый участник Сообщения: 24
|
Профиль | Отправить PM | Цитировать Цитата madmasles:
![]() MsgBox(0,'Факториал', 'Результат: ' & _Factorial(InputBox('Факториал','Введите число:'))) Func _Factorial($int) Local $i, $res=1 For $i=1 To $int $res = $res * $i ConsoleWrite( $i & '='& $res & '='& _IsOverflow($res) & @CR) Next Return $res EndFunc Func _IsOverflow($Value) If $Value - $Value = 0 Then Return 0 Else Return 1 EndIf EndFunc |
|
Отправлено: 03:40, 17-03-2010 | #3 |
Ветеран Сообщения: 812
|
Профиль | Отправить PM | Цитировать |
Отправлено: 04:27, 17-03-2010 | #4 |
![]() Старожил Сообщения: 215
|
Профиль | Отправить PM | Цитировать centaurvv, если нужен только порядок числа (В числе 100! - 157 десятичных знаков) - можно воспользоваться этим:
Цитата:
|
||
------- Отправлено: 10:12, 17-03-2010 | #5 |
![]() Старожил Сообщения: 367
|
Профиль | Отправить PM | Цитировать SyDr,
Цитата SyDr:
![]() Цитата SyDr:
Автору могу посоветовать следующее. Т.к. факториалы больших чисел содержат в себе очень много десятичных знаков, лично мне кажется сомнительным использование их все. Если нужно узнать примерный порядок + несколько (возможно не совсем верных) десятичных знаков, то можно воспользоваться следующим приемом n* = Ln(n!) = Ln(1*2*3*...*n) = Ln(1) + Ln(2) + Ln(3) + ... + Ln(n) и просто иметь в виду что n! = exp(n*) $a = _FalseFact(InputBox('Factorial', 'Etner N')) MsgBox(0, '', $a[1]) Func _FalseFact($n) Dim $aTmp[2] If $n = 0 OR $n = 1 Then Return 1 $tmp = 0 For $i = 1 to $n $tmp += Log($i) Next If $n <= 170 Then $aTmp[0] = Exp($tmp) $aTmp[1] = 'The factorial of ' & $n & ' is aproximately ' & $aTmp[0] Else $aTmp[0] = $tmp $aTmp[1] = $N & ' is too big, I can show its factorial only in exponential form. It''s approximately Exp(' & $aTmp[0] & ')' EndIf Return $aTmp EndFunc |
||
------- Отправлено: 12:51, 17-03-2010 | #6 |
![]() Старожил Сообщения: 367
|
Профиль | Отправить PM | Цитировать |
------- Отправлено: 13:24, 17-03-2010 | #7 |
Googler Сообщения: 3665
|
Профиль | Отправить PM | Цитировать может просто столбиком?..
![]() ConsoleWrite(_BinaryFacrorial(100) &@CRLF) ; Факториал Func _BinaryFacrorial($iNum) Local $res = Binary("0x01") For $i=1 To $iNum $res = _BinaryMult($res, Binary("0x"& Hex($i,2))) Next Return $res EndFunc ; ==> _BinaryFacrorial() ; Умножение двух бинарных переменных как чисел (столбиком ;) ) Func _BinaryMult($bin1, $bin2) If IsBinary($bin1)=0 Or IsBinary($bin2)=0 Then Return SetError(1) Local $z1 = BinaryLen($bin1), $t1 = DllStructCreate("byte["& $z1 &"]") DllStructSetData($t1, 1, $bin1) Local $bin0 = Binary(Chr(0)) For $i=$z1*8-1 To 0 Step -1 If BitAND(DllStructGetData($t1,1,BitShift($i,3)+1),BitRotate(128,-BitAND($i,7))) Then $bin0 = _BinaryAdd($bin0, $bin2) $bin2 = _Binary2x($bin2) Next Return $bin0 EndFunc ; ==> _BinaryMult() ; сложение двух бинарных переменных, как чисел Func _BinaryAdd($bin1, $bin2) If IsBinary($bin1)=0 Or IsBinary($bin2)=0 Then Return SetError(1) Local $z1=BinaryLen($bin1), $z2=BinaryLen($bin2) Local $z0=$z1, $i, $x=0 If $z2 > $z0 Then $z0 = $z2 Local $tb1 = DllStructCreate("byte["& $z0-$z1+1 &"];byte["& $z1 &"]") Local $tb2 = DllStructCreate("byte["& $z0-$z2+1 &"];byte["& $z2 &"]") Local $ti1 = DllStructCreate("byte;byte["& $z0 &"]", DllStructGetPtr($tb1)) Local $ti2 = DllStructCreate("byte;byte["& $z0 &"]", DllStructGetPtr($tb2)) Local $tb0 = DllStructCreate("byte;byte["& $z0 &"]") DllStructSetData($tb1, 2, $bin1) DllStructSetData($tb2, 2, $bin2) For $i = $z0 To 1 Step -1 $x = BitShift($x, 8) $x += DllStructGetData($ti1, 2, $i) + DllStructGetData($ti2, 2 ,$i) DllStructSetData($tb0, 2, $x, $i) Next If Not(BitAND($x, 0x100)) Then Return DllStructGetData($tb0, 2) Return Binary(Chr(1)) & DllStructGetData($tb0, 2) EndFunc ; ==> _BinaryAdd() ; умножение бинарных данных на 2, т.е. ; сдвиг влево с добавлением нулевого бита Func _Binary2x($bin) If IsBinary($bin)=0 Then Return SetError(1) Local $z = BinaryLen($bin), $i, $t, $x=0 If $z=0 Then Return Binary("0x00") $t = DllStructCreate("byte["& $z &"]") DllStructSetData($t, 1, $bin) For $i = $z To 1 Step -1 $x = BitShift($x, 8) $x = BitOR($x, BitRotate(DllStructGetData($t,1,$i), 1, "W")) DllStructSetData ($t, 1, $x, $i) Next If Not(BitAND($x, 0x100)) Then Return DllStructGetData($t, 1) Return Binary(Chr(1)) & DllStructGetData($t, 1) EndFunc ; ==> _Binary2x() P.S. проверял этим: Hex Calculator for Programmers and Cryptanalysts |
Отправлено: 15:51, 17-03-2010 | #8 |
![]() Старожил Сообщения: 215
|
Профиль | Отправить PM | Цитировать |
------- Отправлено: 17:21, 17-03-2010 | #9 |
![]() Старожил Сообщения: 367
|
Профиль | Отправить PM | Цитировать Цитата SyDr:
![]() с помощью метода amel27, подсчет 100! заняло 13 сек на моей тачке. Уж не знаю, сколько он будет считать большие значения. Наверное экспоненциально медленнее. А может еще медленнее. Зато без потери точности. на соседнем форуме я запостил скрипт которым удалось посчитать 100000! за 1,2 сек. Хоть и с потерей точности. Но мне кажется это не принципиально, когда речь идет о таких больших числах. Для справки |
|
------- Отправлено: 17:55, 17-03-2010 | #10 |
|
![]() |
Участник сейчас на форуме |
![]() |
Участник вне форума |
![]() |
Автор темы |
![]() |
Сообщение прикреплено |
| |||||
Название темы | Автор | Информация о форуме | Ответов | Последнее сообщение | |
Медиа - Как ускорить просмотр больших документов html | shaint | Microsoft Windows 2000/XP | 1 | 24-09-2009 09:50 | |
VBA - [решено] Отображение больших чисел и приведение типов | DaniilS | Программирование и базы данных | 3 | 23-05-2009 09:58 | |
При клике правой клавишей мыши на больших файлах или просмотре Опций на видеокарте, экран гаснет на 2-3 секунды | starl | Microsoft Windows 2000/XP | 11 | 29-10-2006 00:05 | |
Smile Brush v.1.0 или GetSmile v.1.100 | Djamper | Программное обеспечение Windows | 11 | 27-03-2004 19:12 | |
Зависание или Перезагрузка - Почему? | EuGin | Непонятные проблемы с Железом | 22 | 07-10-2002 07:40 |
|