Модераторы: Snowy, MetalFan, bems, Poseidon
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Помогите, найти ошибку в коде! 
:(
    Опции темы
Zodt
Дата 10.5.2014, 18:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 4
Регистрация: 10.5.2014

Репутация: нет
Всего: нет



Не могу понять где ошибся, когда ввожу обычные числа все в порядке, а как только десятичные все рушится... даже extended вместо integer'a ставил, думал в этом проблема, но увы...

Код

program kurs_delphi;
{$APPTYPE CONSOLE}
uses
  SysUtils;
var
i,V,Qmax,Qmin: integer;
Q,p,S,pmax: real;
Qtab: array [0..12] of integer =(23,34,45,57,68,53,45,42,49,58,67,78,93);
Qras: array [0..12] of real;
c: array [0..12] of integer;

begin
  V:=212;
  i:=0;
  Qmax:=Qtab[i];
  Qmin:=Qtab[i];
  S:=0;

  while V<=290 do begin
  begin
  c[i]:=V;

  // Подбор уравнения
  if V<215 then Q:=11.3*V-683.65
   else
      if V<222 then Q:=1.5714*V-280.85
      else
         if V<236 then Q:=1.64*V-342.71
         else
            if V<243 then Q:=(-0.42)*V+146.14
            else
              if V<250 then Q:=V-201
              else
                if V<270 then Q:=0.9*V-176
                else
                  if V<=290 then Q:=1.3*V-284                 
  end;
  Qras[i]:=Q;
  if (V<215) then V:=V+1 else     // Смена шага
   if (V<250) then V:=V+7 else V:=V+10;
  i:=i+1;
  end;

  for i:=0 to 12 do  // Нахождение Qmax, Qmin
   begin
      if Qmax<Qtab[i] then Qmax:=Qtab[i];
      if Qmin>Qtab[i] then Qmin:=Qtab[i];
   end;

  for i:=0 to 12 do
   begin
     write(c[i],': ',Qras[i]:0:2);  // Вывод таблицы
     if Qras[i]<>Qtab[i] then  // Вывод погрешности, если она есть
      begin
        p:=abs(Qras[i]-Qtab[i])/(Qmax-Qmin)*100;
        if pmax < p then pmax:=p;    // нахождение максимальной локальной погрешности
        write(' (',p:0:2,'%)');
        S:=S+p;  // нахождение суммарной погрешности
      end;
      writeln('');
   end;
   writeln('max loc pogr = ',pmax:0:2);
   writeln('Summ pogr = ',S:0:2);
  readln;
end.?


Это сообщение отредактировал(а) Zodt - 10.5.2014, 18:07
PM MAIL   Вверх
Фантом
Дата 10.5.2014, 18:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Вы это прекратите!
***


Профиль
Группа: Участник Клуба
Сообщений: 1516
Регистрация: 23.3.2008

Репутация: нет
Всего: 49



Цитата(Zodt @  10.5.2014,  19:06 Найти цитируемый пост)
Не могу понять где ошибся, когда ввожу обычные числа все в порядке, а как только десятичные все рушится...

Мы тоже. Поскольку в программе нет ни одного ввода, да и отличие "обычных" чисел от "десятичных" - тоже тайна, то, сокрее всего, и не поймем.
PM   Вверх
Zodt
Дата 10.5.2014, 19:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 4
Регистрация: 10.5.2014

Репутация: нет
Всего: нет



1) Мне ввод в программе не нужен, я в коде подставляю уравнения и цифры. Программа должна рассчитывать погрешность по 1 прямой и суммарную погрешность.
2) Под обычными, извиняюсь, привычка, подразумевал целые.
PM MAIL   Вверх
Фантом
Дата 10.5.2014, 21:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Вы это прекратите!
***


Профиль
Группа: Участник Клуба
Сообщений: 1516
Регистрация: 23.3.2008

Репутация: нет
Всего: 49



Цитата(Zodt @  10.5.2014,  20:22 Найти цитируемый пост)
1) Мне ввод в программе не нужен, я в коде подставляю уравнения и цифры.

Это замечательно, но мы-то откуда должны узнать, что и куда подставляется? Если уж с русским языком проблем больше, чем с Паскалем, давайте хотя бы два примера: работающий с "обычными" числами и не работающий - с "десятичными".

Цитата(Zodt @  10.5.2014,  20:22 Найти цитируемый пост)

2) Под обычными, извиняюсь, привычка, подразумевал целые. 

Жаль, что у Вас не выработалась привычка нормально излагать свои мысли (или хотя бы вопросы). Это, кстати, для программирования тоже весьма и весьма полезно.
PM   Вверх
Zodt
Дата 10.5.2014, 22:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 4
Регистрация: 10.5.2014

Репутация: нет
Всего: нет



Вот вариант с десятичными числами(не работающая).
Код

program Kypcach;
{$APPTYPE CONSOLE}
uses
  SysUtils;

var
i: integer;
Qmax,V,Qmin: extended;
Q,p,S,pmax: real;
Qtab: array [0..12] of extended =(0.07 , 0.21 , 0.36 , 0.49 , 0.53 , 0.44 , 0.31, 0.36 , 0.29 , 0.49 ,0.62 , 0.74 , 0.87);
Qras: array [0..12] of real;
c: array [0..12] of extended;

begin
  V:=0;
  i:=0;
  Qmax:=Qtab[i];
  Qmin:=Qtab[i];
  S:=0;

  while V<=8.2 do begin
  begin
  c[i]:=V;

  if V<1.2 then Q:=0.35*V+0.07
  else
  if V<1.8 then Q:=V/15+0.41
  else
  if V<3 then Q:=0.86-0.183*V
  else
  if V<3.8 then Q:=0.385-0.025*V
  else
  if V<4.6 then Q:=0.0583*V+0.091
  else
  if V<6.2 then Q:=0.1625*V-0.3875
  else
  if V<8.2 then Q:=0.125*V-0.155
  end;
  Qras[i]:=Q;
  if (V<1.2) then V:=V+0.4 else
  if (V<3) then V:=V+0.6 else
   if (V<6.2) then V:=V+0.8 else V:=V+1;
  i:=i+1;
  end;

  for i:=0 to 12 do
  begin
  if Qmax<Qtab[i] then Qmax:=Qtab[i];
  if Qmin>Qtab[i] then Qmin:=Qtab[i];
  end;

  for i:=0 to 12 do
  begin
  write(c[i],': ',Qras[i]:0:2);
  if Qras[i]<>Qtab[i] then
  begin
  p:=abs(Qras[i]-Qtab[i])/(Qmax-Qmin)*100;
  if pmax < p then pmax:=p;
  write(' (',p:0:2,'%)');
  S:=S+p;
  end;
  writeln('');
  end;
  writeln('max loc pogr = ',pmax:0:2);
  writeln('Summ pogr = ',S:0:2);
  readln;
end.

PM MAIL   Вверх
ФедосеевПавел
Дата 10.5.2014, 22:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 291
Регистрация: 7.2.2009

Репутация: нет
Всего: 10



И я свои 5 копеек добавлю.

У тебя, похоже - кусочно-линейная аппроксимация функции.
При этом, остаётся открытым вопрос о равенстве значения аргумента V для табличной и для вычисляемой функций для одного и того же индекса i.

Может быть, задавать два массива - Qtab[...] и Vtab[...] вместо странного и, возможно, ошибочного пересчёта шага? И тогда будет точное соответствие аргументов как для табличной функции, так и для полученной по формуле. Исчезнет потенциальная угроза выхода индека за пределы массива.

Это тоже прикольно для сравнения чисел разных типов, особенно для real.
Код
     if Qras[i]<>Qtab[i] then  // Вывод погрешности, если она есть


Но это то, что бросилось в глаза. Возможно, что вопрос был о другом...
PM   Вверх
Фантом
Дата 10.5.2014, 23:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Вы это прекратите!
***


Профиль
Группа: Участник Клуба
Сообщений: 1516
Регистрация: 23.3.2008

Репутация: нет
Всего: 49



Цитата(Zodt @  10.5.2014,  23:35 Найти цитируемый пост)
Вот вариант с десятичными числами(не работающая).

В обоих случаях переменная pmax при первой проверке не инициализирована, поэтому внутри нее оказывается что попало.

Кроме того, второй вариант такой же рабочий, как и первый (в том смысле что собирается и запускается, выдавая результаты примерно той же степени осмысленности). Что Вам не нравится?
PM   Вверх
Zodt
Дата 10.5.2014, 23:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 4
Регистрация: 10.5.2014

Репутация: нет
Всего: нет



Цитата(ФедосеевПавел @  10.5.2014,  22:52 Найти цитируемый пост)
И я свои 5 копеек добавлю.

У тебя, похоже - кусочно-линейная аппроксимация функции.
При этом, остаётся открытым вопрос о равенстве значения аргумента V для табличной и для вычисляемой функций для одного и того же индекса i.


Да ты прав, у меня кусочно-линейная аппроксимация функции.


Цитата(ФедосеевПавел @  10.5.2014,  22:52 Найти цитируемый пост)

Может быть, задавать два массива - Qtab[...] и Vtab[...] вместо странного и, возможно, ошибочного пересчёта шага? И тогда будет точное соответствие аргументов как для табличной функции, так и для полученной по формуле. Исчезнет потенциальная угроза выхода индека за пределы массива.


Честно говоря, я не совсем понял что ты имеешь ввиду. Точнее смысл уловил, но вот как воплотить в жизнь, мягко говоря, не совсем

Цитата(ФедосеевПавел @  10.5.2014,  22:52 Найти цитируемый пост)

Это тоже прикольно для сравнения чисел разных типов, особенно для real.
код Pascal/Delphi
1:
     if Qras[i]<>Qtab[i] then  // Вывод погрешности, если она есть


Не заметил, спасибо, что указал на ошибочку, правда, она ничего толком не поменяла в итоге=(

PM MAIL   Вверх
ФедосеевПавел
Дата 10.5.2014, 23:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 291
Регистрация: 7.2.2009

Репутация: нет
Всего: 10



Таблицу точных значений функции и аргумента можно задато так (значения для Vtab взяты с потолка):
Код
var
  Qtab: array [0..12] of extended =(0.07 , 0.21 , 0.36 , 0.49 , 0.53 , 0.44 , 0.31, 0.36 , 0.29 , 0.49 ,0.62 , 0.74 , 0.87);
  Vtab: array [0..12] of extended =(0.01 , 0.02 , 0.03 , 0.09 , 0.12 , 0.42 , 0.71, 0.96 , 1.29 , 1.69 ,1.82 , 2.40 , 3.88);
............................
begin
  for i:=0 to 12 do   (* было  while V<=8.2 do begin*)
  begin
    V:=Vtab[i];
(*    c[i]:=V;                                    <------------------ раз есть Vtab, то c[i] уже не нужен*)

  if V<1.2 then Q:=0.35*V+0.07
  else
  if V<1.8 then Q:=V/15+0.41
  else
  if V<3 then Q:=0.86-0.183*V
  else
  if V<3.8 then Q:=0.385-0.025*V
  else
  if V<4.6 then Q:=0.0583*V+0.091
  else
  if V<6.2 then Q:=0.1625*V-0.3875
  else
  if V<8.2 then Q:=0.125*V-0.155
  end;
  Qras[i]:=Q;
(*                               <--------------------------  удалить блок за ненадобностью
  if (V<1.2) then V:=V+0.4 else
  if (V<3) then V:=V+0.6 else
   if (V<6.2) then V:=V+0.8 else V:=V+1;
  i:=i+1;
*)
  end;
........................................
end.

Теперь, имея все данные для расчётов, если доработать прогу, можно даже самостоятельно вычислять коэффициенты в самой программе.

Это сообщение отредактировал(а) ФедосеевПавел - 10.5.2014, 23:37
PM   Вверх
ФедосеевПавел
Дата 11.5.2014, 01:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 291
Регистрация: 7.2.2009

Репутация: нет
Всего: 10



В общем, твоя прога из первого поста после упрощения будет такой
Код
program kurs_delphi;

{$APPTYPE CONSOLE}
uses
  SysUtils;

  function PiecewiseLinear(x: real; a, b, Xi: array of real): real;
  var
    i: integer;
  begin
    i := low(Xi);
    repeat
      Inc(i);
    until (x < Xi[i]) or (i = high(Xi));
    PiecewiseLinear := a[i] * x + b[i];
  end;

var
  i:    integer;
  V, Q, Qmax, Qmin, p, pmax, S: real;
  Vtab: array [0..12] of real;
  Qtab: array [0..12] of real = (23, 34, 45, 57, 68, 53, 45, 42, 49, 58, 67, 78, 93);
  Qras: array [0..12] of real;

  {коэффициенты для вычисления кусочно-линейной функции}
  a:  array [0..7] of real = (0, 11.3, 1.5714, 1.64, -0.42, 1, 0.9, 1.3);
  b:  array [0..7] of real = (0, -683.65, -280.85, -342.71, 146.14, -201, -176, -284);
  Xi: array [0..7] of real = (0, 215, 222, 236, 243, 250, 270, 290);

begin
  {раз уж вычисляем значения аргументов}
  V := 212;
  for i := 0 to 12 do
  begin
    Vtab[i] := V;
    if (V < 215) then
      V := V + 1
    else     // Смена шага
    if (V < 250) then
      V := V + 7
    else
      V := V + 10;
  end;

  for i := 0 to 12 do
    Qras[i] := PiecewiseLinear(Vtab[i], a, b, Xi);

  Qmax := Qtab[0];
  Qmin := Qtab[0];
  for i := 1 to 12 do  // Нахождение Qmax, Qmin
  begin
    if Qmax < Qtab[i] then
      Qmax := Qtab[i];
    if Qmin > Qtab[i] then
      Qmin := Qtab[i];
  end;

  S := 0;
  pmax := 0;
  for i := 0 to 12 do
  begin
    Write(Vtab[i]: 4: 1, ': ', Qras[i]: 7: 2, ' [', Qtab[i]: 0: 2, ']');  // Вывод таблицы
    p := abs(Qras[i] - Qtab[i]) / (Qmax - Qmin) * 100;
    if p > 0.01 then  // Вывод погрешности, если она есть
    begin
      if pmax < p then
        pmax := p;    // нахождение максимальной локальной погрешности
      Write(' (', p: 0: 2, '%)');
      S := S + p;  // нахождение суммарной погрешности
    end;
    WriteLn('');
  end;
  WriteLn('max loc pogr = ', pmax: 0: 2);
  WriteLn('Summ pogr = ', S: 0: 2);
  readln;
end.

Но она делает точно тоже самое. Итак, приходим туда откуда пришли - что тебя не устраивает?
PM   Вверх
ФедосеевПавел
Дата 12.5.2014, 07:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 291
Регистрация: 7.2.2009

Репутация: нет
Всего: 10



Zodt, задавай вопросы на форуме. Как видишь, я не обращаю внимание на наличие сообщений в PM.
Т.к. ты задал вопрос в личку, то в личку и отвечаю.
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Для новичков"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0687 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.