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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Переполнение разрядной сетки, консольное приложение 
:(
    Опции темы
varra
Дата 9.10.2003, 14:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 67
Регистрация: 27.3.2003
Где: Новосибирск

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



Код

var
T,S,s1: real;

...

while T < S do
 begin
     T := T + s1;
     s1 := s1/2;
end;


пусть T=0, S=10, s1 = 4

как определить,когда s1 выйдет за пределы разрядной сетки?
PM MAIL   Вверх
x77
Дата 9.10.2003, 15:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



tmp := s1;
s1 := s1/2;
if tmp = s1 then
...


--------------------
Я никогда не сопротивлялся искушению, поскольку узнал: что мне
не нравится, то меня не искушает.
© Джордж Бернард Шоу (Ирландия)
PM MAIL ICQ   Вверх
p0s0l
Дата 9.10.2003, 16:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Г-н Посол
****


Профиль
Группа: Экс. модератор
Сообщений: 3668
Регистрация: 13.7.2003
Где: 58°38' с.ш. 4 9°41' в.д.

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



А можно так:
Код
 while T < S do
 begin
   T := T + s1;
   s1 := s1/2;
   if s1 = 0 then break;
 end;

При ПРС в меньшую сторону число становится равным нулю...



--------------------
С уважением, г-н Посол.
PM   Вверх
Dmitry V.Abramov
Дата 9.10.2003, 19:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 177
Регистрация: 30.9.2003
Где: Saint-Petersburg

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



Цитата(p0s0l @ 9.10.2003, 16:41)
А можно так:
Код
 while T < S do
 begin
   T := T + s1;
   s1 := s1/2;
   if s1 = 0 then break;
 end;

При ПРС в меньшую сторону число становится равным нулю...

А НЕправильнее так: (пример оставлен, дабы было стыдно за свой старческий маразм)
Код
const
 NaN = 0/0; // :)
 Inf = 1/0; // :)))
...
 if s1 = NaN then ...; // уй, как мало...
 if s1 = Inf then ...; // ой, как много...


Это не прикол. Это корректная работа с экстремальными числами в FPU.

Это сообщение отредактировал(а) Dmitry V.Abramov - 9.10.2003, 22:54
--------------------
/DVA
PM MAIL WWW   Вверх
x77
Дата 9.10.2003, 19:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



круто smile.gif

только все равно непонятно, чем 0/0 корректнее 0 с точки зрения компилятора smile.gif


--------------------
Я никогда не сопротивлялся искушению, поскольку узнал: что мне
не нравится, то меня не искушает.
© Джордж Бернард Шоу (Ирландия)
PM MAIL ICQ   Вверх
Dmitry V.Abramov
Дата 9.10.2003, 19:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 177
Регистрация: 30.9.2003
Где: Saint-Petersburg

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



Цитата(x77 @ 9.10.2003, 19:13)
круто smile.gif

только все равно непонятно, чем 0/0 корректнее 0 с точки зрения компилятора smile.gif

1. 0/0 > 0 чушь. thanx to p0s0l
2. позволяет отлавливать переполнение сетки. чушь. не для того оно.
3. 0/1 = 0. В то время, как NaN/1 инициализирует raise EUnderFlow
4. FPU знает про NaN.
5. Что-то есть еще, но никак не припомнить...

============
Спасибо p0s0l за своевременные указания на старческий склероз.

Это сообщение отредактировал(а) Dmitry V.Abramov - 9.10.2003, 22:51
--------------------
/DVA
PM MAIL WWW   Вверх
p0s0l
Дата 9.10.2003, 21:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Г-н Посол
****


Профиль
Группа: Экс. модератор
Сообщений: 3668
Регистрация: 13.7.2003
Где: 58°38' с.ш. 4 9°41' в.д.

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



Dmitry V.Abramov, к сожалению, вы ошибаетесь (частично).
Я согласен, что с числами в форме с ПЗ надо работать аккуратно.
Но NaN это не то, что вы думаете.
NaN - это не число! И это близко не 0!
При переполнении ПРС в меньшую сторону получается 0, а не NaN, как вы думаете !!!
А при переполении в большую сторону получается Infinity или NegInfinity !
NaN + 5 = NaN
NaN * 2 = NaN
и т.д.
NaN не должно участвовать в операциях сравнения.

И если в том цикле while сделать проверку:
if s1 = NaN then Break;
то Break сработает при первом же проходе, т.к. NaN равен ЛЮБОМУ другому числу, в том числе и бесконечности!
Так что придется оставить мой вариант...


Это сообщение отредактировал(а) p0s0l - 9.10.2003, 22:01


--------------------
С уважением, г-н Посол.
PM   Вверх
Dmitry V.Abramov
Дата 9.10.2003, 22:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 177
Регистрация: 30.9.2003
Где: Saint-Petersburg

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



Цитата
Dmitry V.Abramov, к сожалению, вы ошибаетесь (частично).

Виноват. Чушь спорол. Вспомнил давние розыски нестабильной ошибки при работе с fpu... и спорол.

Более того, NaN в Delphi лучше вообще не трогать - Exception гарантирован.
Цитата
Так что придется оставить мой вариант...

Обязательно. Спасибо за бдительность!
--------------------
/DVA
PM MAIL WWW   Вверх
varra
Дата 10.10.2003, 05:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 67
Регистрация: 27.3.2003
Где: Новосибирск

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



p0s0l, сэнкс smile.gif

а ведь еще до переполнения возникает ситуация, когда s1 становится настолько малым, что перестает влиять на сумму T... при S=10, s1 = 4 у меня это срабатывает на 39 шаге (переполнение - где-то на 1077), если отслеживать T в окне отладки (становится = 8,причем без какой-либо дробной части...). однако программно получаю 54й шаг :
Код


var
T,S,s1: real;
i,i_small:integer;
tmp:real;
flag:boolean=true;
...
 i := 0;//обнуляем счетчик
 i _small :=0;
 T := 0;
 tmp := 0;
 while T < S do
 begin
     T := T + s1;
     // T перестает увеличиваться:
     if (T = tmp) and flag then
     begin
       i_small := i;//запоминаем шаг
       flag := false;
     end;

     i := i+1;
     tmp := tmp + s1;
     s1 := s1/2;
     
     //ПРС:
     if s1=0 then
     begin
       writeln;
       writeln('i_small = ',i_small,' Sd = ',Sd);
       writeln;
       writeln('Perepolnenie razryadnoi setki na ',i,' shage');
     end;


Это сообщение отредактировал(а) varra - 10.10.2003, 05:47
PM MAIL   Вверх
p0s0l
Дата 10.10.2003, 11:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Г-н Посол
****


Профиль
Группа: Экс. модератор
Сообщений: 3668
Регистрация: 13.7.2003
Где: 58°38' с.ш. 4 9°41' в.д.

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



Dmitry V.Abramov, не стоит так уж сильно переживать! Любой может ошибиться, для того и форум, чтобы можно было не боясь высказывать своё мнение. Если что, дак другие подправят.
Так что всё нормально!

Насчет NaN (NaN = Not a Number):
Infinity/Infinity=NAN
Infinity-Infinity=NAN
Любые операции с NAN = NAN
Кстати, есть +NAN и -NAN...

varra, а с этим уже ничего не поделаешь. Если буди использовать другой тип, Double или Extended - они оттянут этот момент...
На мантиссу в Single(=Real) отводится 52 бита. Поэтому, при сложении 8 и 2^-52 результат никак не влезет в мантиссу, (т.к. между старшей единицей и младшей должно быть около 54 нулей), поэтому отбрасывается младшая часть результата...



--------------------
С уважением, г-н Посол.
PM   Вверх
Unregistered
Дата 10.10.2003, 15:14 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











меня теперь интересует, почему прога выдает i_small = 54, в то время как я при отладке вижу в Watch, что сумма Т перестает увеличиваться на 39(!) шаге...
  Вверх
p0s0l
Дата 10.10.2003, 15:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Г-н Посол
****


Профиль
Группа: Экс. модератор
Сообщений: 3668
Регистрация: 13.7.2003
Где: 58°38' с.ш. 4 9°41' в.д.

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



Потому что тебе показывают округленно (Default).
Чтобы показывалось что есть на самом деле, щелкни на Ватче, который показывает значение T, и выбери тип отображения Floating Point...



--------------------
С уважением, г-н Посол.
PM   Вверх
varra
Дата 10.10.2003, 17:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 67
Регистрация: 27.3.2003
Где: Новосибирск

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



спасибо тебе, p0s0l
а задачка была про чертей, усаживающихся на игле smile.gif)
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

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

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

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

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


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

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


 




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


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

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