Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2009.06.07;
Скачать: CL | DM;

Вниз

Странности с математикой (real, extended)   Найти похожие ветки 

 
alex989   (2009-04-20 20:47) [0]

Доброго времени суток!

Мне нужно составить программу, заполняющую таблицу вида:

X| | | |
Y| | | |

по функции: Y = A * sin(2 * pi * f * X)
числа A и f - постоянные, X меняется с определенным шагом. Я сделал массив 2 строки, 100 столбцов (с запасом =)) И пытаюсь его заполнить, но выходит ахинея.
вот код:

program Project3;

{$APPTYPE CONSOLE}

uses
 SysUtils, Math;

var
 Farr: array [0..1, 0..100] of extended;
 A, f, t, x, d: extended;
 j: integer;
 s: string;

begin
 A := 5;
 f := 50;
 t := 5;
 d := 0.1; // шаг
 j := 0; // счетчик для массива
 x := d;
 repeat
   Farr[0,j] := x;
   Farr[1,j] := A * sin(2 * pi * f * x);
   x := x + d;
   j := j + 1;
   writeln((FloatToStr(Farr[0,j])+"   "+FloatToStr(Farr[1,j])+#10#13));
 until x >= t;

 readln(s); // чтобы окошко не закрылось
end.


Проблемы следующие:
неправильно рсчитывается элемент массива, т.е. A * sin(2 * pi * f * x), если посчитать на калькуляторе винды, числа абсолютно разные.
следующая непонятка, если поменять тип данных на real (вместо extended), результаты будут другими, но опять же - неправильными...
и наконец функция printf выводи нули, хотя массив числами заполняется (правда, неправильно).. может я как-то не так использую FloatToStr?

Заранее спасибо!


 
FireMan_Alexey ©   (2009-04-20 21:15) [1]

Может дело в том, что угол в функции рассчитывается в радианах?


 
FireMan_Alexey ©   (2009-04-20 21:25) [2]

Увеличивай J после вывода, а не до!!!


 
Servy ©   (2009-04-20 21:27) [3]


>   Farr[0,j] := x;
>   Farr[1,j] := A * sin(2 * pi * f * x);
>   x := x + d;
>   j := j + 1;
>   writeln((FloatToStr(Farr[0,j])+"   "+FloatToStr(Farr[1,
> j])+#10#13));


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


> если посчитать на калькуляторе винды, числа абсолютно разные

Конкретные примеры в студию. Возможно, в калькуляторе у тебя Sin считается от аргумента в градусах, тогда как делфевый Sin ждет аргумента в радианах (что описано в справке).


> readln(s); // чтобы окошко не закрылось


Readln без параметров ждет нажатия ентера, s тут лишняя.


 
FireMan_Alexey ©   (2009-04-20 21:52) [4]

Да вообще формула не понятная!
один градус для Дельфийного синуса = (Пи/180). А потом умножай на нужный угол и все! :)
Зачем прибавлять 0.1 когда каждый раз умножаешь на 50? Прибавляй 0.5, а 50 в топку!
И вообще че ты считаешь?


 
FireMan_Alexey ©   (2009-04-20 21:57) [5]

А с REAL и EXTENDED разница может быть лишь в том случае когда {$REALCOMPATIBILITY ON}, тогда на реал 6 байт выделяется, а так 8, точно как у дабла! :)


 
Servy ©   (2009-04-20 23:11) [6]

> А с REAL и EXTENDED разница может быть лишь в том случае
> когда {$REALCOMPATIBILITY ON}, тогда на реал 6 байт выделяется,
> а так 8, точно как у дабла! :)


Неправда ваша, Extended не тоже самое что Double.


Type     Range                              Significant digits   Size in bytes
...
Double   5.0 x 10^-324 .. 1.7 x 10^308      15-16                8
...
Extended 3.6 x 10^-4951 .. 1.1 x 10^4932    19-20                10
...


Из стандартной справки. Так что, кое какая разница между Real и Extended присутствует в любом случае ^_^


 
FireMan_Alexey ©   (2009-04-21 00:26) [7]


> Servy ©   (20.04.09 23:11) [6]

А я и не говорил, что они по размеру совпадают!
Я говорил, что при вычислении, выше описанной формулы, глобальной разницы быть не может!

Смысл не в том что 8 или 10 байт, а в том что 0.5 оно и в Африке 0.5!
От смены 8 или 10 байтной переменной огромной погрешности в вычислении обыкновенного синуса быть не может!
Погрешность в вычислении можно заметить если использовать 4 байтный (сингл) и 8 байтную (даблу). Я замечал погрешность в 1Е-08, а автор пишет:


> если поменять тип данных на real (вместо extended), результаты
> будут другими


Ну если считать показатели где то в 18 цифре после запятой, то я соглашусь с вашими аргументами, но такая точность нужна лишь в космосе или 3Д игрушке на больших расстояниях! Ну или в Автокаде...


 
Германн ©   (2009-04-21 01:37) [8]


> Смысл не в том что 8 или 10 байт, а в том что 0.5 оно и
> в Африке 0.5!

А вот нифига! В Африке 0.5 может и не быть 0.5!
Да и не только в Африке! :)


 
Servy ©   (2009-04-21 04:23) [9]

> я и не говорил, что они по размеру совпадают!


Зато вы говорили:


> А с REAL и EXTENDED разница может быть лишь в том случае
> когда {$REALCOMPATIBILITY ON},



> От смены 8 или 10 байтной переменной огромной погрешности
> в вычислении обыкновенного синуса быть не может!


На первой итерации цикла из [0], использование Real дает ответ 8,71*10^-15, использование Extended 5,42*10^-19. Разница в 4 раза для вас недостаточно огромна?


> 0.5 оно и в Африке 0.5!

0,5 оно в любой двоичной Африке 0,5, а вот 0,1 уже от размера двоичной Африки зависит.


 
Servy ©   (2009-04-21 04:25) [10]

> Разница в 4 раза

Прошу прощения, на 4 порядка, в ~10000 раз.


 
alex989   (2009-04-21 08:15) [11]

Спасибо за ответы!
Насчет вывода нулей понятно.

Считаю я такую вешь (кто шарит в электронике, поймет):
U = A * sin(2*pi*f*t)

A-амплитуда сигнала, f - частота, t - время (как я думаю, t и есть координата x)

нужно заполнить таблицу, чтобы нарисовать по ней синусоиду. Но что-то не вяжется тут...


> Может дело в том, что угол в функции рассчитывается в радианах?

можно по-подробнее?


 
alex989   (2009-04-21 08:15) [12]

Спасибо за ответы!
Насчет вывода нулей понятно.

Считаю я такую вешь (кто шарит в электронике, поймет):
U = A * sin(2*pi*f*t)

A-амплитуда сигнала, f - частота, t - время (как я думаю, t и есть координата x)

нужно заполнить таблицу, чтобы нарисовать по ней синусоиду. Но что-то не вяжется тут...


> Может дело в том, что угол в функции рассчитывается в радианах?

можно по-подробнее?


 
alex989   (2009-04-21 08:19) [13]


> На первой итерации цикла из [0], использование Real дает
> ответ 8,71*10^-15, использование Extended 5,42*10^-19. Разница
> в 4 раза для вас недостаточно огромна?


вот и я про тоже :(

x (или t-по формуле) - это время, измерять его просто в секундах не получится, т.к. частота сигнала 50 Гц, потому я и взял 0,1


> 0,5 оно в любой двоичной Африке 0,5, а вот 0,1 уже от размера
> двоичной Африки зависит.

а от чего конкретно?


 
Jeer ©   (2009-04-21 10:05) [14]


> потому я и взял 0,1


Слишком крупный шаг.
Чтобы "увидеть" синусоиду надо сделать мельче шаг по времени.


 
12 ©   (2009-04-21 12:14) [15]

> 0,5 оно в любой двоичной Африке 0,5, а вот 0,1 уже от размера
> двоичной Африки зависит.
а от чего конкретно?

от того же, что и 1/3 для человека
1/3 = 0.(3)
в периоде, для человека понятно, а вот записть это конечной дробью можно только примерно.
0.333333 или 0.333333333333333333333 или
второе точнее первого
Если больше ячеек для хранения числа, то и представление точнее. А, значит, и разный результат
0.333333 < 0.333333333333333333333
т.е.
1/3 <> 1/3,  для разных Африк



Страницы: 1 вся ветка

Текущий архив: 2009.06.07;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.012 c
15-1238739088
Patrick
2009-04-03 10:11
2009.06.07
Представление данных


15-1238704205
Юрий
2009-04-03 00:30
2009.06.07
С днем рождения ! 3 апреля 2009 пятница


15-1238877001
Юрий
2009-04-05 00:30
2009.06.07
С днем рождения ! 5 апреля 2009 воскресенье


15-1238953192
ЭРИКА
2009-04-05 21:39
2009.06.07
С ДНЕМ РОЖДЕНИЯ!


3-1222067899
Клён новичок
2008-09-22 11:18
2009.06.07
Как подставить переменную в запрос?