unsigned short recfactorial(unsigned short num)
{
unsigned short result;
if (num == 1 || num == 0)
result = 1;
else
{
__asm
{
mov ax, num
mov cx, recfactorial(num-1)
mul cx
jnc __local
jmp __carry
__local: mov result, ax
}
}
return result;
__carry: MessageBox(NULL, "Out of range1", NULL, NULL);
return 0;
}
рекурсивная функция вычисления факториала
Код:
Но я что-то не так сделал у меня компилятор ругается на строчку
Код:
mov cx, recfactorial(num-1)
Ошибка такая
E2188 Expression syntax
Подскажите пожалуйста, как сделать правильно.
Цитата: zuze
Подскажите пожалуйста, как сделать правильно.
Правильно - писать либо на С, либо на asm, а не путать эти языки.
Ты сам для себя можешь объяснить, что ты делаешь в строке
mov cx, recfactorial(num-1)
А теперь представь это дело с т.з. ассемблера.
Ты понимаешь, чем ассемблер отличается от языков более высокого уровня?
Код:
unsigned short recfactorial(unsigned short num)
{
unsigned short result;
if (num == 1 || num == 0)
result = 1;
else
{
__asm
{
mov cx, [num]
dec cx
push cx
call recfactorial
mov cx, ax
mov ax, [num]
mul cx
jnc __local
jmp __carry
__local: mov result, ax
}
}
return result;
__carry: MessageBox(NULL, "Out of range1", NULL, NULL);
return 0;
}
{
unsigned short result;
if (num == 1 || num == 0)
result = 1;
else
{
__asm
{
mov cx, [num]
dec cx
push cx
call recfactorial
mov cx, ax
mov ax, [num]
mul cx
jnc __local
jmp __carry
__local: mov result, ax
}
}
return result;
__carry: MessageBox(NULL, "Out of range1", NULL, NULL);
return 0;
}
Но опять ошибки.
E2188 Expression syntax
E2329 Invalid combination of opcode and operands
Ругается на эту строчку
Код:
call recfactorial
Вчём же дело.
Помогите пожалуйста.
Ну это немного извращенно :))))))
factorial.h
Код:
#ifndef _FACTORIAL_H_
#define _FACTORIAL_H_
class Factorial
{
public:
Factorial();
~Factorial();
unsigned short recfactorial(unsigned short num);
unsigned short factorial(unsigned short num);
};
Factorial :: Factorial()
{
}
Factorial :: ~Factorial()
{
}
unsigned short Factorial :: recfactorial(unsigned short num)
{
unsigned short result;
if (num == 1 || num == 0)
result = 1;
else
{
result = recfactorial(num-1);
__asm
{
mov cx, result
mov ax, num
mul cx
jnc __local
jmp __carry
__local: mov result, ax
}
}
return result;
__carry: MessageBox(NULL, "Out of range1", NULL, NULL);
return 0;
}
unsigned short Factorial :: factorial(unsigned short num)
{
unsigned short result = 1;
for (unsigned short i = 2; i <= num; i++)
{
__asm
{
mov ax, result
mov cx, i
mul cx
jnc __local
jmp __carry
__local: mov result, ax
}
}
return result;
__carry: MessageBox(NULL, "Out of range2", NULL, NULL);
return 0;
}
#endif
#define _FACTORIAL_H_
class Factorial
{
public:
Factorial();
~Factorial();
unsigned short recfactorial(unsigned short num);
unsigned short factorial(unsigned short num);
};
Factorial :: Factorial()
{
}
Factorial :: ~Factorial()
{
}
unsigned short Factorial :: recfactorial(unsigned short num)
{
unsigned short result;
if (num == 1 || num == 0)
result = 1;
else
{
result = recfactorial(num-1);
__asm
{
mov cx, result
mov ax, num
mul cx
jnc __local
jmp __carry
__local: mov result, ax
}
}
return result;
__carry: MessageBox(NULL, "Out of range1", NULL, NULL);
return 0;
}
unsigned short Factorial :: factorial(unsigned short num)
{
unsigned short result = 1;
for (unsigned short i = 2; i <= num; i++)
{
__asm
{
mov ax, result
mov cx, i
mul cx
jnc __local
jmp __carry
__local: mov result, ax
}
}
return result;
__carry: MessageBox(NULL, "Out of range2", NULL, NULL);
return 0;
}
#endif
Основной файл (Unit1.cpp)
Код:
//------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
#include "factorial.h"
//------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
unsigned short numfactorial;
Factorial Factorial1;
//------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
numfactorial = StrToInt(Edit1->Text);
Edit2->Text = IntToStr(Factorial1.recfactorial(numfactorial));
}
//------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
numfactorial = StrToInt(Edit1->Text);
Edit3->Text = IntToStr(Factorial1.factorial(numfactorial));
}
//------------------------------------------------------------------------
void __fastcall TForm1::Button3Click(TObject *Sender)
{
if (!Edit1->Text.IsEmpty())
Edit1->Clear();
if (!Edit2->Text.IsEmpty())
Edit2->Clear();
if (!Edit3->Text.IsEmpty())
Edit3->Clear();
Edit1->ReadOnly = false;
}
//------------------------------------------------------------------------
void __fastcall TForm1::Edit1Change(TObject *Sender)
{
if (Edit1->Text.IsEmpty())
return;
int i;
if (TryStrToInt(Edit1->Text, i))
{
if (i > -1)
{
if (i > 65535)
{
MessageBox(0, "Вы ввели значение больше чем 65535!","Сообщение", MB_OK);
Edit1->Clear();
}
AnsiString mynull = Edit1->Text;
if (mynull[1] == '0')
Edit1->ReadOnly = true;
}
else
{
MessageBox(0, "Вы ввели отрицательное число!","Сообщение", MB_OK);
Edit1->Clear();
}
}
else
{
MessageBox(0, "Введенный текст не является числом!","Сообщение", MB_OK);
Edit1->Clear();
}
}
//------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
#include "factorial.h"
//------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
unsigned short numfactorial;
Factorial Factorial1;
//------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
numfactorial = StrToInt(Edit1->Text);
Edit2->Text = IntToStr(Factorial1.recfactorial(numfactorial));
}
//------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
numfactorial = StrToInt(Edit1->Text);
Edit3->Text = IntToStr(Factorial1.factorial(numfactorial));
}
//------------------------------------------------------------------------
void __fastcall TForm1::Button3Click(TObject *Sender)
{
if (!Edit1->Text.IsEmpty())
Edit1->Clear();
if (!Edit2->Text.IsEmpty())
Edit2->Clear();
if (!Edit3->Text.IsEmpty())
Edit3->Clear();
Edit1->ReadOnly = false;
}
//------------------------------------------------------------------------
void __fastcall TForm1::Edit1Change(TObject *Sender)
{
if (Edit1->Text.IsEmpty())
return;
int i;
if (TryStrToInt(Edit1->Text, i))
{
if (i > -1)
{
if (i > 65535)
{
MessageBox(0, "Вы ввели значение больше чем 65535!","Сообщение", MB_OK);
Edit1->Clear();
}
AnsiString mynull = Edit1->Text;
if (mynull[1] == '0')
Edit1->ReadOnly = true;
}
else
{
MessageBox(0, "Вы ввели отрицательное число!","Сообщение", MB_OK);
Edit1->Clear();
}
}
else
{
MessageBox(0, "Введенный текст не является числом!","Сообщение", MB_OK);
Edit1->Clear();
}
}
//------------------------------------------------------------------------
Исправил с 9 всё работает, а вот если ввести 65535 не работает, только не рекурсивная функция работает правельно, почему и как поправить рекурсивную функцию?
Cообщение "Out of range1" должно выводится не только при вводе 9, а 9 и больше?. В моей программе ограничение стоит на ввод не больше 65535.
Я ввожу 65535 и хочу вычислить факториал с помощью рекурсивной функции и возникает ошибка.
Ошибка такая.
Выскакивает окно Debugger Exception Notification в этом окне написано
Project factorial.exe raised exception EStackOverflow with message 'Stack overflow'. Process stopped. Use step or Run continue.
Как поправить рекурсивную функцию, помогите пожалуйста.
Ты принимаешь участие в конкурсе на самый бессмысленный код?
Ведь задача решается в три строчки, без классов, без ассемблера и даже без рекурсии. Они здесь совершенно не нужны.
Код:
void main()
{
unsigned long ddNumber = 5, // for example
ddResult;
__asm
{
mov ecx, ddNumber
mov eax, 1
LP: mul ecx
loop LP
mov ddResult, eax
}
}
{
unsigned long ddNumber = 5, // for example
ddResult;
__asm
{
mov ecx, ddNumber
mov eax, 1
LP: mul ecx
loop LP
mov ddResult, eax
}
}
А ведь действительно, всего 3 строчки кода, а факториал-то тоже умеют считать! Чудеса какие-то... :eek:
Код:
unsigned long long fac(int val) {
unsigned long long fact;
int i;
for(i = 1,fact = 1; i <= val && (fact *= i); ++i);
return fact;
}
unsigned long long fact;
int i;
for(i = 1,fact = 1; i <= val && (fact *= i); ++i);
return fact;
}
Цитата: igor_nf
Кто нибудь может объяснить, зачем здесь асм? Если уж пишете на Си, то на Си и пишите. Или тогда на чистом асме. Сама задача вычисления факториала на Си решается элементарно:
Код:
unsigned long long fac(int val) {
unsigned long long fact;
int i;
for(i = 1,fact = 1; i <= val && (fact *= i); ++i);
return fact;
}
unsigned long long fact;
int i;
for(i = 1,fact = 1; i <= val && (fact *= i); ++i);
return fact;
}
Ну если убрать ошибки из этого кода, то это будет то, что нужно автору.
Код:
#include <stdio.h>
unsigned long long fac(int val) {
unsigned long long fact;
int i;
for(i = 1,fact = 1; i <= val && (fact *= i); ++i);
return fact;
}
int main(int ac, char **av) {
int i;
for(i = 0; i < 10; ++i)
printf("Fac of %d is %lld\n", i, fac(i));
return 0;
}
unsigned long long fac(int val) {
unsigned long long fact;
int i;
for(i = 1,fact = 1; i <= val && (fact *= i); ++i);
return fact;
}
int main(int ac, char **av) {
int i;
for(i = 0; i < 10; ++i)
printf("Fac of %d is %lld\n", i, fac(i));
return 0;
}
Результат:
Код:
Fac of 0 is 1
Fac of 1 is 1
Fac of 2 is 2
Fac of 3 is 6
Fac of 4 is 24
Fac of 5 is 120
Fac of 6 is 720
Fac of 7 is 5040
Fac of 8 is 40320
Fac of 9 is 362880
Fac of 1 is 1
Fac of 2 is 2
Fac of 3 is 6
Fac of 4 is 24
Fac of 5 is 120
Fac of 6 is 720
Fac of 7 is 5040
Fac of 8 is 40320
Fac of 9 is 362880
Неосилил. Green, где ошибка-то?
Цитата: igor_nf
Результат:
Код:
Fac of 0 is 1
Fac of 1 is 1
Fac of 2 is 2
Fac of 3 is 6
Fac of 4 is 24
Fac of 5 is 120
Fac of 6 is 720
Fac of 7 is 5040
Fac of 8 is 40320
Fac of 9 is 362880
Fac of 1 is 1
Fac of 2 is 2
Fac of 3 is 6
Fac of 4 is 24
Fac of 5 is 120
Fac of 6 is 720
Fac of 7 is 5040
Fac of 8 is 40320
Fac of 9 is 362880
Неосилил. Green, где ошибка-то?
Это не является удовлетворительным набором тестов, т.к. не учитываются граничные значения.
Смотрим:
Код:
Fac of -1 is 1
Fac of 66 is 0
Fac of 66 is 0
кроме того у автора топика функция имеет сигнатуру:
unsigned short recfactorial(unsigned short num)
а не
unsigned long long fac(int val)
Цитата:
Это не является удовлетворительным набором тестов, т.к. не учитываются граничные значения.
Впрочем, я и не утверждал, что данный вариант функции может что-то большее. Проверку на переполнение, думаю, вставить не проблема. Предполагал на входе алгоритма только положительные небольшие по абсолютной величине числа. По поводу прототипа:
Код:
unsigned short recfactorial(unsigned short num)
Я не понимаю, почему short - автору что, памяти так жалко?
ну что вы прицепились, может человеку надо написать программу на Си со вставкой кода из Ассемблера. Аsm легко связать с языками более высокого уровня. Главное учитывать несколько правил, и всё ок ;)