Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Принтер "портит" выполнение программы? [D2005, XP]


Страницы:   1 2 3

Abcdef123 ©   (2010-12-22 06:31:00) 

Здравствуйте, Мастера. Заранее извиняюсь, если мой вопрос послан не по теме данного форума.
Столкнулась с такой проблемой. Программа очень давняя, работала нормально, проблема возникла только у клиента сейчас, когда они купили новый принтер (HP). В одном месте программы дает ошибку Number out of range. Если проигнорировать ошибку и попробовать запустить то же самое (не перезагружая проект), то второй раз выполняется номально. Со старым принтером вообще нормально работает!!!
Вот сейчас детали:трассировка ошибки показала место, где получается "большое" число. В процедуре объявлена переменная типа Currency и ей присваивается некое значение, вычисляемое по формуле, на основе данных таблицы. Так вот, первый раз похоже значение это не вычисляется (это я так полагаю), поскольку интересное значение этой переменной получается: –922337203685477.5808 (то есть минимальное значение, которое может иметь этот тип). Знаний насчет драйвера принтера у меня недостаточно. Вот и думаю, возможно ли, что драйвер принтера каким то образом "портить" программу? И если да, то каким образом второй раз ошибки нет, присваивается нужное рассчитанное значение этой переменной. Пожалуй, на этом описание закончу, если что-то нужно подробнее сообшить - спросите. Возможно, что кто-то встречался с подобной проблемой. Может я вообще не там ищу причину? Буду рада любому дельному совету. Заранее спасибо!


12   (2011-01-18 16:21:00) [1]

еще раз тему перечитал - тогда так: Компьютер портит.
Без компьютера же программа не лажает?!
Вот.. :)
А чтоб программа не лажала - ее надо отлаживать (с)


12   (2011-01-18 15:51:00) [2]

да-да


var
 R:Single;
begin
 R:=0.1;
 if R=0.1 then
  Label1.Caption:='Равно' else
  Label1.Caption:='Не равно'
end;
При нажатии кнопки мы увидим надпись «Не равно». На первый взгляд это кажется абсурдом.
(с) Антон Григорьев


из этой же серии, имхо


Amoeba_   (2011-01-18 11:47:00) [3]


> Григорьев Антон, "Невероятные особенности вещественных чисел"
> , как-то так, гуглите, короче

Неочевидные особенности вещественных чисел
http://www.delphikingdom.com/asp/viewitem.asp?catalogid=374


12   (2011-01-18 09:48:00) [4]


> когда
> в функции идет деление на ноль, то программа не идет на
> except, а присваивает результату вот такое больше разрядное
> значение.

Вероятно, там не 0, а несколько больше(меньше).

function CalcProportionAsAmount(rlTotal, rlSubTotal, rlAmount : Currency) : Currency;
const
 Eps = 0.0001;
begin
try
if (rlTotal >  Eps) then  
  result:= rlAmount * (rlSubTotal / rlTotal)
else
  result:= 0;
except
result:= 0;
end;

end;

Григорьев Антон, "Невероятные особенности вещественных чисел" , как-то так, гуглите, короче


Abcdef123   (2011-01-18 08:50:00) [5]

Здравствуйте, Мастера.
Докладываю - наконец-то у клиента всё протестировали, но, ничего не помогло. Проблема существует.
А вот, что произошло на моем компе! Как я писала, что у меня на компе программа работает нормально.
Но, как только я протестировала идею [19], у меня вылетает такая же ошибка! Хотя предложение использовать asm FINIT end; должно бы наоборот - помочь!
Я прошла пошагово, и нашла, что когда
в функции идет деление на ноль, то программа не идет на except, а присваивает результату вот такое больше разрядное значение.
Если я добавлю перед применением формулы проверку на ноль, то ошибки нет.
В общем, чтобы уж точно было понятно привожу описываемые варинты: работаютщие:
function CalcProportionAsAmount(rlTotal, rlSubTotal, rlAmount : Currency) : Currency;
begin
try
 result:= rlAmount * (rlSubTotal / rlTotal);
except
 result:= 0;
end;
end

function CalcProportionAsAmount(rlTotal, rlSubTotal, rlAmount : Currency) : Currency;
begin
 asm FINIT end;
try
 if rlTotal <> 0 then  
   result:= rlAmount * (rlSubTotal / rlTotal)
 else
   result:= 0;
except
 result:= 0;
end;
end
А ЭТО НЕРАБОТАЮЩИЙ:
function CalcProportionAsAmount(rlTotal, rlSubTotal, rlAmount : Currency) : Currency;
begin
 asm FINIT end;
try
 result:= rlAmount * (rlSubTotal / rlTotal);
except
 result:= 0;
end;
end

На моем компе я проверяю с моим принтером. То есть всё также  много вопросов - всё те же.
Прошу прокомментировать.


Ega23   (2010-12-24 06:20:00) [6]


>  вы за использование использование проверки на нуль или
> за использование except?


Дурная постановка вопроса.


Abcdef123   (2010-12-24 05:54:00) [7]

To [40]: Красиво написано, но не поняла, вы за использование использование проверки на нуль или за использование except?


han_malign   (2010-12-23 12:35:00) [8]


> Не всё так просто

- с currency - просто(ε=0.0001)

>> А деление проверяется на зеро заранее.
> ты не погорячился?

- подразумевался пост 12 © (23.12.10 10:20) [30], и тут надо исходить из вероятности возникновения ситуации...
Если это исключительная, крайне редкая ситуация - то лишнее ветвление(не убирающее необходимости защищенной секции) - избыточно.
Но учитывая:
> {Здесь некотовый код, определены значения переменных rlBase,  rlMulti, rlBaseDM, rlMultiDM. Кстати, значение  rlBaseDM,  rlMultiDM порой бывают равны нулю}
- ситуация вполне нормальная, и ветвление обосновано, т.к. нормальные входные данные не должны порождать исключение(которое дает значительное пенальти производительности)...


12   (2010-12-23 11:21:00) [9]

Raise; - ну тут варианты..


12   (2010-12-23 11:19:00) [10]

вообщем, я б так написал

function TryCalcProportionAsAmount(const rlTotal, rlSubTotal, rlAmount : Currency; var MyResult: Currency) : Boolean;
begin
Result := true;
try
 if rlTotal <> 0 then
   MyResult := rlAmount * (rlSubTotal / rlTotal) else
   MyResult := 0;
except
 result:= false;
 Raise;
end;
end;

....
if TryCalcProportionAsAmount(блаблабла, Variable) then
 Do(Variable);


Ega23   (2010-12-23 11:12:00) [11]


> А деление проверяется на зеро заранее.


Не всё так просто


brother   (2010-12-23 11:12:00) [12]

> А деление проверяется на зеро заранее.

ты не погорячился?
try там вполне подходит...


12   (2010-12-23 11:10:00) [13]


> Range Check Error

> currency(1E13)/0.0001

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

А деление проверяется на зеро заранее.


han_malign   (2010-12-23 11:01:00) [14]


> ну так и писать надо
> if rlTotal <> 0 then ...
> else Result := 0;

- а вот тут ты не совсем прав - currency(1E13)/0.0001, хотя это конечно экстремальный случай...


Ega23   (2010-12-23 10:54:00) [15]


> а какой тут Except?
> кроме /0


Divizion By Zero
Range Check Error


Abcdef123   (2010-12-23 10:52:00) [16]

To [31]: Огромное спасибо за ответ. Мне это было важно знать! Теперь спокойно не боясь за последствия могу это использовать!


han_malign   (2010-12-23 10:40:00) [17]


> Если остается, то я боюсь, а вдруг это сбрасывание повредит работу других приложений у клиента?

- нет, состояние процессора/сопроцессора изменяется только в контексте текущего процесса/потока(при переключении между потоками состояние регистров сохраняется и соответственно восстанавливается).

Но некоторые нехорошие драйвера и/или сторонние библиотеки, к которым ваше приложение явно или неявно(например они могут цеплять system-wide hook-и, а сейчас еще каждая собака балуется rootkit-ами(из лучших побуждений конечно)) обращается - могут запарывать состояние регистров именно в контексте вашего процесса...


12   (2010-12-23 10:20:00) [18]

кстати

try
  rlPercent := (rlSubTotal / rlTotal);
except
  rlPercent := 0;
end;

а какой тут Except?
кроме /0

ну так и писать надо
if rlTotal <> 0 then ...
else Result := 0;


12   (2010-12-23 10:17:00) [19]

Поставить левый принтер. из стандартных, назначить печать в файл, напечатать.
Ошибка повторилась?

showmessage все параметры в CalcProportionAsAmount(rlTotal, rlSubTotal, rlAmount
или числитель большой или знаменатель маленький


Abcdef123   (2010-12-23 07:54:00) [20]

To [27]. Почему? А что на [24] вопрос никто не знает ответа?


Страницы:   1 2 3

Наверх

Титульная страница Поиск, карта сайта Написать письмо