Оберон-технология: особенности и перспективы |
Тематика обсуждения: Оберон-технология. Особенности, перспективы, практическое применение.
Всего в теме 6256 сообщений
Добавить свое сообщение
Отслеживать это обсуждение Обсуждение из раздела Школа ОБЕРОНА
№ 2406 28-01-2007 17:45 | |
Ответ на »сообщение 2404« (PGR)
___________________________
В принципе, я так и считал (в соответствии с определением).
№ 2405 28-01-2007 17:45 | |
Ответ на »сообщение 2403« (AVC)
_______________________
Может быть в нем REAL == long double ? Хотя по стандарту КП вроде-бы не должно.
В Си, например, такое проходит без ошибок.
int main()
№ 2404 28-01-2007 17:21 | |
Первая процедура определяет LDBL_EPSILON, вторая -- DBL_EPSILON
PROCEDURE Eps*;
VAR t1, eps: REAL;
BEGIN
t1 := 1;
REPEAT
eps := t1;
t1 := t1 / 2
UNTIL 1 + t1 = 1;
StdLog.Real(eps); StdLog.Ln
END Eps;
PROCEDURE Eps1*;
VAR t1, t2, eps: REAL;
BEGIN
t1 := 1;
REPEAT
eps := t1;
t1 := t1 / 2;
t2 := 1 + t1
UNTIL t2 = 1;
StdLog.Real(eps); StdLog.Ln
END Eps1;
№ 2403 28-01-2007 17:06 | |
Ответ на »сообщение 2402« (PGR)
___________________________
Ответ на »сообщение 2401« (AVC)
_______________________
Вряд-ли поможет. Это только показывает, что проблема не связана с языком программирования...
Проблема действительно коренится не в языке программирования, а, видимо, в преобразованиях double => long double => double.
Но более аккуратная (?! -- сомнения станут ясны чуть позже) реализация компилятора может ее предотвратить, что показывает моя попытка добиться того же эффекта на другом доступном компиляторе КП - Gardens Point Component Pascal (GPCP).
Там все отрабатывает чисто, без ассертов! :)
Как говорится, "ты не поверишь!!" :)
Правда, по пути я "намучился":
1) Не могу ввести REAL-константу с точкой, приходится действовать "обходными путями" -- писать 1 / 10 вместо 0.1 (что за маразм?!);
2) Пока не добавил ключ компиляции -nodebug, получал сообщение error: ILASM failed to assemble IL file;
3) Math.Eps() пришлось "считать" самому, т.к. модуль Math я пока не обнаружил.
Воистину, "не понос, так золотуха". :)
И еще интересный момент. Граница сравнения проходит при eps, кратном Math.Eps(), то есть множитель n -- целое число. Интересно почему?
Ну, это, кажется, понятно.
Ведь Math.Eps() по сути всего лишь значение самого младшего бита мантиссы (при экспоненте, соответствующей числу 1).
Т.е. все остальные возможные значения мантиссы выражаются через Math.Eps() целочисленно, она как бы "единичка" для мантиссы.
№ 2402 28-01-2007 16:25 | |
Ответ на »сообщение 2401« (AVC)
_______________________
Вряд-ли поможет. Это только показывает, что проблема не связана с языком программирования...
И еще интересный момент. Граница сравнения проходит при eps, кратном Math.Eps(), то есть множитель n -- целое число. Интересно почему?
При dt=0.1 такой вариант проходит, а просто 25 -- нет.
ASSERT(ABS(x-10/dt)<25.00000000000001*Math.Eps())
№ 2401 28-01-2007 13:39 | |
Ответ на »сообщение 2399« (PGR)
___________________________
Эффект полностью воспроизводим в Си (MinGW).
void test(double c, int n)
...
test(0.1, 26);
...
test(0.0001, 21569);
Может быть это как-то поможет...
№ 2400 28-01-2007 12:18 | |
Я вообще не понимаю, что это самое машинное эпсилон даёт. По определению это - минимальное число, для которого выполняется неравенство 1.0+Eps>1.0. При попытке прибавить к единице число, меньшее чем машинное эпсилон, мы должны получить единицу из-за ошибки округления. Но это - оценка погрешности одной только операции, и ожидать, что она окажется универсальной, оснований я не вижу.
№ 2399 28-01-2007 11:47 | |
Ответ на »сообщение 2398« (AVC)
______________________
Ну да -- больше, а где закономерность?
№ 2398 28-01-2007 11:24 | |
Ответ на »сообщение 2397« (PGR)
___________________________
Дальше -- больше. :)
dt=0.0001 -- 21569*Math.Eps()
№ 2397 28-01-2007 10:04 | |
Ответ на »сообщение 2395« (PGR)
____________________
Минимальные eps, при которых выполняется ASSERT:
dt=0.1 -- 26*Math.Eps()
dt=0.01 -- 94*Math.Eps()
dt=0.001 -- 937*Math.Eps()
Добавить свое сообщение
Отслеживать это обсуждение
Дополнительная навигация: |
|