Клубове Дир.бг
powered by diri.bg
търси в Клубове diri.bg Разширено търсене

Вход
Име
Парола

Клубове
Dir.bg
Взаимопомощ
Горещи теми
Компютри и Интернет
Контакти
Култура и изкуство
Мнения
Наука
Политика, Свят
Спорт
Техника
Градове
Религия и мистика
Фен клубове
Хоби, Развлечения
Общества
Я, архивите са живи
Клубове Дирене Регистрация Кой е тук Въпроси Списък Купувам / Продавам 12:57 28.06.24 
Компютри и Интернет
   >> Delphi
*Кратък преглед

Страници по тази тема: 1 | 2 | >> (покажи всички)
Тема Много интересно нещонови  
Автор Lizard (приятел)
Публикувано12.08.03 14:56



Мислите ли че
r := r*100; r := round(r); r := r/100;
е еквивалентно на
r := round(r*100)/100;

Аз мислех, че е,
но тествайте това

var
r : real;
begin
r := 0.975;
r := round(r*100)/100;
Memo1.Lines.Add(format('%0.3f',[r]));

r := 0.975;
r := r*100; r := round(r); r := r/100;
Memo1.Lines.Add(format('%0.3f',[r]));

end;



Тема Re: Много интересно нещо [re: Lizard]  
Автор Hateras (чакащ)
Публикувано12.08.03 17:50



мда, мноо интересно...
птичето се крие някъде в round(r*100), и по-конкретно при обръщането на "малките" FP типове към Extended - например
0.975 (Single) става 0,975000023841858 (Extended), round(r*100)=98.000
0.955 (Single) става 0,954999983310699 (Extended), round(r*100)=95,000, не 96,000

--------------------------------------
Започва Път от моят праг...


Тема Re: Много интересно нещонови [re: Hateras]  
АвторKCV (Нерегистриран)
Публикувано13.08.03 10:09



ako e
r : extended/ single
go niama tozi problem

ako e Real /Double go ima

в хелпа пише за Real че "... its storage format is not native to the Intel processor architecture" нещо е в това проблема
но точното обяснение не го знам....

инак с тези Реални числа човек винаги може да се изпарзаля
там дето не е очаквал

сещам се по този повод че преди 2 години
един прятел който имаше опит в писането
даже беше писал дравери......
та пишеше някаква програма беше на Ц++( това нее от значение)
и беше изпонаписал на сума ти места
нещо от рода на
if r1=r2 ...
if r3=r4....
където r1,r2,r3,r4 са му от някав реален тип
и естествено IFовете несе изпълняваха никога

то е азбучно че реални числа не се сравняват директно
и човека го знаеше но го беше забравил



Тема Re: Много интересно нещонови [re: Lizard]  
Автор NDeu (динозавър)
Публикувано13.08.03 12:24



Както колегите по-горе са отбелязали, проблема идва от дължината на различните представяния - по-специално р-ра на мантисата.
В bits :
Single 23
Double 52
Extended 64
Real 40

Както се казва Нищо изненадващо, но съм учуден

Ако ти се чете





Тема Re: Много интересно нещонови [re: Hateras]  
Автор SDR (TaskMaster)
Публикувано14.08.03 10:41



kogato sa w edin izraz chislata se preobrazuwat kam naj golemiq wazmojen tip - i chak rezultata kam tipa ot lqwo na rawnoto poradi towa ti gubish tochnost pri mnojestweno prirawnqwane... be izobshto real math suxs :)

------------------------------
I got a COMPILER, and I'm not afraid to use it!


Тема Re: Много интересно нещонови [re: Lizard]  
Автор Eмил ()
Публикувано15.08.03 12:23



По прост пример:

var r:real; {или single или double или extended}
...
r:=0.975;
if r=0.975 then ShowMessage('yes') else ShowMessage('no');
...

Само за extended дава 'yes'.За другите разултата е 'no'
Extended типа се записва в 10 байта.
Всички останали в по-малко.
Single - 4 байта.
Double - 8 байта.
Real е еквивалентен на Double по подразбиране,
или в по старите версии на 6 байта.

Да речем, че r е double. Тогава присвояването
"r:= 0.975" ще заеме в паметта 8 байта.
На следващия ред имаме:
if r=0.975 then ...
Какво се сравнява?
Едното е променливата r (8 байта).
Другото което компилатора вижда е
константата 0.975
Какво се прави: 0.975 се представя като
extended (! 10 байта).
Понеже другото е double, то r се разширява
до 10 байта, НО това няма да е еквивалентно
на константата 0.975, защото r е било
с по-малко значащи цифри и се допълва с нули.
За по-голяма яснота нека не е 0.975, а числото пи.
На колко е равно?
P1=3.14 (2 знака точност след запетаята - примерно това е double)
или
P2=3.1415 (4 знака точност след запетаята - примерно това е extended )

Сега дали P1=P2 ?
За да си сравним трябва да ги приведем към един и същи тип
и то по-големия - extended.

P1 става: 3.14 -> 3.1400 (с нули)
P2 понеже си е вече extended то си остава 3.1415

Сега равни ли са 3.1400 и 3.1415 ?
Естествено не.

Може да има възражение: "да ама пи си е с много знаци
след запетаята, а 0.975 е само с 3 знака."
Отговора е: това е вярно само в десетична система,
а вътрешно числата се представат в двоична и
там това число не е с три знака а е безкрайна
периодична дроб и е въпрос на точност след кой
знак ще се отреже. Например 1/3=0.3333333...
не може да се запише с краен брой знаци, но
ако се използва не десетична, а троична
бройна система, то 1/3 се записва точно!


Сега конкретно за примера от постинга:

1 случай) r := r*100; r := round(r); r := r/100;
2 случай) r := round(r*100)/100;

Първо втория. Какво прави компилатора?
1. Вижда r*100. (в скобите)
Реакция:
- r от real става extended
- 100 се записва като extended
- Умножават се. РЕЗУЛТАТА Е EXTENDED
и с него се продължават следващите изчисления!

В пъврия случай ситуацията е различна.
Какво прави компилатора?
1. Вижда r := r*100;
Реакция:
- r от real става extended
- 100 се записва като extended
- Умножават се. резултата е extended както и преди.
- НО имаме r:=резултата, а r паметта е 8 байта
докато резултата е extended. Следствие:
резултата се реже(закръглява) до по-малка
точност и се записва в паметта определена
за променливата r.
Е сега следващите оператори (r := round(r); r := r/100;)
се изпълняват със стойността на r (double) от паметта,
а тя е РАЗЛИЧНА от стойността extended в предишния
случай "r := round(r*100)/100", просто в предишния
случай няма междинно записване в паметта, което
да "реже", а се изпълнява докрай с extended и
накрая се записва. Поради това е възможно
да се получат различни резултати.
Числото 0.975 в случая са подбрано така,
че ако се закръгли до double (D) или extended (E)
то в едното закръгляване D<0.975, а в другия E>0.975
Разликата може да е в 14 знак след запетаята,
но round КОРЕКТНО закръглява в различни посоки
в двата случая. От тук и различните резултати.

Цялата тази история може да се види, ако
се погледне машинния код, който се
генерира (CPU window).

Уф! престарах се. дано е било интересно на някой.



Тема Re: Много интересно нещонови [re: Eмил]  
Автор millennium ()
Публикувано15.08.03 17:21



Е не това наистина много ми хареса
много ценно! :) и полезно

p.s. наистина работата с real числа sux :P) и рябва внимателно да се пипа ...



Тема Сравняване на реални числанови [re: millennium]  
Автор NejDet ()
Публикувано18.08.03 15:02



const epsilon = 0.0000001;

var r1,r2:real;//double, single ....
begin
r1 := ....;
r2 := ....
if abs(r1-r2) < epsilom then ...............
esle ................

end;

Никога не е късно човек да се провали!


Тема Re: Сравняване на реални числанови [re: NejDet]  
Автор Eмил ()
Публикувано18.08.03 16:38



To millennium и SDR
"...real math suxs..."

Не е точно така.
Реалните числа (в математически смисъл) са безкрайно
много. А тяхното изобразяване в паметта на компютъра
е в краен брой байтове следователно набора реални числа
в компютъра е дискретен и представя реалните числа с
КРАЙНА точност. И работата с реални числа трябва да се
знае така както се знаят и други компютърни технологии.
По мое мнение причината в "изненадите" на реалните числа
е, че понастоящем в масовите програми те малко се
използват. Сега програмиста го вълнува повече какъв
компонент да използва за да му е "по-шарена" програмата
или коя нова технология със засукано име. Но работа
с числа с плаваща точка по-рядко се сблъсква. Аз
предполагам, че преди повечко години, компютрите
са се използвали предимно за математически изчисления
(разбира се не, че сега не ги използват и за това)
и начина на работа с реални числа се е струвал съвсем
естествен.
Спомнете си че първия език от високо ниво
(1955 год. ако не ме лъже склерозата) е FORTRAN
т.е. Formula Translation. T.e. "първия" език
е бил замислен за математически изчисления.
Ако се погледне в една по-стара книжка където
се говори за това какви библиотеки има към
дадения език или среда то там се имат предвид
библиотека от функции за математически изчисления.
То и сега в Delphi има един много хубав unit: Math.pas.
Колко хора (като %) го ползват? Или ако смея да бъда
малко язвителен то колко хора знаят, че въобще го има.
Сега ако се спомене думата библиотека то първата
асоциация е лента с наредени компоненти на нея.
Не че това е лошо, много си е хубаво даже.
Лошото е (според мен) че би трябвало един програмист
първо да има добра теоретическа подготовка (широка) и
след това знания за конкретен език среда или технология.
Извинявам се, че май на морал го ударих...


То NejDet
"if abs(r1-r2) < epsilom then ..............."

Да това е така, и този начин се цитира във всички
книжки. Но той не е пълен.

Нека r1 и r2 да означават тегло на предмети.

Нека:
const epsilon = 0.001; {в килограми}
сега:
"if abs(r1-r2) < epsilom then ..............."
означава, че ако на два предмета теглото се различава
с по-малко от 0.001 кг. (1 грам) то ги считаме
че са равни (т.е. тежат еднакво).

Това е ОК ако сравняваме две буци сирене от магазина,
които тежат по два, три колограма. Двете буци тежат
еднакво, ако разликата с под 1 грам. ОК.

Сега нека да сравним теглото на два танкера петрол
Първи:1000000 кг (1000 тона)
Втори:1000001 кг (1000 тона + 1000грама)
(доста точно сме премерили танкерите :)

Сега танкер едно може да мине през шлюза на
панамския канал. Условието е:
други танкери могат да минат само ако са
равни на първия (малко измислено условие ,
но идеята е ясна).
Е равни ли са двата танкера?
Не! разликата е 1000 пъти epsilon.
"if abs(r1-r2) < epsilom then..." не е изпълнено.
Очевидно epsilon не може да го считаме едно и също
за буците сирене и за танкерите. Ами ако мериме маса
на звезди и планети. Слънцето тежи 1.99Е30 кг.
Е ако се различават с 1 МИЛИАРД тона две звезди
то те равни маси ли имат. Това е такава микроскопична
разлика, че не е възможно да се измери.
Поуката е, че реалните числа означават нещо мерено
в реалния свят (дължина, маса, температура и т.н.)
а тези величини се имат грешка при измерването и то
много по-голяма от предоставянята точност от компютъра.
Ако програмата работи да речем с разстояния между
градове (географска програма :)
Разстоянието между градовете А и Х е 100 км
а между А и Y e 100,001 км (100 км + 1 метър)
Е това смислено ли е? Кой дава разтояния между градове
с точност 1 метър? Очевидно при сравняване на разстояния
в този случай епсилон е 1 км. И 500 метра разлика между
две дистанции да се счита за нула.
А в програмата някаква формула е изчислила двете
разстояния така
100.00000001 и
100.0000000099 км.
Е и сега работа на програмиста е да каже равни ли са те
или не, а не да казва "real math suxs"

Така че ако се сравняват две реални числа за равенство
то алгоритъма предложен от NejDet следва да се разшири
така:

1. С каква точност работим?
Примерно 1% (везни на пазара) то епсилон=0.01
Примерно най-съвършенните везни във физическа
лаборатория 0.0001% то епсилон=0.000001
(забележете дори 1 милионна е много повече от
точността която предлагат реалните числа
в компютъра около 17-18 знака)

2. Второ от сравняваните числа r1 и r2, кое е по-голямо?
(Можем да сравняваме теглото на два слона или на слон и муха).
М1:=Max(r1,r2)
M2:=Min(r1,r2)

И сега сравняване на М1 и М2, но като процент от по-голямото.

if abs(М1-М2) < epsilom*М1 then ....

Ако епсилон=0.01 (една стотна) то
сравнявайки слонове теглата са равни, ако разликата
е по-малка от една стотна от теглото на слона (да речем 20 кг)

Сравнявайки мухи теглата са равни ако разликата
е по-малка пак от една стотна, но от теглото на
мухата (да речем 2 милиграма).


Пак се отплеснах.
Може би защото ме мързи да работя :)



Тема Re: Сравняване на реални числанови [re: Eмил]  
Автор NejDet ()
Публикувано19.08.03 08:51



Напълно си прав Емил.

Наистина в математиката с epsilon означават пребрежимо малки числа, които се избират в зависимост от контекста на задачата.

Няма смисъл от сравняването на слонове и мухи нали!? (по тегло)

Никога не е късно човек да се провали!



Страници по тази тема: 1 | 2 | >> (покажи всички)
*Кратък преглед
Клуб :  


Clubs.dir.bg е форум за дискусии. Dir.bg не носи отговорност за съдържанието и достоверността на публикуваните в дискусиите материали.

Никаква част от съдържанието на тази страница не може да бъде репродуцирана, записвана или предавана под каквато и да е форма или по какъвто и да е повод без писменото съгласие на Dir.bg
За Забележки, коментари и предложения ползвайте формата за Обратна връзка | Мобилна версия | Потребителско споразумение
© 2006-2024 Dir.bg Всички права запазени.