On-line: гостей 0. Всего: 0 [подробнее..]
АвторСообщение





Пост 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 кажется работает правильно)

Спасибо: 0 
ПрофильЦитата Ответить
Ответов - 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


Спасибо: 0 
ПрофильЦитата Ответить





Пост N: 167
Зарегистрирован: 12.11.06
ссылка на сообщение  Отправлено: 07.11.10 13:40. Заголовок: Петр - спасибо! Хотя..


Петр - спасибо! Хотя и не успокоили...

Запустил поиск и уменя в программе операция (%) более 1000 раз, ну алгоритмы такие размножал... Как можно попытаться порешать эти проблемки? По проверке на других компиляторах - мне доступны и проверил на C#/VFP5 ошибок не получил! А пример кода "роняющего" программу сейчас проверю - очень интересно!

Спасибо: 0 
ПрофильЦитата Ответить





Пост N: 168
Зарегистрирован: 12.11.06
ссылка на сообщение  Отправлено: 07.11.10 13:56. Заголовок: Действительно роняет..


Действительно роняет! Но мне проще - мои финансовые программы не работают с такими размерностями

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник


Пост 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

Вот в этом направлении и двигайтесь.

Спасибо: 0 
ПрофильЦитата Ответить





Пост N: 169
Зарегистрирован: 12.11.06
ссылка на сообщение  Отправлено: 08.11.10 10:51. Заголовок: Спасибо! - Это идея,..


Спасибо! - Это идея, но разве на Clipper могу переопределить оператор (%)?

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник


Пост N: 995
Зарегистрирован: 09.10.06
ссылка на сообщение  Отправлено: 08.11.10 13:11. Заголовок: Во-первых, вы попроб..


Во-первых, вы попробуйте, за #xtranslate <xExp1> % <xExp2> => fMod( <xExp1>, <xExp2> ) отвечает препроцессор, Clipper ни о чем и не догадывается, что ему собираются подсунуть.
Во вторых с помощью какого-то gsar, sed или других утилит сделать 1000 замен, что раз плюнуть.
В третьих я же вам не предложил
ASSOCIATE CLASS ... OPERATOR "%" ... и т.п.

Спасибо: 0 
ПрофильЦитата Ответить





Пост N: 170
Зарегистрирован: 12.11.06
ссылка на сообщение  Отправлено: 08.11.10 16:29. Заголовок: Спасибо... Этой же е..


Спасибо... Этой же ерундой уже занимаюсь! Увы % это не только знак "операции", но и обозначения "процента", использующегося в бизнесе. Да'с сколько еще открытий чудных меня ожидает?

Спасибо: 0 
ПрофильЦитата Ответить





Пост 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 - как то быстро разобрался

Спасибо: 0 
ПрофильЦитата Ответить
Администратор




Пост N: 1805
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 22.01.11 14:57. Заголовок: AndreyZh пишет: Фун..


AndreyZh пишет:

 цитата:
Функция IndexExp() - расширение индексного файла рабочей области в Clipper возвращает ".NTX", а в xHarbour ".ntx"



У меня сохранились сырцы Харбора версии 0.39 от 2002 года, и там уже IndexExt() был на нижнем регистре. Почему ? Я могу только сказать, что так сложилось исторически. Возможно, разработчики ориентировались на *nix, где принято использовать нижний регистр.

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 1642
Зарегистрирован: 12.09.06
ссылка на сообщение  Отправлено: 22.01.11 17:04. Заголовок: AndreyZh пишет: В x..


AndreyZh пишет:

 цитата:
В xHarbour нет ф-ции PrintReady, но есть "аналог" IsPrinter - как то быстро разобрался



Пользуйся поиском на форуме. Много чего узнаешь интересного...
http://clipper.borda.ru/?1-20-0-00000363-000-0-0-1200576623<\/u><\/a>

AndreyZh пишет:

 цитата:
может быть Вам известны другие "грабельки", связанные с несовместимостью Clipper & xHarbour?


Можешь открыть отдельную тему. Но только перечень этих несовместимостей.

Спасибо: 0 
ПрофильЦитата Ответить





Пост N: 199
Зарегистрирован: 12.11.06
ссылка на сообщение  Отправлено: 22.01.11 18:54. Заголовок: Andrey пишет: Польз..


Andrey пишет:
 цитата:

Пользуйся поиском на форуме. Много чего узнаешь интересного...
http://clipper.borda.ru/?1-20-0-00000363-000-0-0-1200576623<\/u><\/a>


Уважаемый тёзка!
Проблема "грабель" и "несовместимостей" заключается в том, что они выявляются в процессе реальной работы реального приложения, т.е. возникает проблема, там где её никогда не было. Только после этого начинается поиск её источника и даже трижды перечитав данный весьма полезный форум сложно ассоциировать "грабли" с конкретным обсуждением!!! Посему изредка эти "грабли" описываю, что часть проблем другие смогли избежать.

Форум крайне полезен, когда возникает конкретный вопрос использованию конкретных возможностей, но увы в меньшей степени помогает избежать проблем в "очевидных" вещах.


 цитата:
Можешь открыть отдельную тему. Но только перечень этих несовместимостей.


Довольно много их с вашей помощью обсудили в "простынках":
1. http://clipper.borda.ru/?1-4-100-00000527-000-0-0-1270323717<\/u><\/a>
2.
http://clipper.borda.ru/?1-3-0-00000137-000-0-0-1287163818<\/u><\/a>

Но "ОБСУЖДЕНИЯ" очень сильно помогают в решении проблемы, но при этом сильно "ПРЯЧУТ" конкретные проблемы за потоком сопутствующей информации, т.е. нужна темы "СО СПИСКОМ ПРОБЛЕМ" без их обсуждений, что только сможет сделать модератор добавляя туда инфу и запрещая "обсуждение" в данной теме.

Пока вспомнил ещё "несовместимости":

1. Имею поиск по первым буквам, который не контролировал, т.е. можно искать даже там, где нет последовательности по символам. Более того Clipper пытается искать даже если нет индекса у таблицы по DbSeek() - конечно ничего не находя. xHarbour при такой попытке "вываливается" по ошибке.

2. Более сложно? - Не нашел решения, да и не сильно нужно. Для просмотра больших текстовых файлов использовал ф-цию С.Кроссмана - исходник loopfile.prg, если кто скачивал мою прожку... Она всегда идеально работала, но не с xHarbour: работает во всех режимах, кроме попыток сместиться вверх стрелкой или PgDn - улетает на самую первую строку. Пошаговое тестирование в клиппере показывало "логичную" обработку каждого действия, но xHarbour на любую клавишу ведёт себя, как "пьяная обезьяна" хотя в по большей части приходит к нужному результату. Вопрос для меня не критичен, т.к. оказалось (нигде в иструкциях не нашел), что memoedit работает с файлами любого размера?

Спасибо: 0 
ПрофильЦитата Ответить
Администратор




Пост N: 1807
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 22.01.11 22:45. Заголовок: Здесь необходимо исп..


Здесь необходимо использовать другой подход. Если Вы нашли какую-то несовместимость, которую считаете существенной, то приймите меры, чтобы ее устранить. Устранить можно либо самому, передав фикс разработчикам, либо долбать разработчиков, чтобы это кто-то сделал. И клевать надо не здесь, а непосредственно в майл-листе харбора.
Здесь конечно тоже есть разработчики, но очень мало. Мне, к примеру, эта несовместимость по IndexExt совершенно неинтересна. Более того, поскольку я уже много лет программирую не на клиппере, а на харборе, ориентируюсь на нижний регистр. И мне устранение этой несовместимости помешает.
Устранить ее - раз плюнуть. Надо в include/hbrddntx.h заменить строку-литерал.
Если считаете, что это необходимо - доказывайте это, но не здесь, а в специально предназначенном для этого месте.
Не ждите, что это кто-то сделает за Вас. Будьте сами кузнецом своего счастья. Если здесь не помогли, то этим форумом мир харбора не ограничивается.
Я, кстати, так и поступал с обнаруженными мной когда-то несовместимостями.


Спасибо: 0 
ПрофильЦитата Ответить





Пост 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

Спасибо: 0 
ПрофильЦитата Ответить
Администратор




Пост 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 двойной точности.

Опять что-то непонятно ?


Спасибо: 0 
ПрофильЦитата Ответить
Администратор




Пост 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


Спасибо: 0 
ПрофильЦитата Ответить
Администратор




Пост N: 2068
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 23.09.11 08:31. Заголовок: AndreyZh пишет: ещё..


AndreyZh пишет:

 цитата:
ещё один крайне серьёзный, непонятный глюк xHarbour (или BCC) (в clipper такой ошибки нет).



Чтобы не возвращатся к этой якобы ошибке, или якобы глюку, замечу. что клиппер делает вычисления точно так же.
Т.е., эта т.н. "ошибка" есть и в клиппере. Еще бы ее не было, ведь вычисления делает не клиппер, и не харбор, а fpu
Думаю, что такая же "ошибка" присутствует и в Delphi, и в любом компиляторе, который выполняет вычисления с числами double

Спасибо: 0 
ПрофильЦитата Ответить





Пост 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#

Спасибо: 0 
ПрофильЦитата Ответить
Администратор




Пост 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. В харборе - тоже самое


Спасибо: 0 
ПрофильЦитата Ответить
Администратор




Пост N: 2070
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 23.09.11 10:23. Заголовок: AndreyZh пишет: Поп..


AndreyZh пишет:

 цитата:
Попытаюсь дать Ваше подробное пояснение этой "гориле-безопастнику" - посмотрю на его реакцию



Мнээ.. не советую. Сьедят (с) Понедельник начинается в субботу

Лучше слелайте в своих программах проверку на ноль не простым сравнением, а через Round(n1, 2)
Я так сделал еще в те далекие времена, когда небо было голубее, трава зеленее, и первый раз попался в клиппере на такую особенность вычислений с double

Спасибо: 1 
ПрофильЦитата Ответить





Пост N: 210
Зарегистрирован: 12.11.06
ссылка на сообщение  Отправлено: 23.09.11 10:57. Заголовок: Pasha пишет: Лучше ..


Pasha пишет:

 цитата:
Лучше слелайте в своих программах проверку на ноль не простым сравнением, а через Round(n1, 2)
Я так сделал еще в те далекие времена, когда небо было голубее, трава зеленее, и первый раз попался в клиппере на такую особенность вычислений с double



Конечно так уже сделал! - "А что делать?"

Спасибо: 0 
ПрофильЦитата Ответить
Ответов - 150 , стр: 1 2 3 4 5 6 7 8 All [только новые]
Ответ:
1 2 3 4 5 6 7 8 9
большой шрифт малый шрифт надстрочный подстрочный заголовок большой заголовок видео с youtube.com картинка из интернета картинка с компьютера ссылка файл с компьютера русская клавиатура транслитератор  цитата  кавычки моноширинный шрифт моноширинный шрифт горизонтальная линия отступ точка LI бегущая строка оффтопик свернутый текст

показывать это сообщение только модераторам
не делать ссылки активными
Имя, пароль:      зарегистрироваться    
Тему читают:
- участник сейчас на форуме
- участник вне форума
Все даты в формате GMT  3 час. Хитов сегодня: 16
Права: смайлы да, картинки да, шрифты да, голосования нет
аватары да, автозамена ссылок вкл, премодерация откл, правка нет