|
Тема |
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 милиграма).
Пак се отплеснах.
Може би защото ме мързи да работя :)
|
| |
|
|
|