OberonCore
https://forum.oberoncore.ru/

вопрос по арифметике
https://forum.oberoncore.ru/viewtopic.php?f=23&t=3712
Страница 1 из 1

Автор:  ___ [ Пятница, 09 Декабрь, 2011 18:51 ]
Заголовок сообщения:  вопрос по арифметике

добрый день!
подскажите как быть...
простой цикл
i:INTEGER; r:REAL;
Код:
i:=-200;
WHILE i <= 200 DO
r:=i / 10;
Log.Real(r);Log.Ln;
INC(i);
END;


в выводе некоторые числа становятся неточными: вместо 8.2 будет 8.199999999999

в эйфеле, если переменная REAL_32, то результаты на этом отрезке точные, если REAL_64, то точные только 8.0 8.5 9.0

в c# для double выписывает весь диапазон нормально

с чем это связано? что можно почитать по этой теме? и какие способы(рецепты), как в ББ обойти такие случаи (числа 2-3 знака после запятой, операций не много (2-3), так, что будут получаться максимум до 9 знака после запятой, т.е. могут быть вычислены точно)? создавать свои типы и операции к ним (как пару целых (одно перед запятой, другую после))? или есть очевидные способы проще, просто их не вижу?

Автор:  Info21 [ Пятница, 09 Декабрь, 2011 19:25 ]
Заголовок сообщения:  Re: вопрос по арифметике

Считайте с REAL, результат округляйте, да и всё.

Или делайте точную арифметику рациональных чисел из пары Integers.Integer.

Автор:  ___ [ Пятница, 09 Декабрь, 2011 20:05 ]
Заголовок сообщения:  Re: вопрос по арифметике

Info21 писал(а):
Считайте с REAL, результат округляйте, да и всё.

а как правильно округлять?
пусть r=8.1999999999999
Код:
r:=r*10;
r:=ENTIER(r+0.5);
r:=r/10;

но при этом опять получится 8.199999999 из последней команды...

Автор:  Info21 [ Пятница, 09 Декабрь, 2011 20:12 ]
Заголовок сообщения:  Re: вопрос по арифметике

Код:
MODULE x;
   IMPORT  Log := StdLog,  In := i21sysIn,  Math;
   
   PROCEDURE Round*;
      VAR  i: INTEGER; r: REAL;
   BEGIN
      i := -200;
      WHILE i <= 200 DO
         r := i / 10;
         Log.Real( Math.Round( r ) ); Log.Ln;
         INC( i );
      END;
   END Round;

END x.

Автор:  ___ [ Пятница, 09 Декабрь, 2011 21:30 ]
Заголовок сообщения:  Re: вопрос по арифметике

Info21 писал(а):
Код:
MODULE x;
   IMPORT  Log := StdLog,  In := i21sysIn,  Math;
   
   PROCEDURE Round*;
      VAR  i: INTEGER; r: REAL;
   BEGIN
      i := -200;
      WHILE i <= 200 DO
         r := i / 10;
         Log.Real( Math.Round( r ) ); Log.Ln;
         INC( i );
      END;
   END Round;

END x.

это округление до целых, а если нужно до десятых или сотых...
в справке math про round сказано, что идентично floor(р+0.5), а floor идентичен ENTIER, но возвращает real, а не longint....

Автор:  Евгений Темиргалеев [ Пятница, 09 Декабрь, 2011 21:50 ]
Заголовок сообщения:  Re: вопрос по арифметике

___ писал(а):
это округление до целых, а если нужно до десятых или сотых...
До сотых: Log.RealForm( r, 16, 0, -2, " " )
StdLog Docu писал(а):
PROCEDURE RealForm (x: REAL; precision, minW, expW: INTEGER; fillCh: CHAR)
...
expW < 0: fixpoint format with -expW digits after the decimal point.

Автор:  Trurl [ Суббота, 10 Декабрь, 2011 09:30 ]
Заголовок сообщения:  Re: вопрос по арифметике

___ писал(а):
это округление до целых, а если нужно до десятых или сотых...

Код:
Math.Round( r*10 ) /10;

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

Автор:  Info21 [ Суббота, 10 Декабрь, 2011 10:07 ]
Заголовок сообщения:  Re: вопрос по арифметике

___ писал(а):
это округление до целых, а если нужно до десятых или сотых...
Виноват, схватил код из первого сообщения.

Впрочем, ЕЭ уже закрыл тему.

Автор:  ___ [ Суббота, 10 Декабрь, 2011 12:03 ]
Заголовок сообщения:  Re: вопрос по арифметике

Евгений Темиргалеев
спасибо, но вывод я использовал просто для иллюстрации, как внутри алгоритма округлять и сравнивать со значениями...
попробовал присвоить r:=8.2; в выводе все равно получил 8.199999999, значит ошибка не из-за вычислений(82/10), а из-за того что это число в принципе не может храниться точно... поэтому нет функций округлений для переменных тк все равно будет хранить 8.19999999?
и как действовать в случае если выводить на форму? преобразовывать r в строку через Strings.RealToStringForm(r,16,0,-2," ",s) и выводить в строковое поле?

Trurl писал(а):
___ писал(а):
это округление до целых, а если нужно до десятых или сотых...

Код:
Math.Round( r*10 ) /10;

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

т.е. и в др языках просто функция вывода округляет, а внутри переменные такие же?...

а где можно поподробнее про это все почитать? чем это чревато на практике? или просто при выводе округлять, а так коллизий давать не должно? а если над такими числами произведены пара операций ошибки не накопятся?

Автор:  Евгений Темиргалеев [ Суббота, 10 Декабрь, 2011 12:15 ]
Заголовок сообщения:  Re: вопрос по арифметике

___ писал(а):
т.е. и в др языках просто функция вывода округляет, а внутри переменные такие же?...а где можно поподробнее про это все почитать?
Теорию --- что-нибудь по системам счисления; может Info21 что-то хорошее посоветует. По представлению, на которое рассчитан REAL в ББ --- стандарт IEEE; в модуле Math на эту тему есть
Math Docu писал(а):
PROCEDURE Mantissa (x: REAL): REAL
Returns the mantissa of x.

Post
1.0 <= ABS(result) < 2.0 OR result = 0.0
x = INF
result = 1.0
x = -INF
result = -1.0
x = not-a-number
ABS(result) > 1.0

PROCEDURE Exponent (x: REAL): INTEGER
Returns the exponent of x such that x = Mantissa(x) * 2Exponent(x). If x represents ±INF or if x is not-a-number, then MAX(INTEGER) is returned.

PROCEDURE Real (m: REAL; e: INTEGER): REAL
Returns m * 2e. If the argument e is MAX(INTEGER), then INF or not-a-number is returned where ±INF is returned if m = ± 1.0 and not-a-number otherwise. Thus for any real x the equation
x = Real(Mantissa(x), Exponent(x))
holds.
Note: the normal arithmetic operations of the language Component Pascal, and the other operations implemented in this module, never produce the IEEE not-a-number value.
Note: Real(0, 0) = 0.

Pre
(1.0 <= ABS(m) < 2.0) OR (m = 0.0) 20

Post
m = 0.0
result = 0.0

Автор:  ___ [ Суббота, 10 Декабрь, 2011 12:37 ]
Заголовок сообщения:  Re: вопрос по арифметике

в этой теме вроде был затронут вопрос пересекающийся с моим (практический вывод из темы, что смешивать реал и шортреал может быстро погрешности давать%))
там были пара ссылок на лит-ру
Цитата:
Во многих случаях не спасает и длинный формат, не спасет и супер-длинный. Я учился по книге Маккракен, Дорн "Численные методы и программирование на Фортране". Там это хорошо описано. То же самое прекрасно изложено в книге Форсайта. Калиткина не довелось, но убежден, что и там тоже есть.

Цитата:
Не так давно натолкнулся на интересный с моей точки зрения сайт Владимира Юровицкого. У него есть раздел как раз на счёт точности вычислений в ПК и их решения.
http://www.yur.ru/science/computer/index.htm
Здесь он нелестно выражается о IEEE754 http://www.yur.ru/science/computer/IEEE754.htm
А тут, в своей монографии, предлагает решене http://www.yur.ru/science/computer/appro/monografia.htm


попробую почитать
viewtopic.php?f=29&t=3327

Автор:  igor [ Воскресенье, 11 Декабрь, 2011 19:21 ]
Заголовок сообщения:  Re: вопрос по арифметике

___ писал(а):
попробую почитать
viewtopic.php?f=29&t=3327
Ещё вот тут округление чисел обсуждалось, но немного совсем.

Автор:  Роман М. [ Понедельник, 12 Декабрь, 2011 13:47 ]
Заголовок сообщения:  Re: вопрос по арифметике

Теория: What Every Computer Scientist Should Know About Floating-Point Arithmetic, David Goldberg, 1991. Или обработанный материал в формате PDF: [http://www.math.umd.edu/~jkolesar/mait613/floating_point_math.pdf], который лучше читается.

Дополнительная ссылка с форума Oberon Community Platform: Arithmetic aberrations in Java and Oberon.

Автор:  Алексей Елин [ Вторник, 13 Декабрь, 2011 14:50 ]
Заголовок сообщения:  Re: вопрос по арифметике

Вот, очень неплохая обзорная статья на хабре на тему:
http://habrahabr.ru/blogs/cpp/112953/

Автор:  Валерий Лаптев [ Вторник, 13 Декабрь, 2011 15:48 ]
Заголовок сообщения:  Re: вопрос по арифметике

Алексей Елин писал(а):
Вот, очень неплохая обзорная статья на хабре на тему:
http://habrahabr.ru/blogs/cpp/112953/

Да, очень хорошая. Спасибо, студентам ссылочку дам.

Страница 1 из 1 Часовой пояс: UTC + 3 часа
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/