Паскаль ошибка деления на ноль

skvr

0 / 0 / 0

Регистрация: 30.01.2015

Сообщений: 32

1

Вещественное деление на ноль

20.03.2015, 09:43. Показов 7881. Ответов 6

Метки нет (Все метки)


Студворк — интернет-сервис помощи студентам

Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
Program test;
uses crt;
var
x : integer;
y : real;
begin
ClrScr;
write('Введите значение x');
read(x);
begin y:=((sin(sqr(x))/cos(sqr(x)))+cos(x))/(ln(abs(sqr(x)+1)));
write ('Ответ=', y:3:2);
end
end.

Сама формула работает и при x=1 получается нужный ответ, но при делении на ноль программа выдает ошибку «вещественное деление на 0»

Что следует сделать, чтобы программа выполнялась?



0



Programming

Эксперт

94731 / 64177 / 26122

Регистрация: 12.04.2006

Сообщений: 116,782

20.03.2015, 09:43

6

1646 / 1075 / 1081

Регистрация: 03.07.2013

Сообщений: 4,507

20.03.2015, 09:46

2

Математику в школе не проходили? Делить на ноль нельзя.
Перед делением проводите проверку на значение знаменателя.

Ну есть еще способ, если устроит (если задача это позволит) — перед делением увеличить/уменьшить знаменатель на мизерную величину 0.000001. Главное чтобы эта мизерная величина (при нуле) не вызвала переполнение типа.



0



0 / 0 / 0

Регистрация: 30.01.2015

Сообщений: 32

20.03.2015, 16:32

 [ТС]

3

Цитата
Сообщение от APALoff
Посмотреть сообщение

Математику в школе не проходили? Делить на ноль нельзя.
Перед делением проводите проверку на значение знаменателя.

Ну есть еще способ, если устроит (если задача это позволит) — перед делением увеличить/уменьшить знаменатель на мизерную величину 0.000001. Главное чтобы эта мизерная величина (при нуле) не вызвала переполнение типа.

Как провести проверку именно знаменателя?

я написал
if ln(x):=0
then
write (‘Ответ = 0’)

но тогда код ошибку выдает: Встречено ‘:=’, а ожидался оператор



0



1646 / 1075 / 1081

Регистрация: 03.07.2013

Сообщений: 4,507

20.03.2015, 16:52

4

Между оператором присваивания и оператором сравнения имеется существенная разница. Об этом Вы можете прочитать в любом учебнике.



0



Puporev

Почетный модератор

64289 / 47588 / 32739

Регистрация: 18.05.2008

Сообщений: 115,181

20.03.2015, 17:08

5

Pascal
1
2
3
4
5
6
7
8
9
10
11
var x,y:real;
begin
write('Введите значение x');
readln(x);
if x=0 then write('y не определено')//ln(0+1)=0
else
 begin
  y:=((sin(sqr(x))/cos(sqr(x)))+cos(x))/(ln(sqr(x)+1)); //нафига abs, x^2+1 всегда >0
  write ('Ответ=', y:0:2);
 end;
end.



1



skvr

0 / 0 / 0

Регистрация: 30.01.2015

Сообщений: 32

20.03.2015, 18:13

 [ТС]

6

Цитата
Сообщение от Puporev
Посмотреть сообщение

Pascal
1
2
3
4
5
6
7
8
9
10
11
var x,y:real;
begin
write('Введите значение x');
readln(x);
if x=0 then write('y не определено')//ln(0+1)=0
else
 begin
  y:=((sin(sqr(x))/cos(sqr(x)))+cos(x))/(ln(sqr(x)+1)); //нафига abs, x^2+1 всегда >0
  write ('Ответ=', y:0:2);
 end;
end.

хех, я также делал, но препод агрился на то, что в числителе при нуле все норм и распространять if x=0 then write(‘y не определено’) не надо
я думал, может как-то распространить это условие, но только на знаменатель ?
ток хз как



0



Puporev

Почетный модератор

64289 / 47588 / 32739

Регистрация: 18.05.2008

Сообщений: 115,181

20.03.2015, 18:22

7

Ну формально нужно так

Pascal
1
if (x=0)or(cos(sqr(x))=0) then write('y не определено')

но ввести с клавиатуры число, равное abs(sqrt(pi/2)), невозможно.



1



IT_Exp

Эксперт

87844 / 49110 / 22898

Регистрация: 17.06.2006

Сообщений: 92,604

20.03.2015, 18:22

7

Форум мехмата ЮФУ

Загрузка…

I’ve FreeDos OS installed on VirtualBox on a windows xp, dual core, host machine. I installed FreeDos because I wanted to run a Pascal code using Turbo Pascal. When I run the code, it throws error ‘Error 200: Division by zero.’. How can I solve this?

-Turbo Pascal 7.0, Free DOS 1.1, Virtual Box 4.3.6, Windows XP Service Pack 3 Host machine
-This error is unfortunately caused by fast Pentium CPUs and I found a patch on the internet that will resolve the error. (www.filewatcher.com/m/bp7patch.zip.62550-0.html) Now the other problem is, when i was tracing the code, it hangs at ‘RxWait procedure when trying to execute while not odd(port[RXTX + 5]) do;’

uses crt;

const
{ COM1: RS232 port address }
RXTX = $3F8; { $2F8 if COM2: is used }
ACK = 6;
NAK = 21;
ESC = 27;

var
dummy,
checkSum : integer;
key : char;
protocol : integer;

procedure InitComm;
{ Set baudrate to 9600, 8 bits, no parity, 1 stop bit }
var i : integer;
begin
i := 1843200 div 9600 div 16;
port[RXTX + 3] := $80;
port[RXTX + 1] := hi(i);
port[RXTX]:= lo(i);
port[RXTX + 3] := 3;
port[RXTX + 4] := $A;
while odd(port[RXTX + 5]) do
begin
dummy := port[RXTX];
delay(10);
end;
end; { InitComm }

procedure Tx(data : integer);
{ Transmit a character on serial channel }
begin
while port[RXTX + 5] and $20 = 0 do;
port[RXTX] := data and $FF;
end; { Tx }

function RxWait : integer;
{ Waits for a character from serial channel }
begin
while not odd(port[RXTX + 5]) do;
RxWait := port[RXTX];
end; { RxWait }

procedure Tx2(data : integer);
{ Transmit a char on serial channel + Calculate check sum }
begin
Tx(data);
checkSum := (checkSum + data) and $FF;
end; { Tx2 }

procedure TxCommand(c1, c2 : char;
sendCheckSum : boolean);
{ Transmit command (no data) on serial channel }
begin
Tx(ESC);
checkSum := 0;
Tx2(ord(c1));
Tx2(ord(c2));
if sendCheckSum then
begin
Tx2(checkSum);
dummy := RxWait;
end;
end; { TxCommand }

function ReadNumber(n : integer) : real;
{ Read n bytes from serial channel }
var
number: real;
i : integer;
begin
number := 0;
checkSum := 0;
for i := 1 to n do
number := number * 256 + RxWait;
dummy := RxWait;
ReadNumber := number;
end; { ReadNumber }

procedure Revisions;
var
tmp : integer;
sw,
prot : real;
begin
TxCommand('P', 'R', FALSE);
checkSum := 0;
tmp := RxWait;
sw := tmp + RxWait / 100.0;
protocol := RxWait;
prot := protocol + RxWait / 100.0;
dummy := RxWait;
tmp := RxWait;
writeln('Software revision: ', sw:4:2);
writeln('Protocol revision: ', prot:4:2);
end; { Revisions }

procedure ReadCountReg;
begin
TxCommand('R', 'C', FALSE);
writeln(ReadNumber(4):11:0, ' coins counted.');
dummy := RxWait;
end; { ReadCountReg }

procedure ReadAccReg;
begin
TxCommand('R', 'A', FALSE);
writeln(ReadNumber(4):11:0, ' coins in accumulator.');
dummy := RxWait;
end; { ReadAccReg }

procedure Setbatch(limit : longint);
begin
TxCommand('W', 'L', FALSE);
case protocol of
1 : begin
Tx2(limit div 256);
Tx2(limit mod 256);
end;
2 : begin
Tx2( limit div 16777216);
Tx2((limit div 65536) mod 256);
Tx2((limit div 256) mod 256);
Tx2( limit mod 256);
end;
end; { case protocol }
Tx2(checkSum);
dummy := RxWait;
end; { Setbatch }

uses crt;
var i,k:word;
BEGIN
clrscr;

asm
mov cx, i { ; это будет i}
mov si, k {; это будет k}
mov bx, 11 {; число для вычисления модуля}

@l0:
cmp cx, 199 {; если i больше или равно 199 выходим из цикла}
jge @ext1

mov ax, si
shr ax, 1 {; деление k на 2}
add ax, cx {; добавляем i}
xor dx, dx {; очищаем dx для деления}
div bx {; делим на 11}

cmp dx, 5{ ; сравниваем остаток}
jnz @label2{ ; если не равен 5 - то на label2}

sub cx, si{ ; иначе i = i - k}
jmp @l0 ; {в начало цикла}

@label2:
mov ax, si {; подготавливаем деление}
xor dx, dx
mul ax {; умножаем на себя (k*k)}
mov dx, cx
shr dx, 1 {; делим i на 2 }
add ax, dx {; добавляем к резульату k*k}
mov si, ax {; заносим результат в k }
jmp @l0 {; в начало цикла}

@ext1:
{... ; обработка результата}
end;
writeln('REZULTAT-ASSAMBLER');
writeln('k=',k,' i=',i);
readkey;
end.

сам цикл таков

i:=57; k:=19;
while i<199 do
if ((i + k div 2) mod 11) = 5 then i:=i-k else k:=k*k+(i div 2)

Сообщение отредактировано: volvo — 18.01.2007 15:18

Неописанная переменная

begin
  S := 1; // Неизвестное имя S
end.

Все используемые переменные должны быть предварительно описаны с помощью ключевого слова var (внутри блока begin/end или, что обычно хуже, в разделе описаний вначале программы).

Отсутствующая ;

begin
  var S: integer 
  S := 1;         // Компилятор здесь скажет: Ожидалась ; — имеется ввиду предыдущая строка!
end.
begin
  var S := 1 
  S := S + 1  // Аналогично: проблема на предыдущей строке, а на текущей нет, потому что после неё идёт end.
end.

Очень частая ошибка у начинающих. Курсор, как правило, позиционируется в начале следующей строки.

Несовместимость типов при присваивании

begin
  var S: integer := 1.3; // Нельзя преобразовать тип real к integer
end.

Безболезненно можно присваивать только данные одного типа. Если данные — разных типов, то в редких случаях можно преобразовать данные одного типа в данные другого. Например, целое можно преобразовать в вещественное, а символ — в строку. Обратные преобразования не допускаются.

Чтобы не ошибаться в подобных простых случаях в Паскале есть следующая краткая форма объявления и инициализации переменной:

begin
  var S := 1.3; // Тип real будет выведен компилятором автоматически
end.

Отсутствие закрывающего апострофа литеральной строки

begin
  var x := 2;   // x получает тип integer
  var y := 3;   // y получает тип integer
  writeln('Результат сложения равен =, x + y); // Не хватает закрывающего апострофа
end.

Закрыть апостроф надо на той же строке, где расположен открывающий апостроф

Ошибки расстановки запятых и апострофов при выводе строк и выражений

begin
  var x := 2;   // x получает тип integer
  var y := 3;   // y получает тип integer
  writeln(x, '+,' y, '=', x+y); // Неверная расстановка запятых и апострофов
end.

Слишком много запятых и апострофов рядом, потому начинающие часто путаются :)
Надо уяснить правила:

  • запятые разделяют разные элементы вывода
  • все, что находится в апострофах, будет выведено на экран без изменений

Ошибка ввода

begin
  var x: integer;
  read(x); // введите блаблабла и посмотрите, что получится
end.

Это — ошибка во время выполнения. Программа пытается преобразовать введенную строку в число, не может это сделать и завершается с ошибкой.

Аналогичный фрагмент в более современном и предпочтительном синтаксисе:

begin
  var x := ReadInteger;
end.

Ошибка неинициализированной переменной

begin
  var x: integer;
  // Забыли инициализировать или ввести x
  var r := x * x;  // r получает тип integer
  writeln('Квадрат числа ', x, ' = ', r);
end.

Перед использованием любую переменную надо ввести или присвоить ей начальное значение. Это действие называется инициализацией переменной.

Деление на 0

begin
  var x := 0;
  var c := 666 div x; // Здесь происходит деление на 0
end.

Если во время выполнения программа выполнит деление на 0, то она завершится с ошибкой.

Корень из отрицательного числа

begin
  writeln(sqrt(-1)); // Корень из отрицательного числа 
end.

В обычном Паскале возникает ошибка времени выполнения.
В PascalABC.NET выводится NaN — Not a Number

Ссылки

  • Программы для начинающих
  • Сайт PascalABC.NET: Программы и алгоритмы для начинающих

  • Паскаль ошибка встречен конец файла а ожидался оператор
  • Паскаль ошибка времени выполнения значение maxvalue должно быть больше нуля имя параметра maxvalue
  • Паскаль ошибка runtime error
  • Паскаль выдает ошибку неизвестное имя
  • Паскаль абс ошибка ожидался идентификатор