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

Вниз

Секунды теряем из-за Double   Найти похожие ветки 

 
Омлет ©   (2011-05-19 12:33) [0]

Ну зачем было для даты-времени брать тип Double?

uses DateUtils;

procedure TForm1.FormCreate(Sender: TObject);
var
 d1, d2 : TDateTime;
begin
 d1 := EncodeTime(0, 0, 5, 0);
 d2 := EncodeTime(0, 0, 6, 0);
 Caption := IntToStr(SecondsBetween(d1, d2));
end;


Т.е. разница между 5 и 6 секундами - в заголовке выводит "0"! Если 6 заменить на 9, то выведет правильное "4".
Из-за этого пришлось перейти на целочисленное время..


 
Ega23 ©   (2011-05-19 12:36) [1]

RTFM Floating point


 
Омлет ©   (2011-05-19 12:41) [2]

> RTFM Floating point

И что? Я понимаю, почему это происходит. Поэтому и негодую - неправильно было брать числа с плавающей точкой для хранения времени.


 
Ega23 ©   (2011-05-19 12:44) [3]

Почему неправильно?


 
Ega23 ©   (2011-05-19 12:46) [4]

Тебе никто не мешает написать свою SecondsBetween, с шахматами и поэтессами.


 
Anatoly Podgoretsky ©   (2011-05-19 12:51) [5]

> Омлет  (19.05.2011 12:41:02)  [2]

А как правильно, что бы при этом было совместимо с OLE, было быстро и
удобно.
Но ты сам виноват, ведь знал же что нужно точное вычисление и зачем то
приводил к Double, а не к целому.


 
Anatoly Podgoretsky ©   (2011-05-19 12:53) [6]

А мог и вообще не приводить, ведь все равно константы, значит можно было сделать - 6-5


 
Anatoly Podgoretsky ©   (2011-05-19 12:54) [7]

> Ega23  (19.05.2011 12:46:04)  [4]

А мог бы отделаться вычитанием. Борланд много горя принес, написав функции
времени для ламеров.


 
Омлет ©   (2011-05-19 13:15) [8]

Я вас не понимаю. Что за отрицание проблемы?
Вы видите ошибку и при этом говорите, мол всё хорошо, сам виноват.


 
asail ©   (2011-05-19 13:24) [9]


> Омлет ©   (19.05.11 13:15) [8]

Согласен.

> Ega23 ©   (19.05.11 12:46) [4]
> Тебе никто не мешает написать свою SecondsBetween, с шахматами
> и поэтессами.

Тебе никто не мешает вообще все на ассемблере писать... И что? Имеющийся функционал в VCL должен работать. Если есть функция SecondsBetween, то она должна возвращать корректный результат для любых корректных данных. Имхо, конечно.


> Anatoly Podgoretsky ©   (19.05.11 12:53) [6]
> А мог и вообще не приводить, ведь все равно константы, значит
> можно было сделать - 6-5

Не надо придираться к примеру, демонстрирующему суть проблемы. Данные могут и из БД придти и с ГУИ и еще хрен знает откуда...


 
asail ©   (2011-05-19 13:26) [10]

З.Ы. Я когда то с такой бедой сам сталкивался...


 
TUser ©   (2011-05-19 13:29) [11]


> Вы видите ошибку и при этом говорите, мол всё хорошо, сам
> виноват.

Формальная логика - ты ожидал поведения, отличного от документированного, значит, сам виноват. То, что ты бы написал эти функции иначе, может даже в сто раз удобнее, это совсем другой вопрос, воспользовался-то ты борландовской функцией.


 
Dimka Maslov ©   (2011-05-19 13:36) [12]

Дело не в Double, а в том, что функция SecondыBetween использует функцию Trunc, а не Round. Поэтому число 0.999999999 преобразуется к целому как 0.

пишем такую вот функцию, и получаем полное счастье
function SecondsBetween(d1, d2: Double): Int64;
begin
 Result := Round(SecondSpan(d1, d2));
end;


 
iZEN   (2011-05-19 13:48) [13]

Я когда-то писал собственную реализацию TimeStamp на основе целого. От Double-представления точно отказался.


 
Anatoly Podgoretsky ©   (2011-05-19 14:12) [14]

> asail  (19.05.2011 13:24:09)  [9]

Ни о каком демонстрирующем примером и речи не было.


 
asail ©   (2011-05-19 14:18) [15]


> Anatoly Podgoretsky ©   (19.05.11 14:12) [14]

Бюрократ!


 
DiamondShark ©   (2011-05-19 14:37) [16]


> Dimka Maslov ©   (19.05.11 13:36) [12]

Дыдадад. Проблема в том, что SecondsBetween реализует заявленное поведение:

Returns the number of seconds between two specified TDateTime values.

Call SecondsBetween to obtain the difference, in seconds, between two TDateTime values. SecondsBetween counts only entire seconds. Thus, SecondsBetween reports the difference between 9:00:00 A.M. and 9:00:00:999 A.M. as 0, because the difference is one millisecond short of an entire second.

http://docwiki.embarcadero.com/VCL/en/DateUtils.SecondsBetween

Проблема не в SecondsBetween, а в том, что ни 5 ни 6 секунд не могут быть точно представлены. А SecondsBetween понятия не имеет, что значения ранее были преобразованы из целых секунд, она честно возврашает количество полных секунд между двумя значениями.


 
KSergey ©   (2011-05-19 15:15) [17]

> Проблема не в SecondsBetween, а в том, что ни 5 ни 6 секунд
> не могут быть точно представлены.

Ну так ТС и спрашивает изначально

> Ну зачем было для даты-времени брать тип Double?

а его по привычке лечат.

> Anatoly Podgoretsky ©   (19.05.11 12:53) [6]
> А мог и вообще не приводить, ведь все равно константы, значит можно было сделать - 6-5

Типа юмарист?


 
Jeer ©   (2011-05-19 15:23) [18]


> Ну зачем было для даты-времени брать тип Double?


Мне не мешает нисколько, даже наоборот.


 
DVM ©   (2011-05-19 15:32) [19]


>  Секунды теряем из-за Double
>
> Омлет ©   (19.05.11 12:33) 

Не думай о секундах свысока
Наступит время сам поймешь наверное
Свистят они как пули у виска
Мгновения, мгновения, мгновения.


 
Inovet ©   (2011-05-19 16:17) [20]

> [0] Омлет ©   (19.05.11 12:33)
> Ну зачем было для даты-времени брать тип Double?

Мне это тоже непонятно. Почему не те же 8 байт int64 и никаких проблем с огруглениями, а конец света ещё долго не наступит, да и для творения мира нормально.


 
Dennis I. Komarov ©   (2011-05-19 16:29) [21]

ИМХО, время - не дискретная величина


 
Германн ©   (2011-05-19 16:31) [22]


> Почему не те же 8 байт int64

В Паскале?


 
Inovet ©   (2011-05-19 16:42) [23]

> [22] Германн ©   (19.05.11 16:31)
>
> > Почему не те же 8 байт int64
>
> В Паскале?

А какие проблемы? Главное аппаратно работает. Или что, в смысле тогда небыло подходящего типа?


 
RWolf ©   (2011-05-19 16:46) [24]

В Паскале не было типа TDateTime.


 
Германн ©   (2011-05-19 18:08) [25]


> В Паскале не было типа TDateTime.
>

Да. Но в Д1 уже был, а Int64 еще не было.


 
Плохиш ©   (2011-05-19 18:20) [26]


> KSergey ©   (19.05.11 15:15) [17]
> Ну так ТС и спрашивает изначально
>
> > Ну зачем было для даты-времени брать тип Double?
>
> а его по привычке лечат.
>

Не эти сначала стырят продукт стоимостью несколько тысяч мериканских енотов, а потом лазят по форумам и скулят, что там что-то не так как им хотелось.


 
DiamondShark ©   (2011-05-19 18:24) [27]


> Мне это тоже непонятно.

Ответов никто не читает?
В дельфи -- для совместимости с OLE.
А вот почему в OLE было выбрано такое представление даты-времени -- это надо у Билли Г. спрашивать.
Хотя, свои резоны тому тоже есть.


 
DiamondShark ©   (2011-05-19 18:38) [28]


> KSergey ©   (19.05.11 15:15) [17]
> Ну так ТС и спрашивает изначально

см.  [5].
Ответ на вопрос "Зачем?" там есть.


> а его по привычке лечат.

Вообще-то, правильное замечание на искусственный пример.
Я тоже могу пример привести:
var x, y: integer;
begin
x := 2147483647;
y := x + 1;
writeln(y);
end.

Тут не то, что тысячная доля секунды теряется, тут вообще творится ад и израиль. Давай, расскажи мне, не "леча", зачем для целых чисел взяли такой дурацкий формат?


 
ов (дом)   (2011-05-20 08:58) [29]


> Dennis I. Komarov ©   (19.05.11 16:29) [21]
> ИМХО, время - не дискретная величина

философия? )
а мб, мб..
 Вот, вроде, Время всегда мерили как засеченное движение чего-либо. т.е., устремляли к пределам, и вот - получали что меньше чем за некое время, ничего не происходит.
Потом фиксировали с более точными приборами более быстрое движение, и объявляли квантом времени более мелкую единицу.
Ну а от этого же не получалось, что и раньше не было таких же движений

Хотя, если не принять что-то за квант времени, точно будет "ад и израиль"


 
KSergey ©   (2011-05-20 09:28) [30]

> DiamondShark ©   (19.05.11 18:24) [27]
> Ответов никто не читает?
> В дельфи -- для совместимости с OLE.

ОЛЕ упоминалось, но я как-то не уловил, что вот так.
Ну тогда да, понятно...



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

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

Наверх





Память: 0.52 MB
Время: 0.004 c
2-1306665558
Kamelot
2011-05-29 14:39
2011.09.11
Как нарисовать картинку, имея массив цветов пикселей?


15-1305794033
Омлет
2011-05-19 12:33
2011.09.11
Секунды теряем из-за Double


2-1306709691
R_R
2011-05-30 02:54
2011.09.11
Как посмотреть первое поле в dbgrid1 по индексу?


2-1306827736
Handle
2011-05-31 11:42
2011.09.11
не определяется версия приложения


3-1263670520
dest81
2010-01-16 22:35
2011.09.11
Firebird set <параметр>= значение





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский