Автор | Сообщение |
|
| |
Пост N: 166
Зарегистрирован: 12.11.06
|
|
Отправлено: 07.11.10 10:24. Заголовок: Волшебные числа и операции
Доброе утро! Вот наткнулся на очередную ошибку xHarbour и Clipper. Думал, что глюк ОС или ПК, но нет. Пример ошибки - оператор "остаток от деления": 8.8 * 3 = 26.4 или 3.3 * 3 = 9.9, но операции (%) дают 26.4%8.8 = 8.8 или (НО правильно) 9.9%3.3 = 0 Вопрос - как Вы обходите данные глюки? Или где в "арифметике" ожидать очередных "засад"? До кучи напомню об ошибочной работе функции Int в Clipper (в xHarbour кажется работает правильно)
| |
|
Ответов - 150
, стр:
1
2
3
4
5
6
7
8
All
[только новые]
|
|
|
| постоянный участник
|
Пост N: 991
Зарегистрирован: 09.10.06
|
|
Отправлено: 07.11.10 13:10. Заголовок: AndreyZh пишет: Вот..
AndreyZh пишет: цитата: | Вот наткнулся на очередную ошибку xHarbour и Clipper. Думал, что глюк ОС или ПК, но нет. |
| #include <stdio.h> #include <math.h> int main( void ) { double d1 = fmod( 9.9, 3.3 ); double d2 = fmod( 26.4, 8.8 ); printf( "9.9%%3.3=%f, 26.4%%8.8=%f\n", d1, d2 ); return 0; } Протестируйте с любым доступным вам С компилятором. У меня PellesC 6.5 "отличился", вывел 9.9%3.3=3.300000, 26.4%8.8=8.800000 все остальные (ms vc 15; bcc 5.5, 5.82, 6.3; mingw 3.5, 4.5.1 ) > 9.9%3.3=0.000000, 26.4%8.8=8.800000 AndreyZh пишет: цитата: | Или где в "арифметике" ожидать очередных "засад"? |
| Вот на таком коде упадет BCC proc main() local i, n n := 1 for i:=1 to 100000 n*=2 next ? n return
| |
|
|
| |
Пост N: 167
Зарегистрирован: 12.11.06
|
|
Отправлено: 07.11.10 13:40. Заголовок: Петр - спасибо! Хотя..
Петр - спасибо! Хотя и не успокоили... Запустил поиск и уменя в программе операция (%) более 1000 раз, ну алгоритмы такие размножал... Как можно попытаться порешать эти проблемки? По проверке на других компиляторах - мне доступны и проверил на C#/VFP5 ошибок не получил! А пример кода "роняющего" программу сейчас проверю - очень интересно!
| |
|
|
| |
Пост N: 168
Зарегистрирован: 12.11.06
|
|
Отправлено: 07.11.10 13:56. Заголовок: Действительно роняет..
Действительно роняет! Но мне проще - мои финансовые программы не работают с такими размерностями
| |
|
|
| постоянный участник
|
Пост N: 994
Зарегистрирован: 09.10.06
|
|
Отправлено: 07.11.10 23:02. Заголовок: AndreyZh пишет: опе..
AndreyZh пишет: цитата: | операция (%) более 1000 раз, ну алгоритмы такие размножал... Как можно попытаться порешать эти проблемки? По проверке на других компиляторах - мне доступны и проверил на C#/VFP5 ошибок не получил! |
| Перестаньте вы называть эту особенность ошибкой. Операция взятия остатка в различных языках программирования реализованы по разному. И поэтому некорректно сравнивать результаты Clipper ([x]Harbour) из семейства xBase c C#. Clipper и [x]Harbour позволяют получить одни и те же результаты - и это главное. [x]Harbour унаследовал все ошибки функции Mod() и оператора % от Clipper и это документированная особенность. Не знаю, что вы хотели бы увидеть, но мне кажется, что что-то типа #xtranslate <xExp1> % <xExp2> => fMod( <xExp1>, <xExp2> ) FUNCTION main SET DECIMALS TO 2 SET FIXED ON ? " 8.8 * 3.0 =", 8.8 * 3.0 ? " 3.3 * 3.0 =", 3.3 * 3.0 ? ? " 18.5 % 4.2 =", 18.5 % 4.2 ? ? " 26.4 % 8.8 =", 26.4 % 8.8 ? " 9.9 % 3.3 =", 9.9 % 3.3 ? "-26.4 % 8.8 =", -26.4 % 8.8 ? " -9.9 % 3.3 =", -9.9 % 3.3 ? " 26.4 %-8.8 =", 26.4 % -8.8 ? " 9.9 %-3.3 =", 9.9 % -3.3 RETURN 0 FUNCTION fMod( x, y ) RETURN x - Round( x/y, 0 ) * y Вот в этом направлении и двигайтесь.
| |
|
|
| |
Пост N: 169
Зарегистрирован: 12.11.06
|
|
Отправлено: 08.11.10 10:51. Заголовок: Спасибо! - Это идея,..
Спасибо! - Это идея, но разве на Clipper могу переопределить оператор (%)?
| |
|
|
| постоянный участник
|
Пост N: 995
Зарегистрирован: 09.10.06
|
|
Отправлено: 08.11.10 13:11. Заголовок: Во-первых, вы попроб..
Во-первых, вы попробуйте, за #xtranslate <xExp1> % <xExp2> => fMod( <xExp1>, <xExp2> ) отвечает препроцессор, Clipper ни о чем и не догадывается, что ему собираются подсунуть. Во вторых с помощью какого-то gsar, sed или других утилит сделать 1000 замен, что раз плюнуть. В третьих я же вам не предложил ASSOCIATE CLASS ... OPERATOR "%" ... и т.п.
| |
|
|
| |
Пост N: 170
Зарегистрирован: 12.11.06
|
|
Отправлено: 08.11.10 16:29. Заголовок: Спасибо... Этой же е..
Спасибо... Этой же ерундой уже занимаюсь! Увы % это не только знак "операции", но и обозначения "процента", использующегося в бизнесе. Да'с сколько еще открытий чудных меня ожидает?
| |
|
|
| |
Пост N: 197
Зарегистрирован: 12.11.06
|
|
Отправлено: 22.01.11 14:11. Заголовок: AndreyZh пишет: Да&..
AndreyZh пишет: цитата: | Да'с сколько еще открытий чудных меня ожидает? |
| Добрый день! Очередные "детские грабельки", на которые потратил часок: Использую DBU пересобранную (какие-то несовместимости Clipper--xHarbour убирал), а пересобрать пришлось из-за обсуждённой раннее несовместимости индексных файлов NTX в данных системах. Но по мере увеличения числа users варианта программы на xHarbour и соотвтственно более частого использования данной утилиты обнаружил небольшой глюк - при создании индексного файла отрезались первые два знака ключевого выражения. Писалось "правильное" выражение и проблема "снималась" - решил разобраться в причине: очередная "засада"... выяснил только по одной функашке, к счастью не использующейся мной в программах: Функция IndexExp() - расширение индексного файла рабочей области в Clipper возвращает ".NTX", а в xHarbour ".ntx" Причём все примеры от "Clipper" и многие "тупо перенесённые" от xHarbour производят сравнения в стиле (IndexExp() = ".NTX") и аналогично в исходниках DBU, что в общем неправильно, а надо везде (Upper(IndexExp()) = ".NTX"). Другие ф-ции с данной "особенностью" искать пока недосуг , но может быть Вам известны другие "грабельки", связанные с несовместимостью Clipper & xHarbour? Вспомнил. В xHarbour нет ф-ции PrintReady, но есть "аналог" IsPrinter - как то быстро разобрался
| |
|
|
| Администратор
|
Пост N: 1805
Зарегистрирован: 23.05.05
|
|
Отправлено: 22.01.11 14:57. Заголовок: AndreyZh пишет: Фун..
AndreyZh пишет: цитата: | Функция IndexExp() - расширение индексного файла рабочей области в Clipper возвращает ".NTX", а в xHarbour ".ntx" |
| У меня сохранились сырцы Харбора версии 0.39 от 2002 года, и там уже IndexExt() был на нижнем регистре. Почему ? Я могу только сказать, что так сложилось исторически. Возможно, разработчики ориентировались на *nix, где принято использовать нижний регистр.
| |
|
|
| постоянный участник
|
Пост N: 1642
Зарегистрирован: 12.09.06
|
|
Отправлено: 22.01.11 17:04. Заголовок: AndreyZh пишет: В x..
| |
|
|
| |
Пост N: 199
Зарегистрирован: 12.11.06
|
|
Отправлено: 22.01.11 18:54. Заголовок: Andrey пишет: Польз..
| |
|
|
|
| Администратор
|
Пост N: 1807
Зарегистрирован: 23.05.05
|
|
Отправлено: 22.01.11 22:45. Заголовок: Здесь необходимо исп..
Здесь необходимо использовать другой подход. Если Вы нашли какую-то несовместимость, которую считаете существенной, то приймите меры, чтобы ее устранить. Устранить можно либо самому, передав фикс разработчикам, либо долбать разработчиков, чтобы это кто-то сделал. И клевать надо не здесь, а непосредственно в майл-листе харбора. Здесь конечно тоже есть разработчики, но очень мало. Мне, к примеру, эта несовместимость по IndexExt совершенно неинтересна. Более того, поскольку я уже много лет программирую не на клиппере, а на харборе, ориентируюсь на нижний регистр. И мне устранение этой несовместимости помешает. Устранить ее - раз плюнуть. Надо в include/hbrddntx.h заменить строку-литерал. Если считаете, что это необходимо - доказывайте это, но не здесь, а в специально предназначенном для этого месте. Не ждите, что это кто-то сделает за Вас. Будьте сами кузнецом своего счастья. Если здесь не помогли, то этим форумом мир харбора не ограничивается. Я, кстати, так и поступал с обнаруженными мной когда-то несовместимостями.
| |
|
|
| |
Пост N: 208
Зарегистрирован: 12.11.06
|
|
Отправлено: 22.09.11 17:58. Заголовок: Pasha пишет: Здесь ..
Pasha пишет: цитата: | Здесь конечно тоже есть разработчики, но очень мало. |
| Добрый вечер! По видимому реакция Pasha показывает почему ошибки данных систем разработки не "тревожат" посетителей форума. Но всё же если таковые есть, то ещё один крайне серьёзный, непонятный глюк xHarbour (или BCC) (в clipper такой ошибки нет). Если "объяснения" по делению можно было как-то понять, то ошибки выитания (10000.00 - (21832.60 - 11832.60)) * 10000000000 = 0.018189894 (10000.00 - (21932.65 - 11932.65)) * 10000000000 = -0.018189894 (1.00 - (3.00 - 2.00) * 10000000000 = 0.0000
| |
|
|
| Администратор
|
Пост N: 2066
Зарегистрирован: 23.05.05
|
|
Отправлено: 22.09.11 22:37. Заголовок: В который раз толчем..
В который раз толчем воду в ступе Согласно стандарту IEEE 754, числа двойной точности занимают в памяти 8 байт (64 бита), из которых 1 бит приходится на знак, 52 бита - на мантиссу, и 11 бит - на экспоненту (по основанию 2) Посмотрим, как FPU (не xHarbour, не bcc, а именно FPU) выполнит эту операцию: Local nd := (10000.00 - (21832.60 - 11832.60)) ? Mantissa(nd), Exponent(nd) Результат: 1 -39 т.е. 1*2**(-39) умножаем этот результат на 10**10, и получаем 0.018189894 Если использовать числа четверенной точности, т.е. 128-ми битные, то такой ощибки округления не возникнет. Но и 128-ми битные числа неизбежно дадут ошибку округления по других операндах. Но харбор использует double двойной точности. Опять что-то непонятно ?
| |
|
|
| Администратор
|
Пост N: 2067
Зарегистрирован: 23.05.05
|
|
Отправлено: 22.09.11 23:26. Заголовок: Чтобы было совсем уж..
Чтобы было совсем уж понятно, перепишем немного функцию mantissa, чтобы она возвращала ее как целое значение. В нашем случае это будет дробная часть нормализованной мантиссы: PROCEDURE Main() Local n2 := 10000.00 Local n3 := 21832.60 - 11832.60 ? Mantissa2(n2), Exponent(n2) ? Mantissa2(n3), Exponent(n3) wait RETURN #pragma BEGINDUMP #include "hbapi.h" HB_FUNC( MANTISSA2 ) { union { double value; char string[sizeof( double )]; } xConvert; union { double value; HB_ULONGLONG ll; } xConvert2; xConvert.value = hb_parnd( 1 ); if( xConvert.value != 0 ) { xConvert.string[6] |= 0xF0; xConvert.string[7] |= 0x3F; xConvert.string[7] &= 0xBF; } xConvert2.value = xConvert.value; hb_retnll( xConvert2.ll ); } #pragma ENDDUMP Получаем: Мантисса n2: 4608176377311526912 Мантисса n3: 4608176377311526911 Эти числа разные, разница - в 19-м десятичном разряде, и операция вычитания между ними не дает 0
| |
|
|
| Администратор
|
Пост N: 2068
Зарегистрирован: 23.05.05
|
|
Отправлено: 23.09.11 08:31. Заголовок: AndreyZh пишет: ещё..
AndreyZh пишет: цитата: | ещё один крайне серьёзный, непонятный глюк xHarbour (или BCC) (в clipper такой ошибки нет). |
| Чтобы не возвращатся к этой якобы ошибке, или якобы глюку, замечу. что клиппер делает вычисления точно так же. Т.е., эта т.н. "ошибка" есть и в клиппере. Еще бы ее не было, ведь вычисления делает не клиппер, и не харбор, а fpu Думаю, что такая же "ошибка" присутствует и в Delphi, и в любом компиляторе, который выполняет вычисления с числами double
| |
|
|
| |
Пост N: 209
Зарегистрирован: 12.11.06
|
|
Отправлено: 23.09.11 09:30. Заголовок: Спасибо Pasha за ооо..
Спасибо Pasha за ооочень обстоятельный ответ! Но позвольте несколько замечаний: 1. Clipper - каюсь до конца поленился проверять то же при использовании констант даёт данный результат 0.018189894 вычислений. 2. Понятно, что не занимаюсь выискиванием проблем у систем разработок. Просто пользователи замечают несуразицы -- я пытаюсь найти их причины -- натыкаюсь на проблемки систем разработок. В частности по "последней" ОШИБКЕ: В товарной накладной есть дата просрочки платежа и сумму, которую необходимо доплатить клиенту и если у покупателя обнаруживается просроченные долги, то им начинается заниматься служба безопастности предприятия. В накладной есть поле "сумма к оплате" и поле "оплачено всего по накладной" - платежей может быть несколько. В конкретном случае, где мне пришлось выслушать очень много лестного от "безопастника": Накладная на 21832.60, было два платежа 11832.60 и 10000.00. Для "сигнала" о просрочке платежа программа просто из суммы накладной вычитает суммы оплат и сравнивает с нулем (думаю аналогичные алгоритмы во всех бизнес разработках): if ("сумма накладной" - "все платежи" > 0) .and. имеется_просрочка_оплаты <выдача задания службе безопастности> endi Попытаюсь дать Ваше подробное пояснение этой "гориле-безопастнику" - посмотрю на его реакцию 3. В клиппере данная конструкция IF даёт корректный результат 4. Ваше объяснение не поясняет факт, что в Харб и Клиппере корректно считает (1.00 - (3.00 - 2.00) * 10000000000 = 0.0000 5. Стало любопытно, а как обрабатывают (считают) другие системы разработки... ВСЕ СЧИТАЮТ "КАК ПОЛОЖЕНО", именно дают в результате ноль проверенные сейчас: Visual FoxPro5.0, MS Acces 2000, OO Calc 3.2, MS VS C#
| |
|
|
| Администратор
|
Пост N: 2069
Зарегистрирован: 23.05.05
|
|
Отправлено: 23.09.11 10:14. Заголовок: AndreyZh пишет: 5. ..
AndreyZh пишет: цитата: | 5. Стало любопытно, а как обрабатывают (считают) другие системы разработки... ВСЕ СЧИТАЮТ "КАК ПОЛОЖЕНО", именно дают в результате ноль проверенные сейчас: Visual FoxPro5.0, MS Acces 2000, OO Calc 3.2, MS VS C# |
| Мне тоже стало любопытно из всего этого безобразия у меня случайно оказался только vfp 6. Даже ms office нет Проверяю: n1 = 10000.00 n2 = 21832.60-11832.60 ? n1 == n2 Результат - .T. казалось бы.. но проверим еще раз на всякий случай: ? (n1-n2)*10000000000 результат - точно такой же, как в клиппере и харборе. Что и неудивительно. Вывод: в фокспро процедура сравнения double выполняется не просто сравнением двух значений, а сравнением с учетом некоторой погрешности eps. Что не совсем верно, и это может вылезти где-то еще. В клиппере операция сравнения - просто сравнение double. В харборе - тоже самое
| |
|
|
| Администратор
|
Пост N: 2070
Зарегистрирован: 23.05.05
|
|
Отправлено: 23.09.11 10:23. Заголовок: AndreyZh пишет: Поп..
AndreyZh пишет: цитата: | Попытаюсь дать Ваше подробное пояснение этой "гориле-безопастнику" - посмотрю на его реакцию |
| Мнээ.. не советую. Сьедят (с) Понедельник начинается в субботу Лучше слелайте в своих программах проверку на ноль не простым сравнением, а через Round(n1, 2) Я так сделал еще в те далекие времена, когда небо было голубее, трава зеленее, и первый раз попался в клиппере на такую особенность вычислений с double
| |
|
|
| |
Пост N: 210
Зарегистрирован: 12.11.06
|
|
Отправлено: 23.09.11 10:57. Заголовок: Pasha пишет: Лучше ..
Pasha пишет: цитата: | Лучше слелайте в своих программах проверку на ноль не простым сравнением, а через Round(n1, 2) Я так сделал еще в те далекие времена, когда небо было голубее, трава зеленее, и первый раз попался в клиппере на такую особенность вычислений с double |
| Конечно так уже сделал! - "А что делать?"
| |
|
|
| Администратор
|
Пост N: 2071
Зарегистрирован: 23.05.05
|
|
Отправлено: 23.09.11 12:48. Заголовок: AndreyZh пишет: 4. ..
AndreyZh пишет: цитата: | 4. Ваше объяснение не поясняет факт, что в Харб и Клиппере корректно считает (1.00 - (3.00 - 2.00) * 10000000000 = 0.0000 |
| Как так ?!! А мне показалось, что я все обьяснил Тестовая программа: Local n1 := 10000.00 Local n2, n3, i Local i1 := 0 Local i2 := 0 for i := 1 to 10000000 n2 := Round(n1+i*0.01, 2) n3 := Round(n1+n1+i*0.01, 2) if n1-(n3-n2) == 0.00 i1 ++ else i2 ++ endif next qout(i1, i2) __Wait('') Результат: 8733568 1266432 Т.е., в 87.3% сравнений получаем равенство, а в 12.7% - неравенство Вот такая она, арифметика с плавающей точкой. Это как повезет. Считайте, что для (1.00 - (3.00 - 2.00) - повезло Кстати, если варьировать параметры цикла, например поставить i до 100000, то результат будет совершенно другим, 52% на 48%
| |
|
|
|
| Администратор
|
Пост N: 2072
Зарегистрирован: 23.05.05
|
|
Отправлено: 25.09.11 12:57. Заголовок: Докладываю о продела..
Докладываю о проделанной работе. На форуме фокса выяснил, что в vfp используется вобщем-то некрасивое и недокументированное решение: при сравнении double числа не просто сравниваются, а сравниваются с округлением до количества десятичных знаков, которое задается для отображения переменной numeric. Это количество десятичных знаков задается при создании переменной в соответсвии со значением set decimals (или прямо в константе), и по умолчанию равно двум. Если перед созданием переменных задать SET DECIMALS TO 18, то при сравнении возникнет ошибка (.F.), точно такая же, как в харборе. Я рассказал об этом в devlist, предложив добавить подобную фичу и в харбор (по отдельной настройке SET). Виктор, естественно, отказал. Да я бы и сам подумал бы 10 раз, прежде чем это делать. Одно дело - предложить, другое - реализовать. Есть еще вариант решения этого вопроса - добавить в харбор еще один числовой подтип - currency. Имеется в виду хранение чисел в целом формате (4 или 8 байт), но с некоторой базой: например, 2 или 4. Если это 2, то, грубо говоря, значения хранятся в "копейках", если 4 - в десятитысячных долях целого. И используется целочисленная арифметика, при которой подобных пролбем в принципе быть не может. В формате dbf есть подобный тип данных - "Y" Несколько лет назад у меня самого чесались руки сделать это, но там есть свои подводные камни. Вобшем, пока этот вопрос открыт. В свою очередь, могу предложить такую функцию для проверки double на 0. В этой функции помимо сравнения значения с нулем проверяется еще и эксонента, и, если она меньше или равна -36 (т.е. значение меньше или равно 2**-36), то считается, что число равно нулю. Как показывает практика, при вычислениях большей погрешности не возникаает. Вот эта функция: #pragma BEGINDUMP #include "hbapi.h" static int exponent( double d ) { int iExponent = 0; union { double value; char string[sizeof( double )]; } xConvert; xConvert.value = d; if( xConvert.value != 0 ) { iExponent = ( int ) ( xConvert.string[7] & 0x07F ); iExponent = iExponent << 4; iExponent += ( int ) ( ( xConvert.string[6] & 0xF0 ) >> 4 ); iExponent -= 1023; } return iExponent; } HB_FUNC( EQU0 ) { double d = hb_parnd(1); hb_retl( d == 0.0 || exponent( d ) <= -36 ); } #pragma ENDDUMP
| |
|
|
| |
Не зарегистрирован
Зарегистрирован: 01.01.70
|
|
Отправлено: 25.09.11 13:39. Заголовок: Учет неполных копеек
По поводу "..используется целочисленная арифметика, при которой подобных пролбем в принципе быть не может" Это справедливо, видимо, только для операций, где нет деления ( вычисления частей) - сложение,вычитание, умножение на целое. Вопрос возник из учетной задачи с финансовыми суммами с дробями( где копейки - десятичные дроби). В этой среде -дополнительно к погрешности,вызванной машинным представлением чисел (то есть неточно), есть другая погрешность - из-за необходимости представлять промежуточные и конечные результаты целым числом копеек. Поскольку принципиально есть операции деления с потерей значаших разрядов ( например расчет сумм НДС), и где всегда ошибка (неточность) вычисления суммы частей не равна сумме ошибок(неточностей) частей. Как правило, при вычислениях необходимо , наборот, явно определять и контролировать получаемую погрешность и относить ее на особую статью учета. Например, товар 3 упаковки (упаковка = 1/3 часть целого) на общую сумму 1.00 руб (100 коп) при ставке НДС 10 % с суммой НДС 0.10 руб при продаже тремя частями при необходимости указывать цену продажи в целых копейках и фиксировать, как полную сумму, так и сумму НДС - при каждой продаже, приводит к разнице в копейку по сумме товара и сумме НДС: 1.00 руб(0.10 ндс) <> 3*0,33 (0,03 ндс - потеря значимости) = 0,99 ( 0,09 ндс) То есть, видимо, лучше применять свой специальный инструментарий для вычислений, в том числе и для сравнения финансовых сумм, чем полагаться на некие неявные свойства арифметических библиотек среды исполнения.
| |
|
|
| Администратор
|
Пост N: 2073
Зарегистрирован: 23.05.05
|
|
Отправлено: 25.09.11 17:11. Заголовок: petr707 пишет: По п..
petr707 пишет: цитата: | По поводу "..используется целочисленная арифметика, при которой подобных пролбем в принципе быть не может" Это справедливо, видимо, только для операций, где нет деления ( вычисления частей) - сложение,вычитание, умножение на целое. |
| Числовой тип харбора сейчас имеет несколько подтипов: целый (integer и long), и double. Операндами бинарной арифметической операции могут быть любые значения, и подтип результата такой операции определяется автоматически, чтобы избежать потери значности: скажем, если это операция long-long, то ее результатом может быть как long, так и double, если для long не хватает разрядности. Результат операции long div long - всегда double. Такие же правила можно выработать и для нового целого типа currency. Пусть результат операции currency div currency будет double, а результат остальных трех операций - currency или double (если разрядности currency не хватает). Так что этот вопрос как раз проблемы не составляет.
| |
|
|
| |
Пост N: 211
Зарегистрирован: 12.11.06
|
|
Отправлено: 25.09.11 18:53. Заголовок: Уважаемые господа! О..
Уважаемые господа! Особенно поклон Pasha за большие усилия по нахождению вариантов решения проблем! Ещё раз "оговорюсь", что в данной теме перечисляются проблемки, выявляющиеся в процессе эксплуатации конкретной системы и их разрешение позволит другим разработчика сразу их избежать при создании своих систем. Если и другие разработчики выявляют какие-то "технические проблемы системы разработки", то так же их хотелось бы знать заранее, что бы не наступать на "грабельки" в своих программах.
| |
|
|
| Администратор
|
Пост N: 2079
Зарегистрирован: 23.05.05
|
|
Отправлено: 27.09.11 18:45. Заголовок: Pasha пишет: Тестов..
Pasha пишет: цитата: | Тестовая программа: Local n1 := 10000.00 Local n2, n3, i Local i1 := 0 Local i2 := 0 for i := 1 to 10000000 n2 := Round(n1+i*0.01, 2) n3 := Round(n1+n1+i*0.01, 2) if n1-(n3-n2) == 0.00 i1 ++ else i2 ++ endif next qout(i1, i2) __Wait('') |
| Из любопытства запустил подобную програмку на vfp6. Харбор показал в 2 раза лучший результат: фокс ее выполнил за 18 сек, харбор - за 9.
| |
|
|
| |
Пост N: 215
Зарегистрирован: 12.11.06
|
|
Отправлено: 19.03.12 08:58. Заголовок: Строгость xHarbour, несовместимая с допусками Clipper
Доброе утро! Опишу очередные геморрои с исправлениями "несовместимостей" между Clipper и xHarbour (может быть кто-то избежит ненужных потерь времени, сразу исправляя несовместимости): 1. Передаю в функцию переменную - func mmm(xPar) - .... - xPar := AllTrim(Upper(xPar)) Если переменная не задана ( =mmm() ), то клиппер нормально продолжает работать, воспринимая xPar, как пустое символьное значение... по крайней мере в моём последующем коде... xHarbour вылетает по ошибке "неопределенный тип"... Выявилось, когда user, самостоятельно настраивая прогу забыл задать параметр. 2. USE ls_works SHAR NEW Открываю таблицу, но алиас ls_works уже используется... Клиппер на это реагирует спокойно и правильно обрабатывает рабочую область... xHarbour вылетает по ошибке... На это натыкался в самом начале переделки системы и описывал, но среди кода затесалась эта фигня, к которой обращаются крайне редко... но обратились... и программа вылетела... и на меня справедливо наехали пользователи. 3. Фигня - конечно. Для просмотра создаётся пустой файл, есть "чужая" функция просмотра текстовых файлов неограниченного размера через класс TBroseDB... так и не смог подружить её с xHarbour... но выкрутился - memedit работает с файлами неогр. размера... но народ привык, что можно при просмотре Home/End просматривать широкий отчёт, но первая строка "пустая", т.е. не работает... выкрутился - заставляю курсор перемещаться вниз на реальные строки... но когда 40 чел "проедают плешь" не очень приятно. Это то, что вспомнил с "последнего" сообщения... на тему 100% совместимостей Clipper и [x]Harbour...
| |
|
|
| Администратор
|
Пост N: 2307
Зарегистрирован: 23.05.05
|
|
Отправлено: 19.03.12 10:14. Заголовок: AndreyZh пишет: - x..
AndreyZh пишет: цитата: | - xPar := AllTrim(Upper(xPar)) Если переменная не задана ( =mmm() ), то клиппер нормально продолжает работать, воспринимая xPar, как пустое символьное значение... по крайней мере в моём последующем коде... xHarbour вылетает по ошибке "неопределенный тип"... Выявилось, когда user, самостоятельно настраивая прогу забыл задать параметр. |
| Это не соответствует действительности. Клиппер (я проверил на 5.2е) работает точно так же, как Харбор Upper(nil) генерирует argument error
| |
|
|
| |
Пост N: 216
Зарегистрирован: 12.11.06
|
|
Отправлено: 19.03.12 10:51. Заголовок: Pasha пишет: Это не..
Pasha пишет: цитата: | Это не соответствует действительности. Клиппер (я проверил на 5.2е) работает точно так же, как Харбор Upper(nil) генерирует argument error |
| Вот "Фома неверущий"... Clipper 5.01r + CTII... использовалось без ошибок с корректной обработкой: #include "laks.ch" * ---------------------------------------------------------------------------- * Стартовая процедура. PROC Main( cPar, cSaveLog ) LOCA lRep:=FALSE, nSel:=1, nSelWork:=1, cTxt:="", aArr:={}, nC:=0, nI:=0 // Глобальные системные установки пакета и конфигурация по df. #include "cfg.ch" cnProgramm := "Администр." // Загружаем/изменяем значения переменных настройки из стандартной базы данных IF !NetUse( "LS.CFG", SHAR_MODE, 5 ) THEN fErrQuit("Недоступна БД конфигурации!","W+*/N") #include "config.ch" cpZatr := IF(Empty(Alltrim(cpZatr)),"В.РАСХОД",cpZatr) // Вставка моего заголовка и блокирование закрытия окна pWind(" Администратор и бухгалтерский модуль (УС Land)... Предприятие: "+Alltrim(cpName),"hla.ico") ..... // Настройка и ремонт запускается до открытия файлов. cPar := IF( Pcount()==0, "", cPar ) IF Upper(cPar)=="R" THEN pRepair() // Ремонт IF Upper(cPar)=="C" THEN aConfig(FALSE) // Конфигурация IF Upper(cPar)=="O" THEN lRep:=TRUE // Признак отчетной программы. ZhSoft() pOpAllBase() // Пользователь в режиме неопределенный. Принудительный вызов режима проверки логики после открытия БД IF Upper(cPar)=="L" CLS pChLogic(Upper(Alltrim(cPar)),Upper(Alltrim(cSaveLog))) ENDI // Вызов системы нуления программы. IF Upper(cPar)=="D" THEN pDestroyBase() .... // Блок ввода и проверки допуска к работе с программой Сейчас исправлено: PROC Main( cPar, cSaveLog ) LOCA lRep:=FALSE, nSel:=1, nSelWork:=1, cTxt:="", aArr:={}, nC:=0, nI:=0 DEFAULT cPar TO "", cSaveLog TO "" где default команда препроцессора: #xcommand DEFAULT <p> TO <v> [, <p2> TO <v2> ] => ; <p> := IF(<p> == NIL, <v>, <p>) ; [; <p2> := IF (<p2> == NIL, <v2>, <p2>) ]
| |
|
|
| Администратор
|
Пост N: 2308
Зарегистрирован: 23.05.05
|
|
Отправлено: 19.03.12 11:22. Заголовок: AndreyZh пишет: Вот..
AndreyZh пишет: цитата: | Вот "Фома неверущий"... Clipper 5.01r + CTII... использовалось без ошибок с корректной обработкой: |
| Точнее формулировать надо. AllTrim(Upper()) это не то же самое, что Upper(Alltrim()) Проверяем: Alltrim(nil) 501 - работает 52, харбор - возникает ошибка Т.е. речь идет не о совместимости клиппера и харбора, а о несовместимости разных версий клиппера. Харбор естественно совместим с версиями 5.2e и 5.3b, которые считаются "каноническими".
| |
|
|
| |
Пост N: 217
Зарегистрирован: 12.11.06
|
|
Отправлено: 19.03.12 12:18. Заголовок: Pasha пишет: Alltri..
Pasha пишет: цитата: | Alltrim(nil) 501 - работает 52, харбор - возникает ошибка Т.е. речь идет не о совместимости клиппера и харбора, а о несовместимости разных версий клиппера. Харбор естественно совместим с версиями 5.2e и 5.3b, которые считаются "каноническими |
|
Pasha пишет: Об ентом и написал выше... То есть, если писать прогу на Harbour "с нуля", то многие вещи будут казаться "очевидными" и прога, скорее всего не будет иметь ошибок, связанных "с совместимостью"... если переделывать, а особенно код, который перелопачивался на протяжении 16 лет, то "веселье" гарантировано. цитата: | Точнее формулировать надо. AllTrim(Upper()) это не то же самое, что Upper(Alltrim()) |
| Нормально, но
| |
|
|
|
| Администратор
|
Пост N: 2309
Зарегистрирован: 23.05.05
|
|
Отправлено: 19.03.12 12:47. Заголовок: AndreyZh пишет: Об ..
AndreyZh пишет: цитата: | Об ентом и написал выше... То есть, если писать прогу на Harbour "с нуля", то многие вещи будут казаться "очевидными" и прога, скорее всего не будет иметь ошибок, связанных "с совместимостью"... если переделывать, а особенно код, который перелопачивался на протяжении 16 лет, то "веселье" гарантировано. |
| Если бы вы переводили программу с 501 на 52/53, то столкнулись с такой же проблемой. Дело не в харборе, а самом клиппере. Кстати, разработчики харбора предусмотрели возможность поведения харбора как для старых версий клиппера Если харбор собрать без флага HB_COMPAT_C53, то Alltrim не будет генерировать ошибку, если ему не передать параметр Так что слова о какой-то особой сложности перехода на харбор некорректны. Надо просто понимать эти несовместимости и учитывать их при переходе. Множество казалось бы несовместимостей связано с особенностиями ms dos, которых просто нет в современных ОС. По поводу ошибки, которую генерирует use, если попытаться 2-й раз открыть уже открытый файл 5.2 генерирует при этом ошибку, как и харбор, а 501 - игнорирует ошибку. Ну и что правильного в таком поведении ? И опять таки, мы имеем дело с разным поведением версий клиппера, а не с несовместимостью клиппера и харбора. Харбор же не может одновременно воспроизвести противоположное поведение разных версий клиппера. По TBrowseDB. Вообще-то это не класс, а функция с уже определенными блоками кода для навигации по таблице БД, и как ее можно прикрутить для навигации по текстовому файлу, я не представляю.
| |
|
|
| |
Пост N: 218
Зарегистрирован: 12.11.06
|
|
Отправлено: 19.03.12 13:32. Заголовок: Pasha пишет: По TBr..
Pasha пишет: цитата: | По TBrowseDB. Вообще-то это не класс, а функция с уже определенными блоками кода для навигации по таблице БД, и как ее можно прикрутить для навигации по текстовому файлу, я не представляю. |
| Не придирайтесь!!! - Да? Что по технологии - ловите, имеющий самостоятельную ценность исходник: Скрытый текст * =========================================================================== * Просмотр файлов неограниченной длины. Адаптация под стиль Жукова Андрея * программы Станислава Кросмана, а также исправление логических ошибок. * !!! Для xHarbour не удалось заставить работать - заменил редактированием. * =========================================================================== #include "function.ch" #define ATNUM(d,c,b,e) IF(At(d,Subs(c,e+1))==0,0,At(d,Subs(c,e+1))+nPointer-1) * #define BUFFER 4096 // Размер считываемого в начале буфера * #define BUFFER2 2048 // Размер считываемого куска файла * #define CRITICAL_LENTH 256 // Размер максимальной длины строки **** 09.2001 Переделал старые установки т.к. вылетал при просмотре больших файлов **** после чего программа стала работать более стабильно. **** ? Не понятно как повлияли данные размеры и почему. Память ОЗУ не менялась. #define BUFFER 2048 // Размер считываемого в начале буфера #define BUFFER2 1024 // Размер считываемого куска файла #define CRITICAL_LENTH 512 // Размер максимальной длины строки STAT nH // handler файла STAT nPointer // Указатель в файле // Флаг позиции в файле(0-достигнуто начало файла,1-внутри файла,2-достигнут конец файла) STAT nFl_pos STAT cStr // Строка-буфер STAT nStrPoint:=1 // Указатель в строке // Флаг позиции в строке-буфере(0-начало строки,1-внутри строки,2-достигнут конец строки) STAT nFf_pos STAT lFl_direction // Направление последнего перемещения STAT nLenFile // Длина текстового файла. // Отладочный пример. Даем параметры и вызываем функцию просмотра PROC M__12__34_(); SET SCOR OFF; Wboard(); CLS; lLookFile("LOOPFILE.PRG",1,2,22,73,"RG+/B") RETU /* Функция просмотра текстовых файлов неогран.длины при помощи обьекта-таблицы. Параметры: Имя файла, координаты окна, цвет отображения текста. Возврашает значиние ложь при обнаружении ошибки. */ FUNC lLookFile( cFile, nX, nY, nDx, nDy, cCol ) LOCA x:=2, y:=2, x1:=nX+nDx-2, y1:=nY+nDy-2, nOldCur:=SetCursor() LOCA cOldCol:=SetColor(), oB, oC, ik:=0 // Обьекты PRIV GetList:={} DEFAULT nX TO 0, nY TO 0, nDx TO 24, nDy TO 79, cCol TO "W/N" fSwopen( nX, nY, nDx, nDy, cCol, 4 ) @ 0,nY+nDy-42 SAY " Home-начало End-конец строки Esc - выход " SetCursor( 0 ) nH := Fopen(cFile, FO_READ) // Просматриваемый файл только для чтения IF nH == -1 THEN RETU FALSE // Ошибка при открытии файла. nLenFile := Fseek( nH, 0, FS_END) // Вымеряем длину файла. Go_home() // Устанавливаем указатель на начало файла oB := TBrowseNew(x, y, x1, y1) // Блоки кода перемещения по сканируемой строке. oB:goTopBlock := {|| Go_home() } oB:goBottomBlock:= {|| Go_end() } oB:skipBlock := {|nSkip| Skipp(nSkip) } // Колонка - извлеченная из строки буфера строка. oC := tbColumnNew("",{|| Take_str() }) // Пока без заголовка колонки. oC:width:= y1 - y + 1 oB:addColumn( oC ) oB:autolite := FALSE // Не выделять текущую строку в процессе стабилизации. // Начало обработки табличного обьекта. WHIL TRUE DispBegin() WHIL !oB:stabilize() .AND. NextKey()==0 // Выполняем цикл стабилизации ENDD @ 0,1 SAY " "+IF(nFl_pos==0," 0",IF(nFl_pos==2,"100",cProc()))+"% " DispEnd() IF ( ik:=Inkey(0) ) == K_ESC THEN EXIT DO CASE // Обрабатываем нажатую клавишу. CASE ik == K_LEFT IF nStrPoint > 1 // Можно перемещаться еще влево. nStrPoint-- oB:refreshAll() ENDI CASE ik == K_RIGHT // След. можно уходить за границу текста 256 знаков. nStrPoint++ oB:refreshAll() CASE ik == K_PGDN oB:rowPos := oB:rowCount // Текущая строка = количеству видим.строк IF !oB:hitBottom THEN oB:pageDown() CASE ik == K_PGUP oB:rowPos := 1 IF !oB:hitTop THEN oB:pageUp() CASE ik == K_UP oB:rowPos := 1 oB:up(); oB:up() CASE ik == K_DOWN oB:rowPos := oB:rowCount oB:down(); oB:down() CASE ik == K_CTRL_PGUP IF !oB:hitTop THEN oB:goTop() CASE ik == K_HOME IF nStrPoint <> 1 nStrPoint := 1 oB:refreshAll() ENDI CASE ik == K_CTRL_PGDN IF !oB:hitBottom THEN oB:goBottom() CASE ik == K_END nStrPoint += Max(0,60-nStrPoint) oB:refreshAll() * oB:panEnd() // Эта запись вместо двух была в оригинале текста. ENDC END Fclose( nH ) // Закрываем файл fDeact( cOldCol ) // Закрываем окно. SetCursor( nOldCur ) RETU TRUE /* Начальное считывание из файла и перерисовка экрана. */ STAT FUNC Go_home() nPointer := 1 // Указатель в просматриваемом файле. nFl_pos := nFf_pos := 0 // Позиция в буфере и файле. lFl_direction := TRUE // Направление последнего перемещения. Fseek( nH, 0, FS_SET ) // Позиционируемся в начало файла. cStr := FreadStr( nH, BUFFER ) // Начальное чтение RETU NIL /* Чтение с конца файла символов согласно размеру буфера и установ параметров */ STAT FUNC Go_end() LOCA nI:=0, nJ := Fseek( nH, 0, FS_END) // Вымеряем длину файла. Fseek( nH, -Min(BUFFER,nJ), FS_END ) // От какого места берем в буфер cStr := FreadStr( nH, Min(BUFFER,nJ) ) // Считали в сканируюмую строку Fseek( nH, 0, FS_END ) // Ушли на конец файла. nI := Rat( CRLF, cStr ) nPointer:= IF(/*есть еще знак конца строки CRLF*/ nI<>0, nI+2, 1 ) nFl_pos := nFf_pos := 2 // Признаки достижения конца строки и файла. lFl_direction := TRUE RETU NIL /* Перемещение по таблице на nN строк. Направление зависит от знака nN. */ STAT FUNC Skipp( nN ) LOCA nI := 0 IF nN >= 0 // Перемещение вниз по таблице FOR nI:=1 TO nN IF !Skipp_down() THEN nN := nI-1 // Достигнут конец файла. NEXT nI ELSE // Перемещаемся вверх по таблице. nN := -nN FOR nI:=1 to nN IF !Skipp_up() THEN nN := nI-1 // Достижение начала файла. NEXT nI nN := -nN ENDI RETU nN // На сколько сумели сдвинуться. /* Перемещение на одну строку вниз по таблице (строке-буфере,файлу). */ STAT FUNC Skipp_down() LOCA nI := ATNUM( CRLF, cStr, 1, nPointer-1 ) IF nFl_pos == 2 THEN RETU FALSE // Ранее достигли конца файла. // Необходима подкачка в буферную строку и есть для этого возможность. IF nI == 0/*нет строк вывода*/ .AND. nFf_pos <> 2 /*находимся внутри файла*/ Driver( TRUE ) // Читаем вниз по файлу. Пополняем cStr. nI := ATNUM(CRLF,cStr,1,nPointer-1) ENDI // Дальше некуда. Из файла считали все до самого его конца. IF nI == 0 THEN nFl_pos:=2/*достигли конца файла*/; RETU FALSE nPointer := nI+2 // Перемещаем указатель nFl_pos := 1 // Шагаем внутри файла. RETU TRUE /* Перемещение на одну строку вверх по таблице (строке-буферу,файлу) */ STAT FUNC Skipp_up() LOCA nI := 0 IF nFl_pos == 0 THEN RETU FALSE // Уже в начале строки. nI := Rat( CRLF, Left(cStr,nPointer-2) ) // Последнее вхождение CRLF IF nI == 0 .AND. nFf_pos <> 0 // Нужна и возможна подкачка из файла. Driver(FALSE) // Читаем вверх. nI := Rat( CRLF, Left(cStr,nPointer-2) ) ENDI IF nI == 0 // Более читать нечего. Достигли самого начала файла. nPointer := 1 nFl_pos := 0 RETU TRUE // При след.вызове проанализирует nFl_pos ENDI nPointer := nI+2 nFl_pos := 1 RETU TRUE /* Возвращает строку просмотра в табличный обьект. */ STAT FUNC Take_str() LOCA cSss:="", nI:=ATNUM( CRLF, cStr, 1, nPointer-1 ) // Нет отдельной строки, а подкачать можно т.к. не достигнут конец файла. IF (nI==0) .AND. (nFf_pos <> 2) Driver( TRUE ) // Подкачиваем из буфера в cStr и изменяем указатель nPointer. nI := ATNUM( CRLF, cStr, 1, nPointer-1 ) ENDI IF nI == 0 // Более нет текстовых строк ниже указателя. cSss := Subs( Subs(cStr,nPointer), nStrPoint ) ELSE cSss := Subs( Subs(cStr,nPointer,nI-nPointer), nStrPoint ) ENDI nI := At(CRLF,cSss) cSss := Left( cSss+Spac(CRITICAL_LENTH), CRITICAL_LENTH )+CRLF RETU cSss //tabexpand(sss) /* Драйвер подкачки из текстового файла в сканируемую строку. Параметр определяет направление просмотра. Истина читаем текст вниз по файлу. */ STAT FUNC Driver( lPar ) LOCA cBuf:="", nI:=0, nJ:=0, nK:=0, nL:=0 nFf_pos := 1 // Просмотр производится внутри строки. IF lPar .AND. nFf_pos <> 2 // Смотрим вниз, но конца файла не достигли. IF !lFl_direction // Идем в конец. Fseek( nH, Len(cStr), FS_RELATIVE ) // С текущего места. lFl_direction := TRUE ENDI IF Len( cBuf:=FreadStr(nH,BUFFER2) ) <> BUFFER2 THEN nFf_pos:=2 cStr := Right( cStr, Len(cStr) - Len(cBuf) ) + cBuf nPointer -= Len(cBuf) // nPointer += Len(cBuf) ELSEIF nFf_pos <> 0 // Нет еще начала файла. Просмотр идет вверх. IF lFl_direction // Идем в начало файла. Fseek( nH, -Len(cStr), FS_RELATIVE ) lFl_direction := FALSE ENDI nI := Fseek( nH, -Min((nL:=Fseek(nH,0,FS_RELATIVE)),BUFFER2), FS_RELATIVE) IF nI == 0 // Дальше некуда. nFf_pos := 0 nJ := nL - nI ELSE nJ := BUFFER2 ENDI /* nJ - реальное значение, на которое удалось передвинуться, nL - старое значение указателя в файле, считываем строку */ cBuf := FreadStr( nH, nJ ) Fseek( nH, nI, FS_SET ) cStr := cBuf+Left(cStr,Len(cStr)-nJ) // корректируем строку nPointer+=nJ ENDI RETU NIL /* Расчет и возврат процента прочтения текста из файла по статическим переменным */ STAT FUNC cProc() LOCA nCur := Fseek( nH, 0, FS_RELATIVE ) RETU Str( zInt(nCur*100/nLenFile), 3 )
|
| |
|
|
| Администратор
|
Пост N: 2312
Зарегистрирован: 23.05.05
|
|
Отправлено: 19.03.12 17:34. Заголовок: AndreyZh пишет: Не ..
AndreyZh пишет: цитата: | Не придирайтесь!!! - Да? Что по технологии - ловите, имеющий самостоятельную ценность исходник: |
| Да я не придираюсь, просто не очень был понятен вопрос. Что касается xHarbour TBrowse - то он не на 100% совместим с клипперовским. И с такой сложной схемой могут быть несовместимости. В этом отношении Harbour TBrowse лучше, я так и делал: собирал xHarbour, а TBrowse брал от Harbour А касательно этой процедуры: ну зачем же делать так сложно ? Лучше загнать текстовый файл в массив, используя MLCount/MemoLine(), и затем этот массив просматривать тем же TBrowse. Это будет и быстрее, и куда проще. Массив строк можно сформировать и другим способом: через TokenInit/TokenNext/ToeknEnd
| |
|
|
| |
Пост N: 232
Зарегистрирован: 12.11.06
|
|
Отправлено: 25.05.12 15:44. Заголовок: Здравствуйте! ... оч..
Здравствуйте! ... очередной глобальный глюк [x]harbour? Если так, то может быть послать разработчикам. Програмка примерно структуры: loca cc:=spac(1) .... @ 1,1 say "введите символ" get cc read .... построение отчета .... вызов запросов печати из формы и в зависимости от устройства вывод куда требуется. Проблема: Если введен символ точка или запятая, то как-бы в форме печати харб нажимает PgDn, на прочих знаках/буквах спокойненько ожидает что ему введут в качестве устройства и нажмут клавиши подтверждения. Можно, если интересно дать полный пример отчёта, но данный глюк во всех, где самым последним get вводится один символ. Как её можно побороть: Пока сделал так, благо после каждого read у меня есть вызов ф-ции верификации user, т.е. просто добавил в неё: if lastkey() = 44 .or. lastkey() = 46 keyb chr(K_ENTER) inkey(0) endi P.S. Уже была чем-то схожая проблема, когда харб не любил цифру 1, но Pasha связывался с разработчиками и они порешали её.
| |
|
|
| |
Пост N: 2381
Зарегистрирован: 17.05.05
|
|
Отправлено: 25.05.12 16:11. Заголовок: AndreyZh Проверил в..
AndreyZh Проверил в Harbour и XHarbour , проблемы не увидел.
| |
|
|
| |
Пост N: 493
Зарегистрирован: 11.06.10
|
|
Отправлено: 25.05.12 17:26. Заголовок: Т.к. AndreyZh пишет:..
Т.к. AndreyZh пишет: , то при вводе любого символа read завершается пробуйте так @ 1,1 say "введите символ" get cc valid lastkey()=13
| |
|
|
| |
Пост N: 233
Зарегистрирован: 12.11.06
|
|
Отправлено: 25.05.12 21:38. Заголовок: Уважаемые господа. ..
Уважаемые господа. Есть некая сложность с тестами, т.к. всё является частью большой системы с кучей взаимопересекающихся процедур, но как то Pasha исхитрялся находить самодостаточные примеры иллюстрирующие приводимые мной уже пару лет "глюки" Dima пишет: цитата: | AndreyZh Проверил в Harbour и XHarbour , проблемы не увидел. |
| Вы скачивали систему... желающие могут это сделать уже с нормальным дистрибутивом дистрибутив с версией июня 2012 (34мб) где ещё имеется данная проблема: программа аналитика/динамические... любой отчет, на последний запрос знака разделителя вводите различные знаки (глюки только на точке и запятой) AlexMyr пишет: цитата: | , то при вводе любого символа read завершается пробуйте так @ 1,1 say "введите символ" get cc valid lastkey()=13 |
| Не в этом проблема... Ясно, что когда ввожу единственный знак, то это и завершает READ, но поведение проги в дальнейшем зависит от символа.
| |
|
|
| |
Пост N: 494
Зарегистрирован: 11.06.10
|
|
Отправлено: 25.05.12 22:06. Заголовок: AndreyZh пишет: но ..
AndreyZh пишет: цитата: | но поведение проги в дальнейшем зависит от символа. |
|
каким боком Harbour к проблеме в Вашей проге ввиде обработки символа?
| |
|
|
| |
Не зарегистрирован
Зарегистрирован: 01.01.70
|
|
Отправлено: 25.05.12 22:27. Заголовок: get, lastkey() and picture
1) в общем случае содержимое GET не совпадает с lastkey() 2) для исключения дефолтового поведения лучше использовать конструкцию с Picture 3) ниже код, где можно посмотреть разницу - при нажатии Esc , PageDown и прочее proc main() loca cc:=space(1) , dd:=space(1),ff:=space(1),i @0,0 cls for i=1 to 20 @ 1,1 say "введите символ 1 " get cc read @2,1 say "cc="+str( asc(cc),3) @3,1 say "lastkey()="+str( lastkey(),3) @ 5,1 say "введите символ 2" get dd picture "X" read @6,1 say "dd="+str( asc(dd),3) @7,1 say "lastkey()="+str( lastkey(),3) @10,1 say "введите символ 3" get ff picture "9" read @11,1 say "ff="+str( asc(ff),3) @12,1 say "lastkey()="+str( lastkey(),3) next i return
| |
|
|
| |
Пост N: 236
Зарегистрирован: 12.11.06
|
|
Отправлено: 26.05.12 09:23. Заголовок: Доброе утро. Напишу..
Доброе утро. Напишу много букф, т.к. исправление данного бага считаю важным и это проявляется в программе на Harbour, а на клиппере всё, правильно, как и должно быть .... Наверное не был услышан, но умею пользоваться шаблонами и etc. Более того понимаю Диму - попытался сделать самостоятельный пример и там всё работает правильно. Пример (иммитация логики программы): proc ptest() loca a:=" ", b:=" " cls @ 1,1 say "введите символы" get a @ 2,1 say "нажмите символ " get b read ptest2() retu proc ptest2() loca a:=" ", b:=" " @ 4,1 say "введите символы" get a @ 5,1 say "нажмите символ " get b read @ 6,0 say "нажмите клавишу "+b+" "+a inkey(0) retu Далее приведу реальный текст процедур, где ***** будут выделены ключевые моменты. Это один из десятков отчетов, где наблюдается данный глюк. Разбил на два сообщения, т.к. форум не хочет по русски воспринимать копипаст
| |
|
|
|
| |
Пост N: 238
Зарегистрирован: 12.11.06
|
|
Отправлено: 26.05.12 09:32. Заголовок: „P„‚„Ђ„t„Ђ„|„w„..
„P„‚„Ђ„t„Ђ„|„w„u„~„y„u. „Q„u„p„|„Ћ„~„Ђ„u „Ѓ„‚„y„|„Ђ„w„u„~„y„u... Всё конечно жутко понятно? ... попробую разделить на маленькое кусочки Скрытый текст
* --------------------------------------------------------------------------- * Оборотная ведомость по финансовым операциям. Анализ кассы, банка по осно- * ваниям документов. * 03.2007 Доб. коррекцию начального сальдо. Работа по нескольким расч/счетам STAT PROC pObFins() LOCA cOldCol:=SetColor(), GetList:={}, dD:=Date(), dT:=Date(), nN:=0, nS:=0, cT:="" LOCA dBeg:=Date(), dEnd:=Date(), nPer:=1, nCash:=3, cReas:=Spac(15), nSaldo:=0 LOCA nBeg:=0, nEnd:=0, nPrih:=0, nRash:=0, np:=0, nr:=0 LOCA nStr:=99999, nPage:=0, nC:=0, nJ:=0, nRep:=77 LOCA cDbf:="", cNtx:="", cTxt:="" LOCA aArr:={{"dMove", "D", 8, 0},; {"sum", "N", 15, 2},; // Приход {"sumPut", "N", 15, 2}} // Расход LOCA sOp:="7655", cOff:=" " S_PROC cSent3 := Spac(25) // Из ЭФ читаем параметры построения отчета. fsWopen(16,18,7,59,cColor,2) @ 1,1 SAY "Пожалуйста вв. дату начала ........ конца ........ периода" @ 2,1 SAY "Цифру 1-Касса,2-Банк,3-Все . Длину подпериода(0-месяц) ..." @ 3,1 SAY "Набор букв основания документов или ничего ..............." @ 4,1 SAY "Набор букв сист.метки (F3) ........................." @ 5,1 SAY "Коррекция для начального сальдо по кассе/банку ..........." @ 6,1 SAY "Разделитель чисел для экспорта в MsOffice или ничего ." @1,28 GET dBeg VALI lValid({||dBeg<=Date()},"Больше текущей!") @1,43 GET dEnd VALI lValid({||dBeg<=dEnd},"Меньше начальной!") @2,28 GET nCash PICT "9" VALI Eval({||nSaldo:=IF(nCash=1,nCashSaldo,IF(nCash=2,nBankSaldo,nCashSaldo+nBankSaldo)),TRUE}) @2,56 GET nPer PICT "999" VALI lValid({||nPer>=0},"Отрицательная длина периода!") @3,44 GET cReas @4,34 GET cSent3 PICT "@S25" @5,48 GET nSaldo PICT "99999999.99" ***** Поведение зависит от введенного символа (глюки только, если точка или запятая) @6,58 GET cOff PICT "X" READ fDeact(cOldCol) cReas := Upper(Alltrim(cReas)) cSent3 := Upper(Alltrim(cSent3)) AP__INPUT ***** В принципе данная вставка решает проблему ****** изначально её не было и пока всё не переделал IF LastKey() == 44 .OR. LastKey() == 46 KEYB Chr(K_ENTER) Inkey(0) ENDI ******************************************** далее постороение отчета - некой вспомогательной таблицы // Настройка баз, расчет бегунка и т/д fTxt_act(" Пожалуйста подождите несколько минут!",cColor) nBeg := nSaldo SELE CASH_ORD ORDE CO_DAT_NUMBER IF nCash <> 2 COUNT TO nC WHIL dat <= dEnd ENDI SELE ACCOUNT ORDE A_DAT_NUMBER IF nCash <> 1 COUNT TO nN WHIL dat <= dEnd ENDI nC += nN cDbf := zTemp(cdTemp,"DBF",32) cNtx := zTemp(cdTemp,"NTX",32) cTxt := zTemp(cdTemp,"TXT",32) DbCreate(cDbf,aArr) LanUse("",cDbf,NO_INDEX,"TEMP",EXCL_MODE,-1,NEW_SEL) INDE ON dMove TO (cNtx) fDeact( cOldCol ) // Построение временной базы на основе первичных документов. pOpenView(cColor,cError,"Подождите! Строю оборотку по деньгам",TRUE) FOR nN := 1 TO 2 IF nCash == 1 .AND. nN == 2 THEN LOOP IF nCash == 2 .AND. nN == 1 THEN LOOP DbSelectArea( IF(nN=1,"CASH_ORD","ACCOUNT") ) DbGoTop() DO WHIL !Eof() .AND. dat <= dEnd pChangeView(++nJ*100/nC) IF Empty(datPay) THEN DbSkip(); LOOP IF !Empty(cReas) .AND. At(cReas,Upper(reason)) <= 0 THEN DbSkip(); LOOP IF !Empty(cSent3) .AND. At(cSent3,Upper(lab1)) <= 0 THEN DbSkip(); LOOP // Расчет начального сальдо. IF dat < dBeg nBeg += IF(tip=="1",(+1),(-1))*sum DbSkip() LOOP ENDI // Обработка операции. Добавляю при необходимости запись во времянку dD := dat nS := sum cT := tip SELE TEMP SEEK dD IF Eof() DbAppend() dMove := dD ENDI IF cT == "1" sum += nS ELSE sumPut += nS ENDI DbSelectArea( IF(nN=1,"CASH_ORD","ACCOUNT") ) DbSkip() ENDD NEXT nN ****** Отчет (таблица) преобразовывается в текстовый файл, который затем отражаю через набор устройств // Вывожу отчет в текстовый файл, считая итоги по подпериодам. SELE TEMP TOP dT := Max(dBeg,dMove) dD := Min(IF(nPer==0,Eom(dT),dT+nPer-1),dEnd) O____A ****** В принципе на эту верку попадаю, когда определяю знак разделитель в форме, но проверял в "обычных" вариантах - такая же херь IF !Empty(cOff) // Экспорт в офис ? "Оборотная ведомость по "+IF(nCash=1,"кассе",IF(nCash=2,"банку","деньгам"))+" с "+Dtoc(dBeg)+" по "+Dtoc(dEnd) ? " Подпериод времени Ост. на начало Приход Расход Ост.на конец " DO WHIL !Eof() X_DEMO IF dMove > dD // Перешли в другой подпериод. Отражаем итоги. ? IF(nPer==0,Left(zCmonth(dT)+Spac(17),17)+Str(Year(dT),4),Dtoc(dT)+" - "+Dtoc(dD))+" "+zStr(nBeg,14,2,cOff)+" "+zStr(np,12,2,cOff)+" "+zStr(nr,12,2,cOff)+" "+zStr(nBeg+np-nr,14,2,cOff) nBeg += np - nr np := nr := 0 dT := dMove dD := Min(IF(nPer==0,Eom(dT),dT+nPer-1),dEnd) ++nStr ENDI // Считаем параметры. np += sum nr += sumPut DbSkip() ENDD // Отражаю данные по последнему периоду и общие итоги. ? IF(nPer==0,Left(zCmonth(dT)+Spac(17),17)+Str(Year(dT),4),Dtoc(dT)+" - "+Dtoc(dD))+" "+zStr(nBeg,14,2,cOff)+" "+zStr(np,12,2,cOff)+" "+zStr(nr,12,2,cOff)+" "+zStr(nBeg+np-nr,14,2,cOff) ? Chr(12) *********** ELSE // Печатаемый формат DO WHIL !Eof() X_DEMO // Выводим шапку, если надо. IF nStr > nLenst IF nPage > 0 THEN Qout(Chr(12)) ? Padc("Оборотная ведомость по "+IF(nCash=1,"кассе",IF(nCash=2,"банку","деньгам"))+" с "+Dtoc(dBeg)+" по "+Dtoc(dEnd),nRep-7)+"Стр."+Str(++nPage,3) ? Repl("-",nRep) ? " Подпериод времени |Ост. на начало| Приход | Расход | Ост.на конец " ? Repl("-",nRep) nStr := 4 ENDI IF dMove > dD // Перешли в другой подпериод. Отражаем итоги. ? IF(nPer==0,Left(zCmonth(dT)+Spac(17),17)+Str(Year(dT),4),Dtoc(dT)+" - "+Dtoc(dD))+" "+cStr(nBeg,14,2)+" "+cStr(np,12,2)+" "+cStr(nr,12,2)+" "+cStr(nBeg+np-nr,14,2) nBeg += np - nr np := nr := 0 dT := dMove dD := Min(IF(nPer==0,Eom(dT),dT+nPer-1),dEnd) ++nStr ENDI // Считаем параметры. np += sum nr += sumPut nPrih += sum nRash += sumPut DbSkip() ENDD // Отражаю данные по последнему периоду и общие итоги. ? IF(nPer==0,Left(zCmonth(dT)+Spac(17),17)+Str(Year(dT),4),Dtoc(dT)+" - "+Dtoc(dD))+" "+cStr(nBeg,14,2)+" "+cStr(np,12,2)+" "+cStr(nr,12,2)+" "+cStr(nBeg+np-nr,14,2) ? Repl("-",nRep) ? Spac(36)+cStr(nPrih,13,2)+cStr(nRash,13,2) ? Chr(12) ENDI C____A pCloseView() ***************** Вывожу текстовый файл, используя отдельную процедуру печати, где по сути и проявляется данный глюк // Демонстрирую отчет и восстанавливаю состояние среды. pFileOutDevice(cTxt) pCloseErase("TEMP",{cDbf,cNtx,cTxt}) pinStat(sOp,0) RETU
|
| |
|
|
| |
Пост N: 239
Зарегистрирован: 12.11.06
|
|
Отправлено: 26.05.12 09:53. Заголовок: „P„‚„t„Ђ„|„w„u„..
Скрытый текст
PROC pFileOutDevice( cFile, nLen, nW, cdbfm ) FIEL compr, filen, begStr, endStr, qtyCopy LOCA nDev := ngOutDev LOCA nBeg := 1 // „N„p„‰„p„|„Ћ„~„p„‘ „ѓ„„„‚„p„~„y„?„p LOCA nEnd := 9999 // „K„Ђ„~„u„‰„~„p„‘ „ѓ„„„‚„p„~„y„?„p. LOCA nQty := 1 // „K„Ђ„|„y„‰„u„ѓ„„„r„Ђ „Џ„{„x„u„}„Ѓ„|„‘„‚„Ђ„r. LOCA cOldCol:=SetColor(), nSel:=Select(), cStr:="", aDbf:={}, cF:="" LOCA nSize:=FileSize(cFile), cString:="", GetList:={} LOCA nI:=0, cSt:="" LOCA axbk:={{"compr", "L", 1, 0},; {"filen", "C", 70, 0},; {"begStr", "N", 10, 0},; {"endStr", "N", 10, 0},; {"qtyCopy", "N", 10, 0}} PRIV cNameFile:="", cOutFile:="", lLoop:=TRUE DEFAULT nLen TO 80 DEFAULT nW TO 6 DEFAULT cdbfm TO "" MEMV->cNameFile := AllTrim(cFile) fSwopen(16,17,7,60,cOther,4) DO WHIL TRUE ******* Казалось бы читаем из обычной формы ввода, но Harbour ппосле её открытия нажимает некие клавиши, что даёт сразу вывод на устройство по умолчани. @ 5,0 SAY Chr(199)+Repl("„џ",59)+Chr(182) COLO PosRepl(cOther,Repl(" ",AT("/",cOther)-2)+"N",1) @ 1,2 SAY "„D„|„‘ „Ѓ„u„‰„p„„„y „Ђ„„„‰„u„„„p/„t„Ђ„{„…„}„u„~„„„p „Ѓ„Ђ„w„p„|„…„z„ѓ„„„p „…„{„p„w„y„„„u „…„ѓ„„„‚„Ђ„z„ѓ„„„r„Ђ" @ 2,2 SAY "1-„P„‚„y„~„„„u„‚,2-„U„p„z„|,3-„^„{„‚,4-„V„A„K,5-Exc„V„A„K,6-„Q„u„t„p„{„„„Ђ„‚,7-Word ." @ 3,2 SAY "„~„p„‰„p„|„Ћ„~„…„ђ „y „{„Ђ„~„u„‰„~„…„ђ „ѓ„„„‚„p„~„y„?„Ќ „y„x „t„Ђ„{„…„}„u„~„„„p" @ 4,2 SAY "„p „„„p„{„w„u „{„Ђ„|„y„‰„u„ѓ„„„r„Ђ „Џ„{„x„u„}„Ѓ„|„‘„‚„Ђ„r „Ѓ„u„‰„p„„„y „t„Ђ„{„…„}„u„~„„„p " @2,58 GET nDev PICT "9" VALI nDev>=1 .AND. nDev<=7 @3,12 GET nBeg WHEN nDev==1.OR.nDev==4 PICT "9999" VALI nBeg>=1 @3,30 GET nEnd WHEN nDev==1.OR.nDev==4 PICT "9999" VALI nBeg<=nEnd @4,56 GET nQty WHEN nDev==1.OR.nDev==4 PICT "999" VALI nQty>=1 READ ****** Это старая ошибка Harbour, которые разработчики уже исправили, но по своей глупой привычке использую свои обработки этого глюка /***** Смотреть как Lack будет реагировать на данный обработчик глюка. При этом появляется глюк Clipper - при прощелкивании Enter запросы идут по кругу, т.е. Ent не обрабатывается и переходим в обработку цикла */ IF lGlukHarb(nDev) THEN LOOP
|
| |
|
|
| |
Пост N: 242
Зарегистрирован: 12.11.06
|
|
Отправлено: 07.06.12 13:56. Заголовок: Добрый день! Систем..
Добрый день! Системные программисты (разработчики), понимающие принципы "математики" xHarbour... ГДЕ ВЫ!!! Очередная пачка глюков данной системы разработки: 1. Деление и умножение обсудили раннее, а оказывается xharbour не умеет даже вычитать и складывать Сколько по Вашему будет (12.2 - 4.4 - 7.8) = ?, а теперь проверьте: WAIT Str((12.2 - 4.4 - 7.8)*1000000000,19,6) 2. Синтаксическая ошибка Wait "MAMA" * "PAPA" успешно пропускается компилятором, но программа вываливается по windows ошибке " too many recursive error handler calls"
| |
|
|
| |
Пост N: 2396
Зарегистрирован: 17.05.05
|
|
Отправлено: 07.06.12 14:25. Заголовок: AndreyZh пишет: Ско..
AndreyZh пишет: цитата: | Сколько по Вашему будет (12.2 - 4.4 - 7.8) = ?, |
| Округляй результат. Clipper кстати так же отработал. ? (12.2 - 4.4 - 7.8)==0 // .F. ? round((12.2 - 4.4 - 7.8),2)==0 // .T.
| |
|
|
| |
Пост N: 228
Зарегистрирован: 11.10.11
|
|
Отправлено: 07.06.12 15:42. Заголовок: AndreyZh пишет: Ско..
AndreyZh пишет: цитата: | Сколько по Вашему будет (12.2 - 4.4 - 7.8) = ?, а теперь проверьте: |
| Проверил! MS VC++ 2010: if ( 12.2 - 4.4 - 7.8 == 0 ) std::cout << "equal to zero\n"; else std::cout << "not equal to zero\n"; std::cout << 12.2 - 4.4 - 7.8 << std::endl; Результат: цитата: | not equal to zero -8.88178e-016 |
|
| |
|
|
| |
Пост N: 124
Зарегистрирован: 10.07.07
|
|
Отправлено: 07.06.12 16:15. Заголовок: AndreyZh пишет: Ско..
AndreyZh пишет: цитата: | Сколько по Вашему будет (12.2 - 4.4 - 7.8) = ? |
| Это явление в вычислительной математике давно описано в учебниках по методам вычислений. Например, Бахвалов Н.С. Численные методы, М. 1975. В параграфе 4 "О вычислительной погрешности", в частности, автор пишет: "Здесь нам впервые встретилось явление потери значащих цифр (или "пропадания значащих цифр"), имеющее место при вычитании близких величин ...".
| |
|
|
| |
Пост N: 243
Зарегистрирован: 12.11.06
|
|
Отправлено: 07.06.12 16:42. Заголовок: Dima пишет: Округля..
Dima пишет: цитата: | Округляй результат. Clipper кстати так же отработал. ? (12.2 - 4.4 - 7.8)==0 // .F. ? round((12.2 - 4.4 - 7.8),2)==0 // .T. |
| На это считаю полезным отметить... заодно посмотрите результат Сыроежки... получаемая цифирь может быть, как больше, так и меньше нуля, кроме это вполне допустимы расчеты, где нормально, что результат "около нуля", т.е. банальные проверки типа "если имеется долг (сумма отгрузки - сумма платежей) клиента, то запретить ему отгрузку", а особенно если имеются скидки/наценки по накладной превращаются в громадные аналитические конструкции, где пытаешься отрабатывать, как "нормальные" погрешности округления, так и погрешности, связанные с логикой подгонки цифр в документах, так и с погрешностями "типа правильного счета" системы разработки. Просто замечу, что ни в клиппер, ни в фоксе, ни в си шарп, ни в аксес таких заморочек (на всей этой команде приходится пописывать) и "особенностей" не возникает, т.е. это не "математические особенности округления", а недоработки инструмента... в данном случае xharbour. Что по особенности Клиппер: а := 0.00 if a == 0.... Над этой ошибкой пришлось в древности много работать и учитывать, кроме того она по разному обрабатывается на разных ОС и разных типах процессоров. Вообще в данной темке "не обсираю" харб, а просто предупреждаю о возможных грабельках других раработчиков и если не интересно, то ...
| |
|
|
| Администратор
|
Пост N: 2366
Зарегистрирован: 23.05.05
|
|
Отправлено: 07.06.12 18:19. Заголовок: AndreyZh пишет: 1. ..
AndreyZh пишет: цитата: | 1. Деление и умножение обсудили раннее, а оказывается xharbour не умеет даже вычитать и складывать |
| Так мы ведь в прошлом году как раз вычитание и обсуждали, не ? Вот цитата от 22.09.11 18:58: цитата: | Если "объяснения" по делению можно было как-то понять, то ошибки выитания (10000.00 - (21832.60 - 11832.60)) * 10000000000 = 0.018189894 (10000.00 - (21932.65 - 11932.65)) * 10000000000 = -0.018189894 (1.00 - (3.00 - 2.00) * 10000000000 = 0.0000 |
| Я и тест делал, в котором видно, что примерно в 1/8 случаев при вычитании double fpu не дает ноль, или равенство. Для гарантированного получения нужного результата необходимо промежуточное округление. И харбор тут ни при чем, как и клиппер и любой другой язык, использующий явно или неявно тип double.
| |
|
|
| Администратор
|
Пост N: 2367
Зарегистрирован: 23.05.05
|
|
Отправлено: 07.06.12 18:25. Заголовок: AndreyZh пишет: Про..
AndreyZh пишет: цитата: | Просто замечу, что ни в клиппер, ни в фоксе, ни в си шарп, ни в аксес таких заморочек (на всей этой команде приходится пописывать) и "особенностей" не возникает, т.е. это не "математические особенности округления", а недоработки инструмента... в данном случае xharbour. |
| Как же не возникает, когда именно возникает именно такая же заморочка с клиппером. Дима же проверил. Да и я только что проверил. Насчет фокса мы когда-то выясняли, там имеется недокументированное неявное округление. О прочих инструментах говорить не буду.
| |
|
|
| постоянный участник
|
Пост N: 768
Зарегистрирован: 27.01.07
|
|
Отправлено: 07.06.12 18:48. Заголовок: Надо уже в Интел и А..
Надо уже в Интел и АМД телегу писАть. Чё-та их ФПУ хреново складыватьумножатьвычитатьделить умеют... :)
| |
|
|
| |
Пост N: 2397
Зарегистрирован: 17.05.05
|
|
Отправлено: 07.06.12 18:52. Заголовок: По поводу фокса можн..
По поводу фокса можно почитать тут
| |
|
|
| |
Пост N: 244
Зарегистрирован: 12.11.06
|
|
Отправлено: 08.06.12 08:48. Заголовок: Dima пишет: По пово..
Dima пишет: цитата: | По поводу фокса можно почитать тут |
| Доброе утро господа! Я не фоксист, не сишник, не и etc... Просто приходится зачастую использовать разный инструмент для решения конкретных задач. Все задачи связаны с бизнес расчетами и как следствие математика является основным нюансом на который обращают внимание пользователи. Как уже отмечал... не пытаюсь очень вникнуть во внутреннию топологию систем разработки. Все проблемки выявляют пользователи (по скромной оценке около 1000 человек) и ставят меня в известность... после чего пытаюсь найти источник проблемы и способ её исправления. Если пофилософствоать, то инструмент работы с базами или финансовой информацией должен в первую очередь обеспечивать стабильность работы с ней и "бухгалтерскую" точность (точность бухгалтерских расчетов). Если же в программе нужно также рассчитать траекторию полета спутника, то придется дописывать програмку на Си. Теперь по конкретным инструментам. Пока ещё в основном используется Clipper 5.01R + CTII и на его "методику" ориентируюсь в "сравнениях". На "вход" переделки под xharbour пошла программа отлаженная в течении 17 лет, в том числе отработаны "грабельки" данной версии клиппера, а тут оказывается не только есть "частичная" несовместимость языков, но и иные алгоритмы "математики". Лирика... на sql фоксисты рассуждают "куда податься с него" и получается, харбоур "тоже не вариант"? Хотя и имеет море предпосылок, что бы заменить все виды померших настольных СУБД. Что по "неумению считать" здесь озвучена идея "недокументированное неявное округление", наверное, что имело быть в пятом клиппере... а ведь это весьма разумно в бизнес приложениях. Под обсуждение арифметики как-то спрятались и другие "занятные" проблемки, озвученные выше: 1. Синтаксическая ошибка Wait "MAMA" * "PAPA" успешно пропускается компилятором, но программа вываливается по windows ошибке "too many recursive error handler calls" 2. Нелюбовь xHarbour к точке и запятой, в качестве переменной формы ввода.
| |
|
|
| Администратор
|
Пост N: 2369
Зарегистрирован: 23.05.05
|
|
Отправлено: 08.06.12 09:37. Заголовок: AndreyZh пишет: 1. ..
AndreyZh пишет: цитата: | 1. Синтаксическая ошибка Wait "MAMA" * "PAPA" успешно пропускается компилятором, но программа вываливается по windows ошибке "too many recursive error handler calls" |
| Что-то я не могу подтвердить такой результат. Компилятор и должен пропускать такую конструкцию, поскольку харбор язык с нестрогой типизацией. Это не синтаксическая ошибка, и клиппер это выражение тоже компилирует, как и харбор. А при его выполнении возникает ошибка "argument error", поскольку операция умножения для строк недопустима. "too many recursive error handler calls" - это уже результат работы обработчика ошибок. Стандартный обработчик ошибок xHarbour такое сообщение не дает. Возможно, у Вас он заменен своим. Смотрите свой обработчик ошибок.
| |
|
|
| постоянный участник
|
Пост N: 769
Зарегистрирован: 27.01.07
|
|
Отправлено: 08.06.12 09:45. Заголовок: AndreyZh пишет: то ..
AndreyZh пишет: цитата: | то инструмент работы с базами или финансовой информацией должен в первую очередь обеспечивать стабильность работы с ней и "бухгалтерскую" точность (точность бухгалтерских расчетов). |
| Откуда инструмент может знать, что программисту нужна "бухгалтерская" точность? Инструмент её обеспечивает, но только тогда, когда человек явно этого попросит.
| |
|
|
| Администратор
|
Пост N: 2370
Зарегистрирован: 23.05.05
|
|
Отправлено: 08.06.12 09:46. Заголовок: AndreyZh пишет: Что..
AndreyZh пишет: цитата: | Что по "неумению считать" здесь озвучена идея "недокументированное неявное округление", наверное, что имело быть в пятом клиппере... а ведь это весьма разумно в бизнес приложениях. |
| Ничего не понятно. Клиппер 5.01, который Вы используете, при операциях с double ведет себя точно так же, как и харбор. Никакого недокументированного округления там и в помине нет. Так зачем его вводить в харборе ? Тогда харбор будет вести себя не так, как клиппер. В ваших примерах клиппер и харбор дают одинаковый результат. Можете дать пример, в котором они ведут себя по разному ? С клиппером у вас дожны были быть такие же заморочки, как и с харбором. Но с клиппером почему-то это проблемы не создавало, а с харбором начало создавать ? Или просто на клиппер некому было пожаловаться ? :)
| |
|
|
| |
Пост N: 245
Зарегистрирован: 12.11.06
|
|
Отправлено: 08.06.12 11:21. Заголовок: Pasha пишет: Andrey..
Pasha пишет: цитата: | AndreyZh пишет: цитата: 1. Синтаксическая ошибка Wait "MAMA" * "PAPA" успешно пропускается компилятором, но программа вываливается по windows ошибке "too many recursive error handler calls" Что-то я не могу подтвердить такой результат. Компилятор и должен пропускать такую конструкцию, поскольку харбор язык с нестрогой типизацией. Это не синтаксическая ошибка, и клиппер это выражение тоже компилирует, как и харбор. А при его выполнении возникает ошибка "argument error", поскольку операция умножения для строк недопустима. "too many recursive error handler calls" - это уже результат работы обработчика ошибок. Стандартный обработчик ошибок xHarbour такое сообщение не дает. Возможно, у Вас он заменен своим. Смотрите свой обработчик ошибок. |
| Использую редакцию xHarbour 1.2.1 rev 6633... по обработчикам ошибок не пугайте такими словами (шутка). Ругается не харб, а судя по win окнам сами винды... Смотрите:
| |
|
|
| постоянный участник
|
Пост N: 770
Зарегистрирован: 27.01.07
|
|
Отправлено: 08.06.12 11:25. Заголовок: AndreyZh пишет: Руг..
AndreyZh пишет: цитата: | Ругается не харб, а судя по win окнам сами винды... |
| Нет, это не винда, а именно хХ. Обработчик ошибок зациклился на вызовах самого себя.
| |
|
|
| |
Пост N: 246
Зарегистрирован: 12.11.06
|
|
Отправлено: 08.06.12 11:33. Заголовок: PSP пишет: Откуда и..
PSP пишет: цитата: | Откуда инструмент может знать, что программисту нужна "бухгалтерская" точность? Инструмент её обеспечивает, но только тогда, когда человек явно этого попросит. |
| А что... какой результат можно попросить от операции 12.2 - 4.4 - 7.8? Теперь... от куда данные цифры. Есть операция распределения товаров накладной по нескольким складам (отделам магазина). В данном случае пришло 12.2 кг. товара, где в первый отдел нужно определить 4.4 кг, а во второй 7.8. Бедный оператор соглашается с числом 7.8, а прога в ответ не могу.... блок программы уже с извращениями (исправлениями): nMax := qtyAll fSwopen(21,0,3,79,cOther,2) DO WHIL !Eof() .AND. codInv==cInv // Читаем распределение по конкретному складу и товару. cCodStores := Spac(2) nQty := nMax @ 1,1 SAY WARES->name+" Осталось распред."+Str(nMax,10,3) @2,1 SAY "Распределить на склад:" GET cCodStores VALI Eval(bCodStores,cCodStores) .AND. Eval({||DevPos(2,28),DevOut(HB_STORE->shotName,cOther),TRUE}) @2,56 SAY "Количество:" GET nQty PICT "9999999.999" VALI lValid({||nQty>=0.AND.nQty<=nMax+0.000001},"Неверное кол-во. Отрицательно или слишком большое!") .AND. zlWar(DETALREC->codWares,nQty) READ IF LastKey()==K_ESC lBreak := TRUE; EXIT ENDI /* Запоминаем данные в массиве и меняем настройки. Склад может повторится, в этом случае добавляем количество в туже строку */ lArr := TRUE FOR nI := 1 TO Len(aArr) IF aArr[nI,1]==DETALREC->codWares.AND.aArr[nI,2]==cCodStores lArr := FALSE; EXIT ENDI NEXT nI IF lArr // Новый товар и склад. Aadd(aArr,{DETALREC->codWares,cCodStores,nQty,DETALREC->sales,DETALREC->tax_n,DETALREC->tax_s}) ELSE // Имеется строка в массиве. aArr[nI,3] += nQty ENDI nMax -= nQty // Еще не весь товар текущего наименования распределили. IF nMax > 0 THEN LOOP DbSkip() nMax := qtyAll ENDD А заодно отвечаю на: Pasha пишет: цитата: | С клиппером у вас дожны были быть такие же заморочки, как и с харбором. Но с клиппером почему-то это проблемы не создавало, а с харбором начало создавать ? Или просто на клиппер некому было пожаловаться ? :) |
| Этот блок использовался без изменения уже больше 20 лет... еще и системы не было... а операция "распределения" производится (провожу ежегодный анализ) более 50 000 раз по всем клиентам (или перебирают больше 200 000 комплектов цифр ежегодно)... была бы проблема - давно бы наткнулся. На xHarb она поперла в виде звонков ежедневно, как начал переводить розничные магазины.
| |
|
|
| постоянный участник
|
Пост N: 771
Зарегистрирован: 27.01.07
|
|
Отправлено: 08.06.12 12:25. Заголовок: AndreyZh пишет: А ч..
AndreyZh пишет: цитата: | А что... какой результат можно попросить от операции 12.2 - 4.4 - 7.8? |
| _SET_DECIMALS в какое значение установлен? Может поменьше сделать, а? Ты уж определись, какая точность тебе нужна. Не думаю, что при расчете масс, сумм, количеств нужна точность в 10 знаков.
| |
|
|
| |
Пост N: 125
Зарегистрирован: 10.07.07
|
|
Отправлено: 08.06.12 12:58. Заголовок: Не прошел проверку и..
Не прошел проверку и Exel http://shot.qip.ru/008CE3-1CkKxIa82/ Однако результат напоминает тот о котором Сыроежка пишет: PSP пишет: цитата: | Откуда инструмент может знать, что программисту нужна "бухгалтерская" точность? Инструмент её обеспечивает, но только тогда, когда человек явно этого попросит. |
| Прав PSP, однако
| |
|
|
| |
Пост N: 247
Зарегистрирован: 12.11.06
|
|
Отправлено: 08.06.12 13:55. Заголовок: ... я не просил у фо..
... я не просил у форума только новых сообщений... по памяти на совет по decimal отвечаю, что сильно в тему не вникал, но в инструции "Note that the command affects only the display and not the accuracy of calculations with numeric values", т.е. эта установка не влияет на точность счета. Хотя на самом деле всё более чудастее!!! В принципе по "схожей" причине не было мыслей по неприятию точки и запятой при печати... Приведу очень занятную картинку, но в начале отмечу, что если в тестовой программе на клиппер написать выражение ? Str( (12.2 - 4.4 - 7.8)*10000000,15,8) то увидем также отличное от нуля выражение округленное до формата str. В реальноых же программах картина радикально меняется - всё на картинке.
| |
|
|
| постоянный участник
|
Пост N: 772
Зарегистрирован: 27.01.07
|
|
Отправлено: 08.06.12 14:01. Заголовок: AndreyZh пишет: но ..
AndreyZh пишет: цитата: | но в инструции "Note that the command affects only the display and not the accuracy of calculations with numeric values", т.е. эта установка не влияет на точность счета. |
| Да, согласен. Тут я ошибся. Тогда Round и все дела...
| |
|
|
| |
Пост N: 248
Зарегистрирован: 12.11.06
|
|
Отправлено: 08.06.12 14:14. Заголовок: PSP пишет: Да, согл..
PSP пишет: цитата: | Да, согласен. Тут я ошибся. Тогда Round и все дела... |
| На это уже ответил: колебания могут быть, как положительными, так и отрицательными и не везде идет сравнение с нулем. Для "нуля" наиболее правильная проверка через Empty(nnn).
| |
|
|
| |
Пост N: 2398
Зарегистрирован: 17.05.05
|
|
Отправлено: 08.06.12 14:34. Заголовок: AndreyZh Не пойму с..
AndreyZh Не пойму совсем о чем спорим ;) Ведь очевидно же что полученный результат нужно округлять , иначе будут периодически лезть вот такие вот "глюки" в программе. Должен признать что и сам (очень давно правда) в своих программах не округлял результат и соответственно лезли похожие глюки. На скрине идет работа с килограммами и граммами , ну так ясное дело что округлять нужно результаты до 3 знаков после запятой , иначе пользователи Ваc заклюют
| |
|
|
| Администратор
|
Пост N: 2371
Зарегистрирован: 23.05.05
|
|
Отправлено: 08.06.12 14:49. Заголовок: AndreyZh пишет: Это..
AndreyZh пишет: цитата: | Этот блок использовался без изменения уже больше 20 лет... еще и системы не было... а операция "распределения" производится (провожу ежегодный анализ) более 50 000 раз по всем клиентам (или перебирают больше 200 000 комплектов цифр ежегодно)... была бы проблема - давно бы наткнулся. На xHarb она поперла в виде звонков ежедневно, как начал переводить розничные магазины. |
| Это все лирика. Попробуйте привести пример разного поведения клиппера и харбора с вещественными числами aka double ieee 754. С 12.2 - 4.4 - 7.8 поведение одинаковое. Вам же каждый день идут звонки от клиентов, то есть материала для проверки более чем достаточно. Попробуйте найти пример, где клиппер дает равенство нулю, а харбор - неравенство. Иначе говорить не о чем. Только сразу говорю - такого примера Вы не найдете, так как. fpu и для клиппера, и для харбора работает одинаково.
| |
|
|
| Администратор
|
Пост N: 2372
Зарегистрирован: 23.05.05
|
|
Отправлено: 08.06.12 14:56. Заголовок: Я для проверки на ра..
Я для проверки на равенство использую такую функцию: #pragma BEGINDUMP #include "hbapi.h" #include "math.h" HB_FUNC( EQU ) { double d1 = hb_parnd( 1 ); double d2 = hb_parnd( 2 ); hb_retl( fabs( d1 - d2 ) < 0.005 ); } #pragma ENDDUMP
| |
|
|
| |
Пост N: 249
Зарегистрирован: 12.11.06
|
|
Отправлено: 08.06.12 15:19. Заголовок: Да мы как-бы ни о че..
Да мы как-бы ни о чем не спорим... просто обсуждаем возможные проблемы и пути их разрешения... появляются довольно много дельных советов полезных, как для меня, так и других разработчиков на харборе. Хотя есть проблемки, но в чем то не очевидные: вернёмся к примеру с "округлением"... и играясь на конкретных числах 12.2/4.4/7.8 - на них наткнулись пользователи, но не факт, что операции с другим набором чисел будет приводить к схожим результатам... тест для других операций обсуждался на первой страницы. "Очередная" заморочка (или непонятка) выявилась в процессе тестов, которые вынужден был провести: 1. Если просто проверить результат выражения wait Str( (12.2 - 4.4 - 7.8)*10000000,15,8), то и Clipper 5.01 и xHarbour дают идентичные результаты - число отличное от нуля. 2. Вводим данные значения в конкретной программе, собранной под Clipper и xHarbour - пока вынужден поддерживать совместимость исходников и получаем уже разные результаты - показаны на картинке. Что меняется??? Может быть у меня код "кривой"... но ведь всё время успешно работал, не вызывая нареканий. Повторю его снова: DO WHIL !Eof() .AND. codInv==cInv // Читаем распределение по конкретному складу и товару. cCodStores := Spac(2) nQty := nMax **** Здесь различно срабатывает условие проверки nQty>=0.AND.nQty<=nMax На картинке просто вывел результат после второй итерации, где видно, что программа на клиппере даёт НОЛЬ @ 1,1 SAY WARES->name+" Осталось распред."+Str(nMax,10,3) @2,1 SAY "Распределить на склад:" GET cCodStores VALI Eval(bCodStores,cCodStores) .AND. Eval({||DevPos(2,28),DevOut(HB_STORE->shotName,cOther),TRUE}) @2,56 SAY "Количество:" GET nQty PICT "9999999.999" VALI lValid({||nQty>=0.AND.nQty<=nMax},"Неверное кол-во. Отрицательно или слишком большое!") .AND. zlWar(DETALREC->codWares,nQty) READ IF LastKey()==K_ESC lBreak := TRUE; EXIT ENDI /* Запоминаем данные в массиве и меняем настройки. Склад может повторится, в этом случае добавляем количество в туже строку */ lArr := TRUE FOR nI := 1 TO Len(aArr) IF aArr[nI,1]==DETALREC->codWares.AND.aArr[nI,2]==cCodStores lArr := FALSE; EXIT ENDI NEXT nI IF lArr // Новый товар и склад. Aadd(aArr,{DETALREC->codWares,cCodStores,nQty,DETALREC->sales,DETALREC->tax_n,DETALREC->tax_s}) ELSE // Имеется строка в массиве. aArr[nI,3] += nQty ENDI nMax -= nQty // Еще не весь товар текущего наименования распределили. IF nMax > 0 THEN LOOP DbSkip() nMax := qtyAll ENDD
| |
|
|
| Администратор
|
Пост N: 2373
Зарегистрирован: 23.05.05
|
|
Отправлено: 08.06.12 15:32. Заголовок: AndreyZh пишет: Что..
AndreyZh пишет: цитата: | Что меняется??? Может быть у меня код "кривой"... но ведь всё время успешно работал, не вызывая нареканий. Повторю его снова: |
| Код может быть и не кривой, только выполнить его вне вашего окружения невозможно, и соответвенно прогнать на клиппере и харборе тоже невозможно Мне рассказать, что такое самодостаточный пример ? Без такого примера анализ этого кода невозможен. Ведь код надо собрать двумя компиляторами (клиппером и харбором), запустить его, так чтобы он запустился, что-то ввести, получить результат и его проанализировать. В таком виде ничего этого сделать нельзя.
| |
|
|
| Администратор
|
Пост N: 2374
Зарегистрирован: 23.05.05
|
|
Отправлено: 08.06.12 15:43. Заголовок: Немного модифицирова..
Немного модифицировал свой старый тест: func main Local n1 := 10000.00 Local n2, n3, i Local i1 := 0 Local i2 := 0 dbCreate('fpu', {{'D1', 'N', 12, 2}, {'D2', 'N', 12, 2}}) use fpu new for i := 1 to 10000000 n2 := Round(n1+i*0.01, 2) n3 := Round(n1+n1+i*0.01, 2) if n1-(n3-n2) == 0.00 i1 ++ else fpu->(dbAppend()) fpu->D1 := n2 fpu->D2 := n3 i2 ++ endif next qout(i1, i2) return nil и прогнал его на клиппере и харборе. Результат получился идентичный. То есть, если различие между компиляторами и есть, то это не результат выполнения арифметических операций. А без самодостаточного примера его выявить нельзя. Так дайте пример. Что его делать то ? Там того кода всего ничего. Выбросьте все лишнее, дайте в конце концов дбф-файл, откуда выбираются данные, напишите, что надо вводить в get Без этого ничего сделать нельзя.
| |
|
|
| |
Пост N: 250
Зарегистрирован: 12.11.06
|
|
Отправлено: 08.06.12 16:07. Заголовок: Pasha пишет: Код мо..
Pasha пишет: цитата: | Код может быть и не кривой, только выполнить его вне вашего окружения невозможно, и соответвенно прогнать на клиппере и харборе тоже невозможно Мне рассказать, что такое самодостаточный пример ? |
| Куда же проще? К тому же любопытно, как может влиять окружение? Что же еще упростил! Варианты на клиппер даёт 0, на харб нет: nmax := 12.2 DO WHIL .t. nQty := nMax @ 1,1 SAY " Осталось распред."+Str(nMax,10,3) @1,56 SAY "Количество:" GET nQty PICT "9999999.999" READ IF LastKey()==K_ESC EXIT ENDI @ 3,1 say str((nqty-nmax)*100000000,19,9) nMax -= nQty IF nMax > 0 LOOP endi ENDD wait Пардон - вводите волшебные числа: Сначала 4.4, затем 7.8... на другом наборе результаты могут разичаться P.S. Надеюсь для пользы развития Харбора "стараюсь".... а не просто потрындеть...
| |
|
|
| |
Пост N: 500
Зарегистрирован: 11.06.10
|
|
Отправлено: 08.06.12 16:18. Заголовок: Тест на harbour (175..
Тест на harbour (17592) 0.000000089 clip*er5.3 0.000000089
| |
|
|
| |
Пост N: 251
Зарегистрирован: 12.11.06
|
|
Отправлено: 08.06.12 16:30. Заголовок: AlexMyr пишет: clip..
AlexMyr пишет: Прога на 5.01R
| |
|
|
| |
Пост N: 2399
Зарегистрирован: 17.05.05
|
|
Отправлено: 08.06.12 16:32. Заголовок: AlexMyr пишет: Тест..
AlexMyr пишет: цитата: | Тест на harbour (17592) 0.000000089 clip*er5.3 0.000000089 |
| И у меня тоже самое + Xharbour выдал тот же результат ЗЫ Clipper 5.2e у меня
| |
|
|
| |
Пост N: 2400
Зарегистрирован: 17.05.05
|
|
Отправлено: 08.06.12 16:34. Заголовок: Dima пишет: Прога н..
AndreyZh пишет: в нем были глючки , хорошо это помню когда переводил прогу с Clipper 5.01 на 5.2e Нашел в архиве Clipper (R) Version 5.01 Copyright (c) Nantucket Corp 1985-1991. All Rights Reserved. Microsoft C Floating Point Support Routines Copyright (c) Microsoft Corp 1984-1987. All Rights Reserved. Результат тот же
| |
|
|
| |
Пост N: 2401
Зарегистрирован: 17.05.05
|
|
Отправлено: 08.06.12 16:48. Заголовок: AndreyZh А какой р..
AndreyZh А какой результат выдаст такой тест на Вашей машинке ? IF 4195835.129876 - ((4195835.129876 / 3145727.129876) * 3145727.129876) #0 ? "BAD" ELSE ? "OK" ENDIF
| |
|
|
| |
Пост N: 501
Зарегистрирован: 11.06.10
|
|
Отправлено: 08.06.12 17:06. Заголовок: И clip* и harbour - ..
И clip* и harbour - OK
| |
|
|
| |
Не зарегистрирован
Зарегистрирован: 01.01.70
|
|
Отправлено: 08.06.12 19:42. Заголовок: округление в GET
Цитата nQty := nMax @ 1,1 SAY " Осталось распред."+Str(nMax,10,3) @1,56 SAY "Количество:" GET nQty PICT "9999999.999" возможно, часть Вашей проблемы в этом сегменте кода. Видимое значение в поле ввода округлено, однако если не менять значение в поле ввода, а просто подтвердить клавишей <Enter> будет передано неокругленное значение. Если просто тупо перебить в поле ввода видимые цифры в общем случае значение переменной ввода после GET будет другим.
| |
|
|
| Администратор
|
Пост N: 2375
Зарегистрирован: 23.05.05
|
|
Отправлено: 08.06.12 20:02. Заголовок: petr707 пишет: в об..
petr707 пишет: цитата: | в общем случае значение переменной ввода после GET будет другим. |
| Именно так Предлагаю уважаемой публике выполнить такой тест на разных версиях клиппера и харбора: local n1 := 12.2 - 7.8 local n2 := 4.4 @ 1,1 say if(n2==n1, 'T', 'F') // ежу понятно, что на всех версиях клиппера и харбора результат будет F @ 2,1 say 'Ввод' get n1 picture '9999999.999' read // ничего вводить не надо, просто нажать enter @ 3,1 say if(n2==n1, 'T', 'F') а после read возможны различия: на харборе по-прежнему будет F, а на клиппере - скажите У меня возникло впечатление, что по read в клиппере содержимое переменной n1 будет округлено. Только в каких версиях ? От 5.01 до 5.3 Так же интересно прогнать этот тест без picture
| |
|
|
| |
Пост N: 2402
Зарегистрирован: 17.05.05
|
|
Отправлено: 08.06.12 21:10. Заголовок: Pasha 5.01 .F. 5.2e..
Pasha 5.01 .F. 5.2e .F. без picture так же
| |
|
|
| Администратор
|
Пост N: 2376
Зарегистрирован: 23.05.05
|
|
Отправлено: 08.06.12 21:25. Заголовок: Dima пишет: 5.01 .F..
Dima пишет: цитата: | 5.01 .F. 5.2e .F. без picture так же |
| Да у меня тоже самое. Со стандартной getsys. Но в рабочих программах я использую свою getsys, и она дает результат T Возможно, у Андрея Жукова тоже своя нестандартная getsys, которая меняет значение переменной, даже если она не изменяется.
| |
|
|
| |
Пост N: 2403
Зарегистрирован: 17.05.05
|
|
Отправлено: 08.06.12 21:28. Заголовок: Pasha пишет: Возмож..
Pasha пишет: цитата: | Возможно, у Андрея Жукова тоже своя нестандартная getsys |
| и мне так кажется. AndreyZh пишет: цитата: | 2. Нелюбовь xHarbour к точке и запятой, в качестве переменной формы ввода. |
| И тут похоже в этом дело. Ждем Андрея.
| |
|
|
| Администратор
|
Пост N: 2377
Зарегистрирован: 23.05.05
|
|
Отправлено: 08.06.12 21:59. Заголовок: Все-таки ситуация др..
Все-таки ситуация другая, getsys ни при чем. Во время редакции значения 4.4 переменная содержит не 4.4, а результат 12.2-7.8, то есть 4.4+eps Если в клиппере нажать просто enter, то значение останется 4.4+eps, и сравниваться будет сама с собой, и сравнение сработает Если ввести 4.4, то затем сравнение 4.4 с 4.4+eps не сработает В xHarbour имеется побочное действие: если не вводить 4.4, а нажать enter, то значение переменной все равно изменится с 4.4+eps на 4.4, и затем сравнение 4.4 с 4.4+eps не сработает в Harbour этого побочного действия нет, и он работает так же, как и клиппер
| |
|
|
| Администратор
|
Пост N: 2378
Зарегистрирован: 23.05.05
|
|
Отправлено: 08.06.12 22:04. Заголовок: Во всяком случае при..
Во всяком случае причина понятна. Это не разное выполнение арифметических операций, никакое не неправильное вычитание. Причина как раз в том, что в xHarbour имеется недокументированное свойство округлять при вводе в get значение переменной. А округление как раз и не нужно, так как после get оно приводит к неравенству при сравнении с округленного и неокругленного значения.
| |
|
|
| постоянный участник
|
Пост N: 773
Зарегистрирован: 27.01.07
|
|
Отправлено: 09.06.12 08:33. Заголовок: Да уж... Вот тебе и ..
Да уж... Вот тебе и xHarbour...
| |
|
|
| |
Пост N: 252
Зарегистрирован: 12.11.06
|
|
Отправлено: 09.06.12 08:48. Заголовок: Громадное спасибо за..
Громадное спасибо за весьма конструктивное обсуждение!!! Причины возможно ясны... только хотелось бы сейчас при наличии ПК проверить все высказанные гипотезы и тесты... а затем, если Вы захотите попробуем разобраться с нелюбовью xHarbour к точке и запятой - конструкции довольно громоздкие, т.е. боюсь, что самодостаточный пример сложно будет придумать, но... если сможете быть любезны скачать дистрибутив (очень легкая сейчас установка), содержащий и исходники, как проги на клиппер, так и на Харб (правда 35 метров) ДИСТРИБУТИВ, то может быть легче будет меня понять... в принципе дистрибутив содержит и батники для сборок, т.е. несложно пересобрать и под любую версию клиппера Сейчас, с Вашего позволения я поиграюсь с высказанными идеями и вернусь.....
| |
|
|
| постоянный участник
|
Пост N: 774
Зарегистрирован: 27.01.07
|
|
Отправлено: 09.06.12 08:50. Заголовок: AndreyZh, проверь, з..
AndreyZh, проверь, заодно, свои задачи на Harbour.
| |
|
|
| |
Пост N: 253
Зарегистрирован: 12.11.06
|
|
Отправлено: 09.06.12 11:15. Заголовок: PSP пишет: AndreyZh..
PSP пишет: цитата: | AndreyZh, проверь, заодно, свои задачи на Harbour. |
| Млин!!! - Советчик... Основное время потратил, что бы установить и как-то научиться делать на нем компиляцию... Harbour 2.0.0 Rev 13372 Отмечу сразу - идентично Clipper 5.01R Мне понравилось предположение по PICTURE (GET - у меня неизмененноы) и сразу решил его прокачать - да... здесь проблема, причем действительно у xHarbour. Чуть изменил тест и на первое поле вводил число ручками, а во втором просто нажимал Enter. В первом get результаты были нулевыми везде, а во втором Clipper&Harbour, если не менять значение, то получалось ноль, а в xHarbour ненулевое число. Различие только тут... все остальные числа идентичны. Использовал код: loca nmax loca nqty loca nq loca getlist:={} //****** ТЕСТЫ ХАРБА CLS nmax := 12.2 nQty := nQ := nMax @1,1 SAY "Количество:" GET nQty PICT "9999999.999" @2,1 SAY "Количество:" GET nQ PICT "9999999.999" READ @ 3,1 say str((nqty-nmax)*10000000000,19,9) @ 4,1 say str((nq-nmax) *10000000000,19,9) nmax := 12.2-4.4 nQty -= 4.4 nQ -= 4.4 @6,1 SAY "Количество:" GET nQty PICT "9999999.999" @7,1 SAY "Количество:" GET nQ PICT "9999999.999" READ @ 8,1 say str((nqty-nmax)*10000000000,19,9) @ 9,1 say str((nq-nmax) *10000000000,19,9) @10,1 say str((nmax-7.8) *10000000000,19,9) IF 4195835.129876 - ((4195835.129876 / 3145727.129876) * 3145727.129876) #0 ? "BAD" ELSE ? "OK" ENDIF wait //****** КОНЕЦ ТЕСТА Dima пишет: цитата: | А какой результат выдаст такой тест на Вашей машинке ? IF 4195835.129876 - ((4195835.129876 / 3145727.129876) * 3145727.129876) #0 ? "BAD" ELSE ? "OK" ENDIF |
| Все 3 системы (clipper 5.01r, xHarbour, Harbour) - OK Dima пишет: цитата: | А какой результат выдаст такой тест на Вашей машинке ? IF 4195835.129876 - ((4195835.129876 / 3145727.129876) * 3145727.129876) #0 ? "BAD" ELSE ? "OK" ENDIF |
|
Dima пишет: цитата: | Не пойму совсем о чем спорим ;) Ведь очевидно же что полученный результат нужно округлять , иначе будут периодически лезть вот такие вот "глюки" в программе. Должен признать что и сам (очень давно правда) в своих программах не округлял результат и соответственно лезли похожие глюки. На скрине идет работа с килограммами и граммами , ну так ясное дело что округлять нужно результаты до 3 знаков после запятой , иначе пользователи Ваc заклюют |
| Здесь, к сожалению не всё так просто... в реальности приходится прогибаться под набор требований: 1. Что бы считало, как 1ц... либо по логике бухов 2. Реальные оперативные суммы (по разным клиентам) от 1 руб до 1 000 000 000 и количества от 0.001 до 1 000 000 3. Приходится манипулировать весами (точность 3 знака), объемами (точность 5 знаков) и количествами в производстве (точность 6 знаков)... тут ещё и алкоголь (с плавающей точностью). Конечно... и уже увидел, что нужно перепахивать все расчеты - весьма неприятно, т.к. придется лезть в многочисленные отлаженные блоки и это ни к чему хорошему не приведёт!
| |
|
|
| постоянный участник
|
Пост N: 775
Зарегистрирован: 27.01.07
|
|
Отправлено: 09.06.12 12:35. Заголовок: AndreyZh пишет: Мли..
AndreyZh пишет: цитата: | Млин!!! - Советчик... Основное время потратил, что бы установить и как-то научиться делать на нем компиляцию... |
| А что ж так? В файле INSTALL есть вся информация.
| |
|
|
| |
Пост N: 254
Зарегистрирован: 12.11.06
|
|
Отправлено: 09.06.12 13:06. Заголовок: PSP пишет: что ж т..
PSP пишет: цитата: | что ж так? В файле INSTALL есть вся информация. |
| Кто же инструкции читает? Покажите мне такого человека?... но вообще говоря Харбор у меня не стоял, да и щупал его очень давно... К сожалению вынужден исчезнуть до 13 в места, где к счастью нет компьютеров... и даже телефон не ловит. Всем приятных праздников!
| |
|
|
| Администратор
|
Пост N: 2379
Зарегистрирован: 23.05.05
|
|
Отправлено: 09.06.12 14:36. Заголовок: AndreyZh пишет: Осн..
AndreyZh пишет: цитата: | Основное время потратил, что бы установить и как-то научиться делать на нем компиляцию... Harbour 2.0.0 Rev 13372 Отмечу сразу - идентично Clipper 5.01R |
| Уже почти год как вышел Harbour 3.0, и лучше использовать его. И для развития своей системы лучше ориентироваться на Harbour. Развитие xHarbour остановилось уже почти 4 года как, разработчики или перешли в команду Harbour, или занимаются другими делами. А Harbour как раз продолжает развиваться, и по этой причине несовместимостей с клиппером у него меньше. Хотя, конечно, в редких случаях могут быть неожиданные сюрпризы с совместимостью и в Harbour.
| |
|
|
| |
Пост N: 255
Зарегистрирован: 12.11.06
|
|
Отправлено: 13.06.12 12:02. Заголовок: Всем приятного "..
Всем приятного "понедельника"! Pasha пишет: цитата: | Уже почти год как вышел Harbour 3.0, и лучше использовать его. И для развития своей системы лучше ориентироваться на Harbour. Развитие xHarbour остановилось уже почти 4 года как, разработчики или перешли в команду Harbour, или занимаются другими делами. А Harbour как раз продолжает развиваться, и по этой причине несовместимостей с клиппером у него меньше. Хотя, конечно, в редких случаях могут быть неожиданные сюрпризы с совместимостью и в Harbour. |
| Желающих помочь разобраться с неприятием точки и запятой xHarbour нет? Ну и ладно нашел решение, хотя и без понимания его эффекта... если у кого так же будут глюки, но после read вставьте код типа: if lastkey() = 44 .or. lastkey() = 46 keyb chr(K_ENTER) inkey(0) endi Теперь для уважаемого Pasha - почему xharbour? Во первых прочтение инструкции Верченко Андрея (Andrey), где очень легко описывалось "вхождение" в данную систему разработки стимулировало попробовать её, а во вторых xHarbour, как прочитал на данном форуме лучше поддерживал оконные функции CT II. Менять уже более-менее отлаженную систему на "неизвестно что" пока не вижу смысла, да и глюки с вашей помощью получается обходить. Что касается "глобальной" переделки под графический интерфейс и с нормальной СУБД, то внимательно присмотрюсь к творчеству Филатова (miniGui) и Кресина (LetoDB) и очень надеюсь, что к тому моменту появится нечто стабильное и хоть как-то документированное ... и конечно Harbour.
| |
|
|
| Администратор
|
Пост N: 2381
Зарегистрирован: 23.05.05
|
|
Отправлено: 13.06.12 13:54. Заголовок: AndreyZh пишет: Жел..
AndreyZh пишет: цитата: | Желающих помочь разобраться с неприятием точки и запятой xHarbour нет? Ну и ладно нашел решение, хотя и без понимания его эффекта... если у кого так же будут глюки, но после read вставьте код типа: if lastkey() = 44 .or. lastkey() = 46 keyb chr(K_ENTER) inkey(0) endi |
| Этот код можно заменить одной строкой: SetLastKey( K_ENTER ) Заодно и проблема становится понятной. В клиппере и xHarbour после read наверное остается разное значение lastkey Можно попробовать сделать тесты. Как я понимаю, в односимвольную переменную вводится точка с запятой ? Вот и прогнать тест: local c := ' ' @ 1, 1 say 'Ввод' get c read ? lastkey() Я сейчас работаю под win64, так что клиппер и запустить то не могу, разве что под эмулятором Интересно, есть ли эта несовместимость в Harbour ?
| |
|
|
| Администратор
|
Пост N: 2382
Зарегистрирован: 23.05.05
|
|
Отправлено: 13.06.12 14:48. Заголовок: AndreyZh пишет: xHa..
AndreyZh пишет: цитата: | xHarbour, как прочитал на данном форуме лучше поддерживал оконные функции CT II |
| Откуда взялось это мнение, и когда оно было высказано, теперь наверное и не выяснить. Я сам оконные функции ct не использую, так что по поводу совместимости ничего не скажу. Могу рассказать историю создания этих функций. Она имеет польские корни. Изначально эти функции были сделаны как prg-модуль в xHarbour, автор - Adam Lubszczyk. Затем в xHarbour же они были переписаны на C-уровень, причем часть функциональности перенесена непосредственно в терминал-api, работа Henryk Olkowski. Затем в 2006-м, уже в Harbour, Przemek их полностью переписал. Позднее вариант Przemek'a был портирован в xHarbour. Таким образом, в олбеих продуктах сейчас присутствует одна и та же реализация оконных функций. Разница в том, что xHarbour перестал развиваться, в отличие от Harbour, так что думается, в Harbour они более проработаны, тем более их автор уже давно как в команде Harbour, а не xHarbour.
| |
|
|
| |
Пост N: 256
Зарегистрирован: 12.11.06
|
|
Отправлено: 13.06.12 15:50. Заголовок: Pasha пишет: Вот и ..
Pasha пишет: цитата: | Вот и прогнать тест: local c := ' ' @ 1, 1 say 'Ввод' get c read ? lastkey() |
| Во первых и клиппер и [x]Harbour возвращают ожидаемые key коды. Проблема: в тестовом примере, приведённом раннее все работает правильно и ожидаемо, а в реальном приложении приходится изголяться. Что по развивающемуся Harbour или стагнирующему xHarbour (хотя Patrick постоянно присылает релизы об успехах развития XHarbour) приведенный пример wait "mama" * "papa" обе системы, хоть и по разному но "необрабатывают" на уровне компилятора: xHarbour вызывает переполнение стека, как пояснили выше Harbour выполняя wait далее вываливается по ошибке выполнения, т.е. "те же balls только вид сбоку" - ИМХО
| |
|
|
| Администратор
|
Пост N: 2383
Зарегистрирован: 23.05.05
|
|
Отправлено: 13.06.12 16:13. Заголовок: AndreyZh пишет: при..
AndreyZh пишет: цитата: | приведенный пример wait "mama" * "papa" обе системы, хоть и по разному но "необрабатывают" на уровне компилятора: |
| Не только оба харбора, но и все 5-е клипперы, от 5.01 до 5.3 точно также "необрабатывают" этот оператор на уровне компилятора, поскольку этот оператор допустим с точки зрения синтаксиса этих языков. Ну а по поводу ошибки переполнения стека, так она возникает в модуле errorsys. При выполнении "mama" * "papa" возникает ошибка argument error, управление передается обработчику ошибок, в нем во время обработки этой ошибки тоже возникает ошибка, управление опять передается этому же обработчику, ну и так далее до переполнения стека. Прчем в стандартном обработчике ошибок xHarbour ошибки в errorsys не возникает, Возможно, вы переопределили этот обработчик на свой, в котором и возникает ошибка.
| |
|
|
| |
Пост N: 257
Зарегистрирован: 12.11.06
|
|
Отправлено: 13.06.12 16:21. Заголовок: Pasha пишет: Прчем ..
Pasha пишет: цитата: | Прчем в стандартном обработчике ошибок xHarbour ошибки в errorsys не возникает, Возможно, вы переопределили этот обработчик на свой, в котором и возникает ошибка |
| Ничего не менял...
| |
|
|
| Администратор
|
Пост N: 2384
Зарегистрирован: 23.05.05
|
|
Отправлено: 13.06.12 18:51. Заголовок: AndreyZh пишет: Жел..
AndreyZh пишет: цитата: | Желающих помочь разобраться с неприятием точки и запятой xHarbour нет? |
| Так в чем состоит различие в поведении клиппера и хХарбора ? Собрать и запустить ваш пример возможности нет никакой. Можете описать словами ? Какие переменные вводятся ? Что именно вводится ? Различие проявляется в процессе ввода ? Вводимые переменные получают разные значения ? После ввода анализируется lastkey, и управление передается на другую ветку ? Что-то другое ?
| |
|
|
| |
Пост N: 258
Зарегистрирован: 12.11.06
|
|
Отправлено: 13.06.12 19:46. Заголовок: Pasha пишет: Так в ..
Pasha пишет: цитата: | Так в чем состоит различие в поведении клиппера и хХарбора ? |
| Различий нет, но при вводе (. или ,) в последний запрос прога на xHarb "начинает жить своей жизнью", если любой другой символ (/*-~ и etc), то она сохраняет его для дальнейшего использования. Тестовый пример, иллюстрирующий подход, но где и xHarb работает конкретно приведён выше. Если Вас не затруднит, то все подробно описано со второй страницы. Pasha пишет: цитата: | Собрать и запустить ваш пример возможности нет никакой |
| Почему? Всё нормально работает и на 64 разрядной Win All... Установка сделана "для блондинок"... проблемка лишь скачать 35 mb дистрибутива (ссылка есть выше) и ничего собирать не нужно... в нём и clipper и xharbour программы с исходниками, а мои попытки разместить набор связанных исходников оказался почти безуспешным - форум преобразует текста в козябяки
| |
|
|
| Администратор
|
Пост N: 2385
Зарегистрирован: 23.05.05
|
|
Отправлено: 13.06.12 20:26. Заголовок: AndreyZh пишет: Раз..
AndreyZh пишет: цитата: | Различий нет, но при вводе (. или ,) в последний запрос прога на xHarb "начинает жить своей жизнью", если любой другой символ (/*-~ и etc), то она сохраняет его для дальнейшего использования. Тестовый пример, иллюстрирующий подход, но где и xHarb работает конкретно приведён выше. Если Вас не затруднит, то все подробно описано со второй страницы. |
| Что такое начинает жить своей жизнью ? Ввод не завершается ? Переменные получают какие-то другие значения, не те, что введены ? После ввода что-то анализируется, например lastkey, и управление передается на другую ветку ? При чем тут 64 бит ? Это клиппер на них не работает. Вы мне предлагаете сравнивать поведение 2-х вариантов вашей системы. Я должен как-то запустить эти 2 варианта, один из них 16-битный, зайти не знаю куда, вводить не знаю что, увидеть в чем-то разницу, потом копаться в мегабайтах сырцов ? Дайте самодостаточный пример. Или хотя бы опишите проблему. Когда я много лет назад адаптировал свои программы под харбор, и не мог сам решить какую-то проблему, я поступал не так. Всю эту предварительную работу проделывал сам, и таки делал этот самодостаточный пример, и давал его тому, кто мог решить эту проблему. Это всегда срабатывало. Не помню, чтобы какая-то существенная проблема оставалась нерешенной.
| |
|
|
| |
Пост N: 259
Зарегистрирован: 12.11.06
|
|
Отправлено: 13.06.12 20:51. Заголовок: Уважаемый Pasha! Я ..
Уважаемый Pasha! Я не прошу Вас решить мою проблему, тем более, что её через опу сам порешал. Просто предположил, что нахождение источника её возникновения в интересах сообщества. Вся она досконально описана на 2, 3 страницы с описанием структуры вызовов и приведением связанных выжимок из исходного кода. Самодостаточный пример не придумал, а упрощенный вариант алгоритма давал "правильные" и ожидаемые результаты. Почему предложил использовать для выяснения проблемы дистрибутив? Там бы Вы смогли бы наглядно увидеть глюк программы на xHarbour и четко его отследить по прилагаемым исходникам. Данная проблема возникала во всех отчетах, где в качестве последнего значения вводится единственный символ и он точка или запятая.
| |
|
|
| постоянный участник
|
Пост N: 2234
Зарегистрирован: 12.09.06
|
|
Отправлено: 13.06.12 21:18. Заголовок: AndreyZh пишет: Что..
AndreyZh пишет: цитата: | Что касается "глобальной" переделки под графический интерфейс и с нормальной СУБД, то внимательно присмотрюсь к творчеству Филатова (miniGui) и Кресина (LetoDB) и очень надеюсь, что к тому моменту появится нечто стабильное и хоть как-то документированное ... и конечно Harbour. |
| Я уже с нового года ковыряю МиниГуи... Успехи так себе, застрял на главном меню программы - стартере для терминалки.... Скин 1 http://shot.qip.ru/003YZC-12Q3rKUxL/ Скин 2 http://shot.qip.ru/003YZC-32Q3rKUxM/ Скин 3 http://shot.qip.ru/003YZC-22Q3rKUxN/ Думаю потом все таки нужно переходить на Harbour + Qt Посмотрел на исходники БАРС-Бюджет http://www.bars-open.ru/ (сборка для 3-х платформ: Linux;Mac OS;MS Windows) Много чего интересного в нем.
| |
|
|
| |
Пост N: 2410
Зарегистрирован: 17.05.05
|
|
Отправлено: 13.06.12 21:31. Заголовок: Andrey пишет: Я уже..
Andrey пишет: цитата: | Я уже с нового года ковыряю МиниГуи |
| Учел для разных разрешений экрана ? ;) И потом к чему твое сообщение тут ?
| |
|
|
| постоянный участник
|
Пост N: 2235
Зарегистрирован: 12.09.06
|
|
Отправлено: 13.06.12 22:44. Заголовок: Dima пишет: Учел дл..
Dima пишет: цитата: | Учел для разных разрешений экрана ? ;) |
| Да нет. Пока только 800*600..... Dima пишет: цитата: | И потом к чему твое сообщение тут ? |
| Из-за этого: Что касается "глобальной" переделки под графический интерфейс и с нормальной СУБД, то внимательно присмотрюсь к творчеству Филатова (miniGui) Работает МиниГуи, и под Ubuntu 11.10, Wine 1.36. Нечего присматриваться, работать надо...
| |
|
|
| |
Пост N: 260
Зарегистрирован: 12.11.06
|
|
Отправлено: 14.06.12 13:09. Заголовок: Andrey пишет: Посмо..
Andrey пишет: цитата: | Посмотрел на исходники БАРС-Бюджет http://www.bars-open.ru/ (сборка для 3-х платформ: Linux;Mac OS;MS Windows) Много чего интересного в нем. |
| Извините, если что! Но Вы в курсе, что в "Барсе" непонятно что реализовано на Харбор... по крайней мере весь интерфейс, по их утверждению сделан на C++ & QT
| |
|
|
| Администратор
|
Пост N: 2409
Зарегистрирован: 23.05.05
|
|
Отправлено: 20.06.12 13:40. Заголовок: Сделал для примера м..
Сделал для примера маленький класс Money, в котором исключены ошибки округления при операциях с плавающей точкой, поскольку значения в обьекте класса хранятся в целом формате. К значению переменной класса надо обращаться через метод value: oMoney:value Для создания переменной надо вызвать метод new: local m1 := Money():new( 12.2 ) Переменные класса Money поддерживают арифметические операции, операции сравнения и операцию присваивания. Думаю, этот класс можно будет выложить в harbour\tests Ссылка: http://zalil.ru/33476877
| |
|
|
| |
Пост N: 261
Зарегистрирован: 12.11.06
|
|
Отправлено: 20.06.12 15:01. Заголовок: Спасибо Pasha за при..
Спасибо Pasha за пример создания собственного класса Очень интересно для освоения работы с классами, хотя и здесь глобальная "беда" проектов, связанных с Harbour - полное отсутствие документации и документирования, но я разобрался Увы... пока "для меня" это решение пока не подходит - использую единный код для программы на Clipper 5.01 + CT II (там еще нет механизмов создания своих классов) и xHarbour. Для себя определил следующий механизм: #define _ZRND(x) => Round(x,9) ..... После операции/чтения Get записать/переопределить nVal := _ZDND(nVal) что в общем тоже приводит к корректным результатам... P.S. А по нелюбви к точке и запятой идей не появилось?
| |
|
|
| |
Пост N: 262
Зарегистрирован: 12.11.06
|
|
Отправлено: 20.06.12 15:08. Заголовок: ... в догонку ... по..
... в догонку ... по теме документирования... Вроде бы всем пользователям в реале объясняю новые вещи в своей системе, отвечаю на "мыло" и звонки, но ВСЕ требуют какую нибудь бумажку для самостоятельного чтения и без неё ну ни как!... пример ежемесячной писульки список модификаций программы При взаимодействии с другими разработчиками по связанным проектам те так же требуют (и дают) четкую и однозначную "ксиву" - если интересно покажу "регламент от программистов Лукойл".
| |
|
|
| постоянный участник
|
Пост N: 327
Зарегистрирован: 06.02.07
|
|
Отправлено: 20.06.12 15:52. Заголовок: Про "список моди..
Про "список модификаций" - у нас это рутина: не наобъясняешься же 200-300 больничкам, что там изменилось. Т.ч. кроме краткого описания (см., например, тут), есть еще отдельным DOC-файликом (чтобы можно было "распечатать и в папочку подшить" - ибо бюрократия вещь хорошая и бессмертна :) ) (например, вот такой стандартный текстик). Снимает 90% "дурацких" вопросов - хотя оставшиеся 10% тоже хорошо взрывают мозг разработчика :). Извиняюсь за оффтоп в ветке, AndreyZh - но сам нарвался :)
| |
|
|
| |
Пост N: 263
Зарегистрирован: 12.11.06
|
|
Отправлено: 20.06.12 16:19. Заголовок: gustow пишет: Про &..
gustow пишет: цитата: | Про "список модификаций" - у нас это рутина: не наобъясняешься же 200-300 больничкам, что там изменилось |
| По то же и толкую... Что бы сложным продуктом пользовались нужна доходчивая инструкция, понятные статьи и желательно коллективный разум на форуме. gustow пишет: цитата: | Т.ч. кроме краткого описания (см., например, тут), есть еще отдельным DOC-файликом |
| Да это ссылка для "читателей" сайтов, а так конечно (и это можно увидеть по страничке), что сделана она из word документа. Кроме таких описаловов имеются детальные статейки по реализации и нюансам сложным бизнес технологий и etc... Ну всё это просто на тему - нужны хоть какие-то описания!
| |
|
|
| постоянный участник
|
Пост N: 328
Зарегистрирован: 06.02.07
|
|
Отправлено: 21.06.12 07:46. Заголовок: Честно говоря, не со..
Честно говоря, не совсем понял (жара, туп с утра :) ). AndreyZh пишет: цитата: | нужны хоть какие-то описания! |
|
- это про "описания работы с Harbour/MiniGUI" (поскольку упоминается "коллективный разум на форуме") или про более детальное описание (для разработчиков/юзеров некоего "практического ПО", разрабатываемого более чем одним человеком) апдейтов этого "бизнес-ПО" (того же "Реестра-Стационара")? Если про Harbour (и сопутствующее ему) - какое-то время назад начал склонять желающих пописАть описание Харбора в формате Викиучебника ( в этой темке форума), да что-то "что они не делают - не идут дела..." :) ("заготовку" первоначальную сделал - а дальше надо со структурой [содержание] публикации определяться и кропать кто может и хочет "по 3 копейки" кусочками). Если про это разговор - м.б. лучше продолжить в указанной темке?
| |
|
|
| |
Пост N: 264
Зарегистрирован: 12.11.06
|
|
Отправлено: 27.07.12 13:54. Заголовок: Добрый день! Не "..
Добрый день! Не "соскучились"? А теперь "Memoedit": Логично, да и в Clipper... при перемешении по линии влево и достижении первой колонки курсор должен оставаться на первой колонке при последующих нажатиях стрелки влево, но "фигфам" в xHarbour он улетает в "бесконечность" вправо за территорию текста, т.е. курсор перемещается не по фактически редактируемой строке, а по некой виртуальной буферной строке (шириной 231 знак). Но пользователи этой "задумки" не понимают и ругаются. "Решено" добавлением в функцию пользователя memoedit строчек: FUNC FMEdit(nMode,nRow,nCol) LOCA nKeys:=LastKey() LOCA nRet:=ME_DEFAULT .... DO CASE .... CASE nKeys == K_LEFT .AND. nCol >= 230 CLEAR TYPEAHEAD KEYB Chr(K_HOME) ENDC RETU nRet
| |
|
|
| |
Пост N: 265
Зарегистрирован: 12.11.06
|
|
Отправлено: 27.07.12 14:14. Заголовок: gustow пишет: Если ..
gustow пишет: цитата: | Если про Harbour (и сопутствующее ему) - какое-то время назад начал склонять желающих пописАть описание Харбора в формате Викиучебника (в этой темке форума), да что-то "что они не делают - не идут дела..." :) ("заготовку" первоначальную сделал - а дальше надо со структурой [содержание] публикации определяться и кропать кто может и хочет "по 3 копейки" кусочками). Если про это разговор - м.б. лучше продолжить в указанной темке? |
| Прочитал это раннее, но и тогда и сейчас сказать по сути нечего... Понятной и вменяемой документации, как ни по Харбор, так ни по обсуждаемых здесь всеьма интересным системам типа LetoDB, miniGUI НЕТ, но кто-то должен её написать. Можно было потребовать её от "коллективного разума", но он это только "щупает" не понимая технологий данных библиотек... а даже краткий список функций с параметрами разработчики не сильно стремяться предоставить... понимаю им интереснее творить. При таком подходе "боюсь", что системы Харбоур остануться уделом, как отметили на другом форуме "секты" выходцев из Clipper
| |
|
|
| moderator
|
Пост N: 405
Зарегистрирован: 11.02.10
|
|
Отправлено: 27.07.12 14:31. Заголовок: AndreyZh пишет: кра..
AndreyZh пишет: цитата: | краткий список функций с параметрами |
| Уже есть! См. здесь
| |
|
|
| |
Пост N: 2472
Зарегистрирован: 17.05.05
|
|
Отправлено: 27.07.12 15:58. Заголовок: AndreyZh пишет: min..
AndreyZh пишет: В теме есть сайтик где лежит дока.
| |
|
|
| |
Пост N: 266
Зарегистрирован: 12.11.06
|
|
Отправлено: 27.07.12 16:20. Заголовок: gfilatov2002 и уважа..
gfilatov2002 и уважаемый Dima - пятница вечер и уже сложно, понятно и однозначно выражать свою мысль, но всё же отделив "мух от котлет": 1. xharbour - есть нормальная дока от 2007 года 2. harbour 3.0 - наконец то появился, надеюсь правильный и полный список функций... хотя материалов для "быстрого старта" окромя описалова Кресина от 2002 года (устарело однако) НЕТ 3. по miniGUI какие-то доки появились "на днях"... что же может быть и стоит уже "поиграться" 4. LetoDB в readme есть упоминания о каких-то функциях.... Обалденно богатая и полезная библиотека? Но спасибо и на этом... опираясь на базовые знания клиппера хоть что-то можно понять. P.S. http://www.whosaway.com/ у меня IE пишет о проблемах подключения... и раньше не хотел его открывать
| |
|
|
| |
Пост N: 2473
Зарегистрирован: 17.05.05
|
|
Отправлено: 27.07.12 16:29. Заголовок: AndreyZh пишет: htt..
AndreyZh пишет: Андрей сайт спокойно открывается в Мозилла и в Opera. Если надо я могу перелить доку на files.mail.ru , мне не сложно. PS IE8 спокойно открыл сайт
| |
|
|
| |
Пост N: 561
Зарегистрирован: 11.06.10
|
|
Отправлено: 27.07.12 16:31. Заголовок: AndreyZh Есть и друг..
AndreyZh Есть и другой вариант - взять платный продукт для разработки и балдеть от того что там все есть, включая саппорт AndreyZh пишет: цитата: | 2. harbour 3.0 - наконец то появился, надеюсь правильный и полный список функций... хотя материалов для "быстрого старта" окромя описалова Кресина от 2002 года (устарело однако) НЕТ |
|
а что конкретно интересует по старту?
| |
|
|
| |
Пост N: 267
Зарегистрирован: 12.11.06
|
|
Отправлено: 27.07.12 16:31. Заголовок: Dima пишет: Андрей ..
Dima пишет: цитата: | Андрей сайт спокойно открывается в Мозилла и в Opera. Если надо я могу перелить доку на files.mail.ru , мне не сложно |
| Буду благодарен... и не обращайте внимание на уставшего и недовольного сегодняшним днём человека
| |
|
|
| |
Пост N: 268
Зарегистрирован: 12.11.06
|
|
Отправлено: 27.07.12 16:34. Заголовок: AlexMyr пишет: Есть..
AlexMyr пишет: цитата: | Есть и другой вариант - взять платный продукт для разработки и балдеть от того что там все есть, включая саппорт |
| А Вы уважаемый! - не передёргивайте... Например Lazarus, впрочем и другие популярные системы разработок (PHP, C++, ...) имеет большой набор литературы, да если поискать на сайтах разработчиков библиотек Harbour то же многое можно накопать!
| |
|
|
| |
Пост N: 2474
Зарегистрирован: 17.05.05
|
|
Отправлено: 27.07.12 16:39. Заголовок: AndreyZh Держи http..
| |
|
|
| |
Пост N: 269
Зарегистрирован: 12.11.06
|
|
Отправлено: 27.07.12 16:49. Заголовок: Dima пишет: Держи h..
Dima пишет: Спасибо - скачал
| |
|
|
| |
Пост N: 562
Зарегистрирован: 11.06.10
|
|
Отправлено: 27.07.12 18:16. Заголовок: AndreyZh пишет: А В..
AndreyZh пишет: цитата: | А Вы уважаемый! - не передёргивайте... Например Lazarus, впрочем и другие популярные системы разработок (PHP, C++, ...) имеет большой набор литературы, да если поискать на сайтах разработчиков библиотек Harbour то же многое можно накопать! |
|
Спокойно! Вот видите Вы уже многое и накопали! Так что там про старт Вас интересует?
| |
|
|
| |
Пост N: 270
Зарегистрирован: 12.11.06
|
|
Отправлено: 30.07.12 09:16. Заголовок: AlexMyr пишет: Так ..
AlexMyr пишет: цитата: | Так что там про старт Вас интересует? |
| Доброе утро! Не ответить - наверное неприлично, хотя уже мало интересно... А для пользы, если есть на русском яыке интересно бы было изучить: 1. Harbour 3. Сборка программы, работа с hbmk 2. Список функций и пример для начинающего по LetoDB 3.... По остальному... Надо посмотреть руквоводство любезно данное Dima.
| |
|
|
| |
Пост N: 563
Зарегистрирован: 11.06.10
|
|
Отправлено: 30.07.12 09:38. Заголовок: AndreyZh пишет: 1. ..
AndreyZh пишет: цитата: | 1. Harbour 3. Сборка программы, работа с hbmk |
| Для начала hbmk2 -help Допустим у вас проект из двух файлов p1.prg, p2.prg, создадим pr1.hbp //begin pr1.hbp p1 p2 //end pr1.hbp Собираем: hbmk2 pr1.hbp Если нужно дополнительно подключить библиотеку, тогда //begin pr1.hbp -l<namelib1> -l<namelib2> p1 p2 //end pr1.hbp Больше примеров на SVN\contrib AndreyZh пишет: цитата: | 2. Список функций и пример для начинающего по LetoDB |
| Изучаем readme.txt и readme_rus.txt, примеры в в letodb/tests
| |
|
|
| |
Пост N: 6282
Зарегистрирован: 17.05.05
|
|
Отправлено: 10.02.17 18:34. Заголовок: Вроде не было в этой..
Вроде не было в этой теме set fixed on SET DECIMALS TO 15 ? 33724.30+6120.30 // 39844.600000000010000 Откуда взялась 1 в 11 знаке после запятой ? Ведь не множим , не делим...
| |
|
|
| |
Пост N: 335
Зарегистрирован: 12.11.06
|
|
Отправлено: 11.02.17 07:23. Заголовок: Что по этому примеру..
| |
|
|
| |
Пост N: 336
Зарегистрирован: 12.11.06
|
|
Отправлено: 11.02.17 07:33. Заголовок: Вдогонку... на VFP 9..
Вдогонку... на VFP 9 так же сложение даёт хвост, но Int там работает, на этом примере правильно
| |
|
|
| постоянный участник
|
Пост N: 1420
Зарегистрирован: 09.10.06
|
|
Отправлено: 11.02.17 11:45. Заголовок: AndreyZh пишет: ост..
AndreyZh пишет: цитата: | осталось проверить "прародителя" - проверить это на чистом С |
| Так вроде ж прародитель Clipper bcc55 цитата: | #include <stdio.h> int main () { double a = 33724.30; double b = 6120.30; printf( "result = %.15f\n", a + b ); printf( "result = %.15f\n", a - b ); return( 0 ); } |
| Вывод цитата: | result = 39844.600000000005820 result = 27604.000000000003640 |
| PellesC 8.0 цитата: | result = 39844.600000000005821 result = 27604.000000000003638 |
|
| |
|
|
| |
Пост N: 6283
Зарегистрирован: 17.05.05
|
|
Отправлено: 11.02.17 14:42. Заголовок: AndreyZh пишет: но ..
AndreyZh пишет: цитата: | но Int там работает, на этом примере правильно |
| А что покажет Foxpro на такой пример ? local n := (3.14 ^ 3.14 ^ 3.14 ^ 3.14) / 0.002 ? n ? int(n) Harbour 1211955117675862000.00 1211955117675862528
| |
|
|
| |
Пост N: 337
Зарегистрирован: 12.11.06
|
|
Отправлено: 11.02.17 16:46. Заголовок: Просто есть fox под ..
Просто есть fox под руками - вот и проверил. Win 10/64
| |
|
|
| постоянный участник
|
Пост N: 1421
Зарегистрирован: 09.10.06
|
|
Отправлено: 11.02.17 17:45. Заголовок: PROCEDURE main() L..
цитата: | PROCEDURE main() LOCAL n := (3.14 ^ 3.14 ^ 3.14 ^ 3.14) / 0.002 ? n ? Int( n ) SET FIXED ON SET DECIMALS TO 15 ? 33724.30+6120.30 // 39844.600000000010000 RETURN C:\ALASKA\XPPW32\bin>pbuild.bat test_f.prg Xbase++ (R) Compiler 1.90.331 Apr 27 2006 Copyright (c) Alaska Software. All rights reserved. File: C:\ALASKA\XPPW32\bin\test_f.prg Line: 13 File C:\ALASKA\XPPW32\bin\test_f.prg successfully compiled. Alaska 32-Bit Linker Version 1.90.331 Copyright (c) Alaska Software 1997-2006. All rights reserved. 1211955117675862000,00 1211955117675862000 39844,600000000010000 |
|
| |
|
|
| |
Пост N: 6285
Зарегистрирован: 17.05.05
|
|
Отправлено: 11.02.17 18:26. Заголовок: Петр пишет: 39844,..
Петр пишет: А Excel считает без "хвоста"
| |
|
|
| постоянный участник
|
Пост N: 1422
Зарегистрирован: 09.10.06
|
|
Отправлено: 11.02.17 18:48. Заголовок: У всех свои правила ..
У всех свои правила - вот знать бы их Но harbour, xharbour, xbase++ и, думаю, clipper пользуются одним и тем же правилом.
| |
|
|
| |
Пост N: 6286
Зарегистрирован: 17.05.05
|
|
Отправлено: 11.02.17 19:05. Заголовок: Петр Да в Clipper т..
Петр Да в Clipper такой же результат (проверил)
| |
|
|
| Администратор
|
Пост N: 3527
Зарегистрирован: 23.05.05
|
|
Отправлено: 11.02.17 20:23. Заголовок: Петр пишет: У всех ..
Петр пишет: цитата: | У всех свои правила - вот знать бы их Но harbour, xharbour, xbase++ и, думаю, clipper пользуются одним и тем же правилом. |
| Все эти операции выполняет одно и то же устройство - FPU, и думается, выполняет одинаково. Не забывайте, что числа хранятся в двоичном представлении, то есть с базой 2. Отображаются они в привычном для нас десятичном формате. Для преобразования числа в строковое представление с базой 10 необходимо выполнить массу арифметических операций: в основном это операции вычитания и умножения или деления на 10. Эти операции во-первых могут выполняться по разному и в разной последовательности, во вторых каждая такая операция тоже дает некоторую погрешность, обычную для операций fpu. Отсюда получается различный результат для разных компиляторов и программных комплексов.
| |
|
|
| Администратор
|
Пост N: 4026
Зарегистрирован: 23.05.05
|
|
Отправлено: 15.06.21 08:40. Заголовок: Вот сам нарвался на ..
Вот сам нарвался на ситуацию: Есть простое суммирование поля с размерностью N, 12, 2. Суммируется около 2 тыс значений В итоге получается результат: 6947703.00000001 Набегает погрешность 10 нанорублей, или 1 микрокопейка Я бы и не заметил такую погрешность, но результат передается в Excel, а там в строке ввода погрешность видно. Пользователи нервничают, ну как обычно
| |
|
|
| |
Пост N: 329
Зарегистрирован: 05.11.05
|
|
Отправлено: 15.06.21 11:16. Заголовок: Pasha пишет: В итог..
Pasha пишет: цитата: | В итоге получается результат: 6947703.00000001 Набегает погрешность 10 нанорублей, или 1 микрокопейка |
| Я еще когда на клиппере писал, стал в таких случаях писать округление до копейки для каждого числа, которые после округления суммировал. По логике это округление не нужно, но приходилось, чтобы таких ошибок не было.
| |
|
|
| |
Пост N: 7395
Зарегистрирован: 17.05.05
|
|
Отправлено: 15.06.21 12:38. Заголовок: Pasha пишет: Есть п..
Pasha пишет: цитата: | Есть простое суммирование поля с размерностью N, 12, 2. Суммируется около 2 тыс значений |
| Тут вопрос возникает. Округлять результат операции суммирования для всех 2 тыс значений или только конечную цифру ?
| |
|
|
| Администратор
|
Пост N: 4027
Зарегистрирован: 23.05.05
|
|
Отправлено: 15.06.21 12:58. Заголовок: Достаточно конечную ..
Достаточно конечную цифру, я так и делаю
| |
|
|
| |
Пост N: 7396
Зарегистрирован: 17.05.05
|
|
Отправлено: 15.06.21 13:49. Заголовок: Pasha пишет: Достат..
Pasha пишет: цитата: | Достаточно конечную цифру, я так и делаю |
| А если складывать вот так ? X+= Base->KLV * Base->CENA , где KLV , "N" ,10,3 а CENA , "N" ,10,2
| |
|
|
| Администратор
|
Пост N: 4028
Зарегистрирован: 23.05.05
|
|
Отправлено: 15.06.21 14:13. Заголовок: здесь конечно требуе..
здесь конечно требуется промежуточное округление, иначе погрешность в случае дробного количества будет достигать до полкопейки
| |
|
|
| |
Пост N: 330
Зарегистрирован: 05.11.05
|
|
Отправлено: 15.06.21 19:13. Заголовок: Я сейчас уже не помн..
Я сейчас уже не помню, что у меня было, но были примеры где промежуточное округление и итоговое разные значения давали. Очевидно, что ошибка была не в 0,00....001, а большая и они накапливались.
| |
|
|
| Администратор
|
Пост N: 4029
Зарегистрирован: 23.05.05
|
|
Отправлено: 15.06.21 20:20. Заголовок: round(1/3+1/3+1/3, 2..
round(1/3+1/3+1/3, 2) --> 1.00 round(1/3, 2)+round(1/3, 2)+round(1/3, 2) --> 0.99
| |
|
|
| |
Пост N: 331
Зарегистрирован: 05.11.05
|
|
Отправлено: 16.06.21 07:24. Заголовок: Все округления могут..
Все округления могут быть полезны, лучше все и делать.
| |
|
|
| Администратор
|
Пост N: 4030
Зарегистрирован: 23.05.05
|
|
Отправлено: 16.06.21 09:15. Заголовок: Я обычно обхожусь бе..
Я обычно обхожусь без округления Сделал такую функцию, для сравнения чисел с точностью до двух десятичных знаков: #include "hbapi.h" #include "math.h" HB_FUNC( EQU ) { double d1 = hb_parnd( 1 ); if( HB_ISNUM( 2 ) ) { double d2 = hb_parnd( 2 ); hb_retl( fabs( d1 - d2 ) < 0.005 ); } else hb_retl( fabs( d1 ) < 0.005 ); } вместо nSum1 == nSum2 или подобное использую Equ(nSum1, nSum2)
| |
|
|
| Администратор
|
Пост N: 4031
Зарегистрирован: 23.05.05
|
|
Отправлено: 16.06.21 11:13. Заголовок: Если скинуть в Excel..
Если скинуть в Excel достаточно большой заполненный dbf-файл, порядка 10 тыс.записей, с числовым полем размерностью N,12, 2 и затем с произвольной строки помечать числовую колонку, то начиная примерно с пометки 1500-2000 строк обязательно возникает погрешность суммы (которую видно внизу Excel) в 8-м знаке в ту или другую сторону, та же микрокопейка Если продолжать помечать колонку дальше, то при пометке 3-4 тыс строк погрешность может аннигилироваться. Забавно Эффект лучше наблюдать в LibreOffice. Погрешность суммирования то появляется, то исчезает
| |
|
|
| |
Пост N: 332
Зарегистрирован: 05.11.05
|
|
Отправлено: 16.06.21 12:20. Заголовок: Pasha пишет: исполь..
Pasha пишет: цитата: | использую Equ(nSum1, nSum2) |
| А я вставил округление до копейки в функцию и где считал нужным писал valround(значение).
| |
|
|
| постоянный участник
|
Пост N: 3765
Зарегистрирован: 17.02.12
|
|
Отправлено: 16.06.21 12:44. Заголовок: rvu пишет где считал..
rvu пишет цитата: | где считал нужным писал valround(значение) |
| Помогает исп. рабочих полей в dbf "N", 19, <все нужные варианты>, т.е через них расчеты. Т.к. клиент сам ставит варианты nDec для разных групп номенклатуры (2, 3, 4, 5, 7), то привязывал имя раб. поля к номенклатуре (picture тоже если надо), работает вариант со времен S87
| |
|
|
| Администратор
|
Пост N: 4134
Зарегистрирован: 23.05.05
|
|
Отправлено: 23.10.23 13:20. Заголовок: Просто крик души Сда..
Просто крик души Сдаем отчет РСВ-1 в ФНС Получаем протокол: 0400400013-СНИЛС XXX-XXX-XXX XX ст.170 (2 м.) = 8873.77 Расчетная сумма = (ст.150 поп + ст.150 (1 мес. + 2 мес.)) * тариф - ст.170 поп - ст.170 (1 мес.) = 150678.66 * 30/100 - 36329.82=8873.79 разница = -.02 V не принимается. II. По основаниям, предусмотренным пунктом 7 статьи 431 Налогового кодекса Российской Федерации: 0400400011-Нарушено условие равенства значения суммы страховых взносов по плательщику страховых взносов совокупной сумме страховых взносов по застрахованным лицам конец протокола проверяю на калькуляторе: 150678.66 * 30/100 - 36329.82 = 8873.78 и там дальше 4 такие же ошибки ФНС, если кто не знает, это Федеральная Налоговая Служба Российской Федерации Риторический вопрос: как научить ФНС арифметике ?
| |
|
Ответов - 150
, стр:
1
2
3
4
5
6
7
8
All
[только новые]
|
|
|