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

Вниз

Принтер "портит" выполнение программы?   Найти похожие ветки 

 
Abcdef123   (2010-12-22 06:31) [0]

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


 
brother ©   (2010-12-22 07:40) [1]

Тут не принтер виноват...

> Если проигнорировать ошибку и попробовать запустить то же
> самое (не перезагружая проект), то второй раз выполняется
> номально.

наводит на мысль, что прога что-то не верно прощитывает... а потом (возможно второй проход просчета) все ок...


 
brother ©   (2010-12-22 07:42) [2]

можно ли попробовать со старым принтером опять? или любыми другими?


 
Abcdef123   (2010-12-22 07:49) [3]

To [2][ так в том то и дело, что они меняли принтеры для всяких комбинаций экспериментов. Со старым работает четко ВСЕГДА, как часы, даже сейчас.А как только меняют на новый - такая вот проблема. Как только снова меняют на старый - опять хорошо проходит. Поэтому и наталкивает на мысль что в принтере проблема. Иначе по логике прога всегда бы сбоила.


 
Ega23 ©   (2010-12-22 08:04) [4]


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


Не думаю. Скорее, данная ошибка существует всегда, вот только явно проявляется с новым принтером.
Логи спасут мир.


 
Abcdef123   (2010-12-22 08:27) [5]

To [4]. Извините за примитивный вопрос - что такое логи? Я посмотрела в инете - типа как трассировка. Я обычно трассировку делаю - в коде, где ошибка - я добавляю мессаджи со сплошной нумеровкой (если надо то со значеними переменных, какие вызывают подозрения на ошибку). И таким образом нахожу строку, на которой споткнулась программа. Такой подход сойдет на лог? Или логи - это что то более точное??


 
Ega23 ©   (2010-12-22 08:42) [6]


>  Такой подход сойдет на лог?

В целом - да. Хотя, на пой взгляд, это более утомительно.


 
MonoLife ©   (2010-12-22 08:51) [7]


>Abcdef123   (22.12.10 06:31)
> поскольку интересное значение этой переменной получается:
>  –922337203685477.5808

инициализировать переменную перед этим не пробовали?


 
Abcdef123   (2010-12-22 09:13) [8]

To [7] Пробовала, присвоила значение ноль. Не помогло :-(


 
brother ©   (2010-12-22 09:17) [9]

так исходники доступны? показываем тогда...


 
Abcdef123   (2010-12-22 09:23) [10]

сразу оговорюсь, чтоб помидорами не забросали, прога ну очень старая, не моя. Я просто сопровождаю пакет.
Вот отрывок из кода, где сбоит:
procedure proc1;
 var
   rlBase, rlMulti, rlBaseDM, rlMultiDM, rlAmount : Currency;
begin
 {Здесь некотовый код, определены значения переменных rlBase, rlMulti, rlBaseDM, rlMultiDM. Кстати, значение  rlBaseDM, rlMultiDM порой бывают равны нулю}
 rlAmount := CalcProportionAsAmount(rlMulti, tblDetail.FieldByNamе("INV_AMT").AsFloat,  rlBase) -
                     CalcProportionAsAmount(rlMultiDM, tblDetail.FieldByName("INV_MEMO").AsFloat, rlBaseDM);
{вот тут значение rlAmount большое (неправильное), которое на следующей строке вызывает ошибку, когда пытаемся присвоить это значение в поле таблицы.}
tblHeader. FieldByName("TOTAL").AsFloat  := FieldByName("TOTAL").AsFloat - rlAmount; //на этой строке выскакивает ошибка
end;

function CalcProportionAsAmount(rlTotal, rlSubTotal, rlAmount : Currency) : Currency;
var
 rlPercent : Real;
begin
 try
   rlPercent := (rlSubTotal / rlTotal);
 except
   rlPercent := 0;
 end;
 CalcProportionAsAmount := rlAmount * rlPercent;
end;


 
MonoLife ©   (2010-12-22 09:42) [11]

А ничего, что тип rlPercent = Real, а rlAmount (в функции) - Currency?


 
Abcdef123   (2010-12-22 09:51) [12]

To [11]: Это вопрос или такой стиль утверждения, что тут и ошибка? Честно говоря, я не думала, что оперировать с карренси и реал может вызвать ошибку. Я полагала, что эти типа совместимы в математических операциях.


 
Ega23 ©   (2010-12-22 09:54) [13]


> Я полагала, что эти типа совместимы в математических операциях.

Совместимы, да не совсем.


 
Abcdef123   (2010-12-22 10:02) [14]

To [13] То есть это и создает проблему? То есть вы уверены, что замена типа 100% исправит ситуацию? Просто поскольку пробоема не у нас,а на стороне (у клиента) сами понимаете, хотелось бы уже ограничить количество выездов для эксперимента. Поэтому, если это как одна из возможных идей, может еще есть предположения в ошибке?
Хорошо, я поменяю тип rlPercent на сарренси. Но, не могли бы вы пояснить, почему так нелогично работает? То есть при первом заходе сбоит, а при втором нормально. Это ж одна и та же процедура выполняется. А со старым принтером вообще нормально. Вот это никак в логику не укладывается.


 
MonoLife ©   (2010-12-22 10:16) [15]


> То есть вы уверены, что замена типа 100% исправит ситуацию?

нет.

к слову, из справки (D7):
When mixed with other real types in assignments and expressions, Currency values are automatically divided or multiplied by 10000.


 
Ega23 ©   (2010-12-22 10:28) [16]


>  То есть вы уверены, что замена типа 100% исправит ситуацию?

Я ни в чём не уверен. Даже в своей будущей половой ориентации.
Но практика показывает, что чем меньше "тёмных" мест и небезопасного кода - тем проще детектируются ошибки (а в идеале - вообще не возникают).


 
brother ©   (2010-12-22 10:31) [17]

function CalcProportionAsAmount(rlTotal, rlSubTotal, rlAmount : Currency) : Currency;
begin
try
  result:= rlAmount * (rlSubTotal / rlTotal); // поставить тут бряк и посмотреть какие значения...
except
  result:= 0;
end;
end


 
Abcdef123   (2010-12-22 10:37) [18]

To [17]: Хорошо, попробую! Спасибо! Но, наверно, сегодня не получится проверить у клиента на месте. Так что сообщу о резульататах позже. А пока, спасибо всем! Если есть еще предложения, чтоб уж заодно все проверить - милости просим. :-)


 
han_malign   (2010-12-22 11:23) [19]

- попробуй вот это заклинание:
 asm FINIT end;
 rlAmount := CalcProportionAsAmount(...)
а потом вот здесь
function CalcProportionAsAmount(rlTotal, rlSubTotal, rlAmount : Currency) : Currency;
begin
  asm FINIT end;
try
  result:= rlAmount * (rlSubTotal / rlTotal);
except
  result:= 0;
end;
end

- не раз и не два, встречал случаи когда что-то-где-то выводило из себя сопроцессор...


 
turbouser ©   (2010-12-22 12:33) [20]

Если уж Currency - так надо везде Currency.
И FieldByName(xxx).AsCurrency и rlPercent : Currency;


 
Anatoly Podgoretsky ©   (2010-12-22 13:40) [21]

> Abcdef123  (22.12.2010 09:13:08)  [8]

Не помогло, что?


 
Abcdef123   (2010-12-23 04:43) [22]

To [21] мне посоветовали "инициализировать переменную перед этим не пробовали?". И я ответила, что пробовала инициализировать, но проблема всё та же.
To [20] простите, может вопрос примитивный, но я правда не знаю, что это вы предлагаете "asm FINIT end;" Что это?


 
brother ©   (2010-12-23 05:21) [23]

> "asm FINIT end;" Что это?

http://forum.shelek.ru/index.php/topic,8892.0.html
1. finit сбрасывает состояние FPU в дефолтовое и, как следствие, переписывает регистр управления.


 
Abcdef123   (2010-12-23 05:49) [24]

To [23] большое спасибо за ответ!!! Поскольку этого не знала, то еще небольшой вопросик - это сбрасывание в дефолтовое состояние распространяется только на процесс работы моего проекта (если я вставлю этот код), или даже после окончания работы с моей программой это дефорлтовое состояние остается? Если остается, то я боюсь, а вдруг это сбрасывание повредит работу других приложений у клиента? (опять же извиняюсь за возможно глупый вопрос)


 
brother ©   (2010-12-23 05:55) [25]

код из [17] или [19] опробован?


 
Abcdef123   (2010-12-23 06:30) [26]

To [25] нет еще, к сожалению. И похоже до нового года поездка к клиентам на это тестирование не состоится. :-(
А насчет проверки [19]  я задала вопрос [24], потому что если вдруг после такой проверки какое то другое приложение у клиента вдруг будет глючить, то мне бошку оторвут за такие эксперименты.


 
brother ©   (2010-12-23 06:54) [27]

тогда, я "умываю руки" ...


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

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


 
12 ©   (2010-12-23 10:17) [29]

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

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


 
12 ©   (2010-12-23 10:20) [30]

кстати

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

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

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


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


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

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

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


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

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


 
Ega23 ©   (2010-12-23 10:54) [33]


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


Divizion By Zero
Range Check Error


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


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

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


 
12 ©   (2010-12-23 11:10) [35]


> Range Check Error

> currency(1E13)/0.0001

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

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


 
Ega23 ©   (2010-12-23 11:12) [36]


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


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


 
brother ©   (2010-12-23 11:12) [37]

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

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


 
12 ©   (2010-12-23 11:19) [38]

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

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);


 
12 ©   (2010-12-23 11:21) [39]

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


 
han_malign   (2010-12-23 12:35) [40]


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

- с currency - просто(&#949;=0.0001)

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

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



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

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

Наверх




Память: 0.55 MB
Время: 0.004 c
2-1295432083
Scott Storch
2011-01-19 13:14
2011.04.24
упростить алгоритм TStrings.SetDelimiterText


6-1191246733
__Unnamed__
2007-10-01 17:52
2011.04.24
Вопрос про сокеты, а точнее про FD_CLOSE и FD_READ


2-1295537929
Айнур
2011-01-20 18:38
2011.04.24
Вопрос по Edit


15-1294598101
from_california
2011-01-09 21:35
2011.04.24
заполнение таблиц в ms sql server management studio


15-1294522195
Юрий
2011-01-09 00:29
2011.04.24
С днем рождения ! 9 января 2011 воскресенье





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский