Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2002.03.04;
Скачать: [xml.tar.bz2];

Вниз

Single   Найти похожие ветки 

 
Fast   (2002-02-15 18:40) [0]

Для эконими памяти и места в файле куда надо сохранять данные вместо типа Real я использовал Single.
Наткнулся на пародокс

r:real;
s:single;
begin
r:=StrToFloat(edit1.text);
s:=r;
if s=r then ShowMessage("Это никогда не сработает");
end;


Тоесть если я ввожу r=0.3 то s=0.30000001192 - откуда берутся лишние знаки?
и почему Single в результате всегда болше Real.


 
Иван Шихалев   (2002-02-15 18:44) [1]

А можно привести и Single и Real? А то "нас сомненья гнетут". Хотя в погрешности округления ничего удивительного нет.


 
Fast   (2002-02-15 18:50) [2]

Предлогаешь сделать так?

begin
r:=StrToFloat(edit1.text);
s:=StrToFloat(edit1.text);
if s=r then ShowMessage("Это никогда не сработает");
end;


Результат тот-же.


 
Иван Шихалев   (2002-02-15 18:54) [3]

Да нет. :0

Сомненья, честно говоря, насчет всегда.

А причина вообще-то проста: не может 0.3 с одной точностью быть равно 0.3 с другой точностью в двоичной системе счисления. Вот и все.


 
Fast   (2002-02-15 18:56) [4]

Мне бы черт с ним с Real....
Просто почему StrToFloat() в Single переводит с погрешностю?
а вот в Real нет.
если кто не до конца понял то бюсь я над тем как из string Line:="0,3" получить s=0,3 a не s=0.30000001192.


 
Иван Шихалев   (2002-02-15 19:03) [5]

И в Single, и в Real с погрешностью... Ну не влазит точное двоичное представление 0.3 в любое конечное число бит.


 
Fast   (2002-02-15 19:12) [6]

Не веришь?
Проверь.
Вот тебе тестовый код (надо два Listbox"a, батон и edit).

procedure TForm1.Button1Click(Sender: TObject);
var
i:integer;
r:real;
s:single;
begin
r:=StrToFloat(edit1.text);
s:=StrToFloat(edit1.text);
ListBox1.Items.Add(FloatToStr(s));
ListBox2.Items.Add(FloatToStr(r));
if s=r then ShowMessage("Это никогда не сработает");
end;

Я предпологаю что Delphi округляет Real но чем ей плох Single
(это уже не четыре байта разницы это ворос)



 
Фэ   (2002-02-15 21:09) [7]

Для корректного сравнения Real типов (Single, Double(Real), Extended,..) как правило вводят константу E равную желаемой точности сравнения.

Вот пример

function IsEqualDouble_(f1, f2, E: extended): boolean;
begin
Result := (abs(f1-f2) < E);
end;

Либо сравнивают до N-го дес.разряда


 
Юрий Зотов (M)   (2002-02-15 21:10) [8]

> Fast

Пусть мы делим 1000 на 999. Результат есть бесконечная дробь, которая не может уместиться в любое конечное число десятичных разрядов. Давайте посмотрим, какое строковое представление результата мы получим, задавая для него разную длину (то есть, отводя под него разное число разрядов):

3 цифры - 1.00
5 цифр - 1.0010
7 цифр - 1.001001

Почему так? Ведь число-то всегда одно и то же, а его изображения разные. Очевидно, все дело в том, какую длину разрядной сетки мы отводим под это число - то есть, где мы его "обрезаем".

То же самое происходит и у Вас. В памяти числа хранятся в двоичной системе счисления, а в ней 0.3 - это бесконечная дробь. Значит, поскольку Real, Single, Double и Extended имеют разное количество двоичных разрядов, одно и то же десятичное число 0.3 фактически будет РАЗНЫМ двоичным числом для каждого из этих типов. Что Вы и наблюдаете.

Прочитайте на "Королевстве" статью Антона Григорьева "Неочевидные особенности вещественных чисел" - многие вопросы исчезнут.




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

Форум: "Основная";
Текущий архив: 2002.03.04;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.46 MB
Время: 0.005 c
4-9325
Алекс
2002-01-04 09:38
2002.03.04
Помогите с SetWindowLong


1-9236
Alex L.
2002-02-15 17:39
2002.03.04
Объединение компонентов


3-9076
Demon ltd
2002-02-06 23:58
2002.03.04
Показ в данных выборочно из таблицы


3-9065
fag2000@ok.ru
2002-02-06 15:18
2002.03.04
как узнать что запись новая


1-9201
kingdom
2002-02-14 16:44
2002.03.04
Как сделать мигание формы в свернутом виде?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский