Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 04.05.2008, 21:48   #1
Кронос
Пользователь
 
Регистрация: 29.04.2007
Сообщений: 66
По умолчанию Помогите с поправкой.

Если выполнить действие 1/3 то получим значение 0.333~3
Если полученное число умножить на 3, то получаем значение 0.999~9

Подскажите код. При выполнении которого в ответе будет получаться единица.
Кронос вне форума Ответить с цитированием
Старый 04.05.2008, 22:06   #2
Xardas
Сисадмин
Форумчанин
 
Аватар для Xardas
 
Регистрация: 28.12.2007
Сообщений: 320
По умолчанию

Наверное, round(1/3*3)
Xardas вне форума Ответить с цитированием
Старый 04.05.2008, 22:17   #3
Кронос
Пользователь
 
Регистрация: 29.04.2007
Сообщений: 66
По умолчанию

Не совсем. round округляет число до ближайшего целого значения. Мне же нужна именно поправка, срабатывающая при очень незначительной разнице.
Кронос вне форума Ответить с цитированием
Старый 04.05.2008, 22:39   #4
alexBlack
Участник клуба
 
Регистрация: 12.10.2007
Сообщений: 1,204
По умолчанию

Кронос, нет незначительной разницы. Есть округление, связанное с тем, что дробь 1/3 даже в десятичной системе счисления бесконечная, а мы пытаемся поместить ее в конечную ячейку памяти. (Большинство вещественных чисел непредставимы в виде конечных дробей в двоичной системе счисления).

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

(1/3) * (3/1) будет равно (1/1).
------------------------------------------------

Кстати, для
Aouble
A := 1/3;
label1.Caption := floatToStr(A*3);
показывает точную 1-цу, т.к floatToStr округляет до 15 знака
(A на самом деле = 0,999999999999999944)

extended дает 19 точных знаков. По-моему достаточно для любых применений.
alexBlack вне форума Ответить с цитированием
Старый 04.05.2008, 22:49   #5
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

Кронос, всё далеко не так просто, как Вам кажется (и хотелось бы).. ;-(

проверьте такой пример:
Код:
var R:Single;
 begin
  R:=0.1;
  if R=0.1 then
   Label1.Caption:='Равно'

  else
   Label1.Caption:='Не равно'
 end;
получится 'Не равно'! почему?!

Вот, почитайте (букв много ;-) - но читать ОБЯЗАТЕЛЬНО!!
Неочевидные особенности вещественных чисел
и
Загадки округления

[hr]
Алекс, не успел - Вы опять меня опередили.. ;-) Респект! ;-)
Serge_Bliznykov вне форума Ответить с цитированием
Старый 04.05.2008, 23:06   #6
Кронос
Пользователь
 
Регистрация: 29.04.2007
Сообщений: 66
По умолчанию

Спасибо за инфу.
Кронос вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц