powered by simpleCommunicator - 2.0.55     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Почему сравнение на >=0 при выражении=0 считается .F.?
18 сообщений из 18, страница 1 из 1
Почему сравнение на >=0 при выражении=0 считается .F.?
    #36484388
CTAC-KO
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Привет!
Столкнулся с такой непоняткой - сравниваю результат вычитания одной переменной из другой на больше или равно 0 и хотя результат выражения=0 выражение не считается .Т.
Вот выражение:
Код: plaintext
IF (m.ltNextStateBeg - m.ltPrevStateEnd) >= m.tnAssignDuration
при этом m.ltNextStateBeg = m.ltPrevStateEnd = "16.01.2010 08:30:00" и они типа DateTime, а в m.tnAssignDuration = 0. Если спросить:
Код: plaintext
?(m.ltNextStateBeg - m.ltPrevStateEnd)
выводится 0
на
Код: plaintext
?m.tnAssignDuration
выводится 0
на
Код: plaintext
?(m.ltNextStateBeg - m.ltPrevStateEnd) >= m.tnAssignDuration
выводится .F.
на
Код: plaintext
?(m.ltNextStateBeg - m.ltPrevStateEnd) >=  0 
выводится .F.
на
Код: plaintext
?(m.ltNextStateBeg - m.ltPrevStateEnd) >=  0 . 00 
выводится .F.
и аж только в обертке в INT:
Код: plaintext
?INT(m.ltNextStateBeg - m.ltPrevStateEnd) >= m.tnAssignDuration
выражение "оправдывается", т.е. выводится .T.

Результат вычитания переменных типа DateTime, как я до сих пор думал, является целочисленным, в секундах. Но выходит что результат - какое-то нецелое число, а что-то типа Float/Double, однако 0 и в Африке 0, какая разница? Оно, что ли, миллисекунды добавляет где не просят и где они не указаны, (значит все равно =0) и все равно тогда не понятно в чем дело. Опять же сравнение на 0.00 не прошло...

Может кто разъяснить в чем тут дело?

вфп9сп1

спасибо
...
Рейтинг: 0 / 0
Почему сравнение на >=0 при выражении=0 считается .F.?
    #36484466
Фотография Игорь Горбонос
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
> Автор: CTAC-KO

А что месье думает(знает) о Null?

Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
Почему сравнение на >=0 при выражении=0 считается .F.?
    #36484919
CTAC-KO
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пардон, мсье, но где же Вы хоть намек на .NULL. узрели?
Все значения переменных при которых случается непонятка я в подробностях изложил. Ни одна из них не .NULL. иль мсье желает результат ISNULL() увидеть - могу лично для Вас устроить :)

Или все это лишь тонкий намек? Извольте объясниться!
...
Рейтинг: 0 / 0
Почему сравнение на >=0 при выражении=0 считается .F.?
    #36484924
CTAC-KO
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
HelpA DateTime value is stored in eight bytes — two four-byte integers. почему ж тогда разница вычитания не integer? Вот в чем вопрос!
...
Рейтинг: 0 / 0
Почему сравнение на >=0 при выражении=0 считается .F.?
    #36484932
reware
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CTAC-KO,

У меня (VFP9) все нормально :
Код: plaintext
1.
2.
3.
4.
5.
m.ltPrevStateEnd = ctot("16.01.2010 08:30:00")
m.ltNextStateBeg = m.ltPrevStateEnd && принудительное клонирование переменной
? (m.ltNextStateBeg - m.ltPrevStateEnd) &&  0 
? (m.ltNextStateBeg - m.ltPrevStateEnd) >=  0  && .T.
z= 0 
? (m.ltNextStateBeg - m.ltPrevStateEnd) >= z && .T.

Вызывает сомнение кажущееся (?) равенство m.ltNextStateBeg = m.ltPrevStateEnd. Если эти переменные являются результатом какого-то вычисления, то они могут и не равняться друг другу.
...
Рейтинг: 0 / 0
Почему сравнение на >=0 при выражении=0 считается .F.?
    #36484940
CTAC-KO
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
самое интересное что повторить ситуацию искусственно не вышло. попробовал задать
d1=datetime()
d2=d1
?d2-d1=0
выдало .T.
я в осадке:лог из проги21:56:18 m.ltNextStateBeg=09.03.2010 08:30:00, m.ltPrevStateEnd=09.03.2010 08:30:00, m.tnAssignDuration=0
21:56:18 m.ltNextStateBeg - m.ltPrevStateEnd >= m.tnAssignDuration=.F.
21:56:18 m.ltNextStateBeg=09.03.2010 08:45:00, m.ltPrevStateEnd=09.03.2010 08:45:00, m.tnAssignDuration=0
21:56:18 m.ltNextStateBeg - m.ltPrevStateEnd >= m.tnAssignDuration=.T.
21:56:58 m.ltNextStateBeg=09.03.2010 08:30:00, m.ltPrevStateEnd=09.03.2010 08:30:00, m.tnAssignDuration=0
21:56:59 m.ltNextStateBeg - m.ltPrevStateEnd >= m.tnAssignDuration=.F.
21:56:59 m.ltNextStateBeg=09.03.2010 08:45:00, m.ltPrevStateEnd=09.03.2010 08:45:00, m.tnAssignDuration=0
21:56:59 m.ltNextStateBeg - m.ltPrevStateEnd >= m.tnAssignDuration=.T.
21:57:03 m.ltNextStateBeg=09.03.2010 08:30:00, m.ltPrevStateEnd=09.03.2010 08:30:00, m.tnAssignDuration=0
21:57:03 m.ltNextStateBeg - m.ltPrevStateEnd >= m.tnAssignDuration=.F.
21:57:03 m.ltNextStateBeg=09.03.2010 08:45:00, m.ltPrevStateEnd=09.03.2010 08:45:00, m.tnAssignDuration=0
21:57:03 m.ltNextStateBeg - m.ltPrevStateEnd >= m.tnAssignDuration=.T.
21:57:22 m.ltNextStateBeg=09.03.2010 08:30:00, m.ltPrevStateEnd=09.03.2010 08:30:00, m.tnAssignDuration=0
21:57:22 m.ltNextStateBeg - m.ltPrevStateEnd >= m.tnAssignDuration=.F.
21:57:22 m.ltNextStateBeg=09.03.2010 08:45:00, m.ltPrevStateEnd=09.03.2010 08:45:00, m.tnAssignDuration=0
21:57:22 m.ltNextStateBeg - m.ltPrevStateEnd >= m.tnAssignDuration=.T.
21:57:28 m.ltNextStateBeg=10.03.2010 08:30:00, m.ltPrevStateEnd=10.03.2010 08:30:00, m.tnAssignDuration=0
21:57:28 m.ltNextStateBeg - m.ltPrevStateEnd >= m.tnAssignDuration=.F.
21:57:28 m.ltNextStateBeg=10.03.2010 08:45:00, m.ltPrevStateEnd=10.03.2010 08:45:00, m.tnAssignDuration=0
21:57:28 m.ltNextStateBeg - m.ltPrevStateEnd >= m.tnAssignDuration=.T.
ну чезанах?!
как это вообще понимать, блин, что для 08:30 - .F., а для 08:45 - тут же радостно .T.?!
Причем результат сравнения дат на равенство выдает .T. во всех случаях...
...
Рейтинг: 0 / 0
Почему сравнение на >=0 при выражении=0 считается .F.?
    #36484995
CTAC-KO
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
По всей вероятности дело в том, что одна из дат со временем 08:30 всегда является результатом вычисления (оно следующее: составляется переменная типа DateTime из двух - одна Date, а другая - DateTime, из первой берется дата, а из второй - время в виде строки и смешиваются через CTOT()), а вторая - берется из таблицы, а для 8:45 - оба значения - из таблицы, но!
я добавил в лог результат их сравнения на равенство и фокс всегда выдает .Т., т.е. переменные равны, а значит их разница меж собой ОБЯЗАНА быть равной 0 или (с)"...а я сошла с ума - какая досада!"
Причем реально как результат вычитания фокс выдает на экран 0, но при сравнении этого ноля с "обычным" - оказывается что это не одно и то же.
Ну, допустим дело в том, что в дате скрыта часть в миллисекундах, которая явно не видна. Но все равно, я ее нигде явно не задаю, значит она, эта часть, всегда должна быть 0. Но даже если это не так, тогда переменные не должны быть равны между собой, но они-то равны! Или как тогда - при сравнении мы миллисекунды не учитываем, а вот при вычитании - учитываем, так что ли?
Да и вообще:
Help DATETIMEReturns the current date and time as a DateTime value, or creates a year 2000-compliant DateTime value.
DATETIME([nYear, nMonth, nDay [, nHours [, nMinutes [, nSeconds]]]])
т.е. ни слова о каких-либо миллисекундах!

И ведь я же не работаю с Numeric-переменными, у которых мб не видна полностью дробная часть, а с DateTime.
...
Рейтинг: 0 / 0
Почему сравнение на >=0 при выражении=0 считается .F.?
    #36485012
reware
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CTAC-KO,

Может быть, лучше сравнивать переменные после их преобразования ?
Код: plaintext
1.
2.
3.
4.
x1=TTOC(DateTime1, 3 )
x2=TTOC(DateTime2, 3 )
IF x1==x2 && или !(x1==x2)
...
ENDIF
Иначе возникают проблемы с внутренними представлениями фокса. По крайней мере, с Numeric такие проблемы имеют место быть.
...
Рейтинг: 0 / 0
Почему сравнение на >=0 при выражении=0 считается .F.?
    #36485262
Фотография Игорь Горбонос
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
> Автор: CTAC-KO
> Или все это лишь тонкий намек? Извольте объясниться!

Я очень часто налетаю на то что полученные данные в курсоре, содержат Null, и при присвоении значения какой-то
переменной сама переменная содержит ноль(глядя в отладчике). Но сравнение с нулём не дает истины, а проверка на IsNull()
показывает где порылась собака. Вот и весь тонкий намек.

Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
Почему сравнение на >=0 при выражении=0 считается .F.?
    #36485367
quxix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
CTAC-KOПривет!
Столкнулся с такой непоняткой - сравниваю результат вычитания одной переменной из другой на больше или равно 0 и хотя результат выражения=0 выражение не считается .Т.
Вот выражение:
Код: plaintext
IF (m.ltNextStateBeg - m.ltPrevStateEnd) >= m.tnAssignDuration
при этом m.ltNextStateBeg = m.ltPrevStateEnd = "16.01.2010 08:30:00" и они типа DateTime, а в m.tnAssignDuration = 0.

Что показывает DISPLAY MEMORY по этим переменным?
...
Рейтинг: 0 / 0
Почему сравнение на >=0 при выражении=0 считается .F.?
    #36485497
Дмитрий Григорьев
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Посмотрите обсуждение на по этой теме вот здесь: http://forum.foxclub.ru/read.php?29,404003,404222#msg-404222

может это ваша ситуация.
...
Рейтинг: 0 / 0
Почему сравнение на >=0 при выражении=0 считается .F.?
    #36486914
CTAC-KO
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо за ссылку, действительно там именно по моей ситуации обсуждение.
Выход назван только один - это округление результатов вычислений с DateTime что я и сделал.
Кому интересно суть примерно такая, как я и предполагал - хранение времени в миллисекундах, но 1 секунда при этом не всегда равна 1000мс, т.е. мб 998 или 999 - от чего и растут глюки...
...
Рейтинг: 0 / 0
Почему сравнение на >=0 при выражении=0 считается .F.?
    #36489107
CTAC-KO
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вот, блин, идиотский фокс!!! ну ё-маё!
завернулся в INT, так теперь сравнение для разницы равной 0 - работает, зато сравнение на, скажем, 900 секунд - нет, но на 900 сек. прекрасно работает без инта... я в шоке... придется писать собственные функции, работающие с DATETIME
...
Рейтинг: 0 / 0
Почему сравнение на >=0 при выражении=0 считается .F.?
    #36489579
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Во-первых, поскольку поля DateTime хранят данные с точностью до секунды, то это значит, что пытаться анализировать время именно с такой точностью - бессмысленно. Банальные правила математики: последняя цифра - недостоверна, предпоследняя - сомнительна.

Ну, грубо говоря, надо всегда предполагать, что DateTime - это время +/- 0.5 секунды

Во-вторых, поскольку FoxPro - это файл-сервер, то ВСЕ модификации данных выполняются на клиенте. Это значит, что если Вы записываете, например, текущее время

Код: plaintext
replace MyField with DateTime()

то Вы записываете время локального компьютера, а вовсе не сервера, на котором храняться файлы DBF. Разумеется, на каждом компьютере время установлено по своему. Причем расхождение системных часов может достигать нескольких минут. Даже если у Вас установлена принудительная синхронизация времени в локальной сети, но ведь эта синхронизация выполняется периодически. Т.е. не гарантирует того, что время на всех компьютерах совпадает с точностью до секунды.

Как следствие, сравнение надо выполнять с некоторыми допусками или в некотором диапазоне. Например

Код: plaintext
1.
2.
3.
4.
m.Delta =  0 . 5 
IF BETWEEN(m.ltNextStateBeg - m.ltPrevStateEnd, m.tnAssignDuration - m.Delta, m.tnAssignDuration + m.Delta)
   ...
ENDIF

Как и было написано по приведенной выше ссылке - сравнение действительных чисел по абсолютному значению - бессмысленная операция. Всегда нужен некий диапазон значений.
...
Рейтинг: 0 / 0
Почему сравнение на >=0 при выражении=0 считается .F.?
    #36489700
quxix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
CTAC-KOвот, блин, идиотский фокс!!! ну ё-маё!
завернулся в INT, так теперь сравнение для разницы равной 0 - работает, зато сравнение на, скажем, 900 секунд - нет, но на 900 сек. прекрасно работает без инта... я в шоке... придется писать собственные функции, работающие с DATETIME

А если попробовать округлять до наибольшего/наименьшего целого?
Т.к. разница между полями типа datetime измеряются в секундах,то любую милисекунду(888.999)
округлим до ближайшей наибольшей целой секунды,т.е. как только появилось хоть какое-то значение в дробной части-это сигнал о преобразовании к ближайшей наибольшей секунде.
0.001=1сек
888.999=889 сек
Код: plaintext
ceiling(x)
или наоборот округляем всегда до наименьшего целого
0.001=0сек
888.999=888 сек
Код: plaintext
floor(x)
...
Рейтинг: 0 / 0
Почему сравнение на >=0 при выражении=0 считается .F.?
    #36489790
quxix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
quxixCTAC-KOвот, блин, идиотский фокс!!! ну ё-маё!
завернулся в INT, так теперь сравнение для разницы равной 0 - работает, зато сравнение на, скажем, 900 секунд - нет, но на 900 сек. прекрасно работает без инта... я в шоке... придется писать собственные функции, работающие с DATETIME

А если попробовать округлять до наибольшего/наименьшего целого?
Т.к. разница между полями типа datetime измеряются в секундах,то любую милисекунду(888.999)
округлим до ближайшей наибольшей целой секунды,т.е. как только появилось хоть какое-то значение в дробной части-это сигнал о преобразовании к ближайшей наибольшей секунде.
0.001=1сек
888.999=889 сек
Код: plaintext
ceiling(x)
или наоборот округляем всегда до наименьшего целого
0.001=0сек
888.999=888 сек
Код: plaintext
floor(x)


И даже все-таки не буду категоричен.
Вот тут сработало при округлении вверх
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
SET DECIMALS TO  16 
SET FIXED ON
create Cursor cursor (dt t,dt2 t)
insert into cursor values(ctot('2009-09-21T12:38:03'),ctot('2009-09-21T12:38:03')) 
replace dt2 with dt2- 68 * 3600 
replace dt2 with dt2+ 68 * 3600 
lnTime1=dt-DToT(TToD(dt))
lnTime2=dt2-DToT(TToD(dt2))
?lntime1=lntime2
?FLOOR(lntime1)=FLOOR(lntime2) &&F
?ceiling(lntime1)=ceiling(lntime2) && T

Хотя и тут Fox опять живет по своим правилам
Код: plaintext
1.
2.
?lntime1             && 45483 . 0000087618800000 
?ceiling(lntime1)  && 45483 . 0000000000000000  &&&!!!!!!!! д.б.  45484 
...
Рейтинг: 0 / 0
Почему сравнение на >=0 при выражении=0 считается .F.?
    #36497277
CTAC-KO
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я, короче, не стал играть в цейлинги и флоры :) написал вот такое:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
************************************************************
* DateTime Difference
* функция возвращает как результат разницу между параметрами
* типа DateTime в нормальных целочисленных секундах
* правда если число выйдет большое, оно может и в научный формат уйти...
************************************************************
LPARAMETERS ttDT1, ttDT2
IF VARTYPE(m.ttDT1)<>"T" OR VARTYPE(m.ttDT2)<>"T"
   m.goMain.Msg("E_ILLEGAL_FUNCTION_CALL","DTDiff") &&: один из параметров не DateTime
   * прога может и цифру ожидает, но пусть падает, раз неправильно функцию использует!
   RETURN .F. 
ENDIF
LOCAL ldDT1, lsDT1, lnDT1Hrs, lnDT1Min, lnDT1Sec, lnDT1SSM,;
	 ldDT2, lsDT2, lnDT2Hrs, lnDT2Min, lnDT2Sec, lnDT2SSM
* установки переменных по первой дате
ldDT1 = TTOD(m.ttDT1)
lsDT1 = TTOC(m.ttDT1)
lnDT1Hrs = INT(VAL(SUBSTR(m.lsDT1,AT(" ",m.lsDT1)+ 1 , 2 )))
lnDT1Min = INT(VAL(SUBSTR(m.lsDT1,AT(" ",m.lsDT1)+ 4 , 2 )))
lnDT1Sec = INT(VAL(SUBSTR(m.lsDT1,AT(" ",m.lsDT1)+ 7 , 2 )))
* секунд от полуночи (Seconds Since Midnight)
lnDT1SSM = m.lnDT1Hrs* 3600 +m.lnDT1Min* 60 +m.lnDT1Sec
* установки переменных по второй дате
ldDT2 = TTOD(m.ttDT2)
lsDT2 = TTOC(m.ttDT2)
lnDT2Hrs = INT(VAL(SUBSTR(m.lsDT2,AT(" ",m.lsDT2)+ 1 , 2 )))
lnDT2Min = INT(VAL(SUBSTR(m.lsDT2,AT(" ",m.lsDT2)+ 4 , 2 )))
lnDT2Sec = INT(VAL(SUBSTR(m.lsDT2,AT(" ",m.lsDT2)+ 7 , 2 )))
* секунд от полуночи (Seconds Since Midnight)
lnDT2SSM = m.lnDT2Hrs* 3600 +m.lnDT2Min* 60 +m.lnDT2Sec
* собственно разница
RETURN (m.ldDT1-m.ldDT2)* 86400  + m.lnDT1SSM - m.lnDT2SSM
мб и не фонтан, но меня устраивает. теперь 0 нормальный, также как и 900 сек.

2 Владимир Максимов:
Сначала я так и попытался сделать, только я пробовал m.tnAssignDuration/1,001, но не понравилось. Кроме того я не использую по своей задаче время с локального РС никогда вообще. В крайнем случае - запрашиваю с SQL-сервера, вернее даже не так - где надо, просто использую TIMESTAMP-поле. Но по задаче оно мне не нужно. Мне нужно распланировать день с интервалом в 15 минут в соотв. с рабочим графиком. Т.е. вариантов дельты нет изначально. Кроме того, меня в задаче изначально же секунды вообще не интересуют, уж не говоря про мс. Но, поскольку разница между ДТ вычисляется в секундах, то я просто свои минуты множил на 60.
А тут сюрприз порылся :)
Хотя, мб достаточно было бы просто использовать функцию Round() для округления до целого?
...
Рейтинг: 0 / 0
Почему сравнение на >=0 при выражении=0 считается .F.?
    #36497747
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CTAC-KOМне нужно распланировать день с интервалом в 15 минут в соотв. с рабочим графиком. Т.е. вариантов дельты нет изначально. Кроме того, меня в задаче изначально же секунды вообще не интересуют, уж не говоря про мс. Но, поскольку разница между ДТ вычисляется в секундах, то я просто свои минуты множил на 60.
А тут сюрприз порылся :)
Хотя, мб достаточно было бы просто использовать функцию Round() для округления до целого?
Так и надо было искать разницу в минутах . Тогда уж точно хватило бы Round() до целого после деления-то на 60. Никаких проблем не возникло бы...

Код: plaintext
ROUND((m.ltNextStateBeg - m.ltPrevStateEnd)/ 60 ,  0 ) >= m.tnAssignDuration
...
Рейтинг: 0 / 0
18 сообщений из 18, страница 1 из 1
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Почему сравнение на >=0 при выражении=0 считается .F.?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]