Перейти к содержанию
Fire Monkey от А до Я
  • 0

Почему отладчик показывает значение вещественной переменной типа Single, не 0.3, а 0.3000000001192029?


Dozent

Вопрос

Рекомендуемые сообщения

  • 0

так и должно быть.
 
Обрезать? смотря для чего. Для представления в виде строки может и нужно будет. Вот код, поэкспериментируйте с 2 последними цифрами:

var
  a: Double = 0.300000011920929;

procedure TForm1.Button1Click(Sender: TObject);
begin
   ShowMessage( FloatToStrF( a, TFloatFormat.ffFixed, 4, 2  ) );
end;

> В райнтайме отображается 0,3!

 

Посмотрите какое значение указано в параметре DecimalDigits

Ссылка на комментарий
  • 0
  • Администраторы

Полезная информация о представлении вещественных чисел в компьютере, объясняющая почему нельзя получить значение 0,3 в машинном представлении:

Ссылка на комментарий
  • 0

Вообще я тоже с этим столкнулся, правда во время анимации. И из-за "длинного хвоста" анимация срабатывала не всегда. Не сразу понял почему.

Анимация делалась для Андроид приложения. Нажимая на Recntangle он увеличивался в высоту с плавной анимацией, а при повторном нажатии возвращался в исходное состояние.

Так вот в коде на нажатие шло сравнение в духе

if Heigh = 80 then AnimationFloat('Heigh', 150);
if Heigh = 150 then AnimationFloat('Heigh', 80);

Ну и как следствие оказалось что не всегда 80, это именно 80, бывает и 80,000139 и т.к. разные вариации были.

Пришлось код усложнить малость.

Так что о таких вещах надо помнить.

Ссылка на комментарий
  • 0
  • Администраторы

Это основы языка и основы работы с вещественными числами. Для таких сравнений нужно использовать функции из System.Math.SameValue

Ссылка на комментарий
  • 0

Я абсолютно согласен с Ярославом на счет "основы работы с вещественными числами", просто хочу добавить, что тоже сталкивался с такими ситуациями, но не считаю их за проблему и решал простыми условиями типа

if Trunc(Height) = 80 then AnimationFloat('Height', 150);
if Trunc(Height) = 150 then AnimationFloat('Height', 80);

Только вот писать их друг за другом не рекомендую. Условие нужно изменить на типа:

if Trunc(Height) = 80 then
  AnimationFloat('Height', 150)
  else
  if Trunc(Height) = 150 then
    AnimationFloat('Height', 80);

так как в Вашем случае может возникнуть ситуация, когда высота элемента может измениться уже до проверки второго условия (хотя на практике это случается очень редко).

Либо тогда "дождаться" изменения высоты и написать так:

if Trunc(Height) = 80 then AnimationFloatWait('Height', 150);
if Trunc(Height) = 150 then AnimationFloat('Height', 80);
Изменено пользователем AlexG
Ссылка на комментарий
  • 0

Height

 

if Height = 80 then AnimationFloat('Height', 150);
if Height = 150 then AnimationFloat('Height', 80);

 

if Trunc(Height) = 80 then AnimationFloat('Height', 150);
if Trunc(Height) = 150 then AnimationFloat('Height', 80);
if Trunc(Height) = 80 then
  AnimationFloat('Height', 150)
  else
  if Trunc(Height) = 150 then
    AnimationFloat('Height', 80);
if Trunc(Height) = 80 then AnimationFloatWait('Height', 150);
if Trunc(Height) = 150 then AnimationFloat('Height', 80);
Ссылка на комментарий
  • 0

 

Я абсолютно согласен с Ярославом на счет "основы работы с вещественными числами", просто хочу добавить, что тоже сталкивался с такими ситуациями, но не считаю их за проблему и решал простыми условиями типа

if Trunc(Height) = 80 then AnimationFloat('Height', 150);
if Trunc(Height) = 150 then AnimationFloat('Height', 80);

Только вот писать их друг за другом не рекомендую. Условие нужно изменить на типа:

if Trunc(Height) = 80 then
  AnimationFloat('Height', 150)
  else
  if Trunc(Height) = 150 then
    AnimationFloat('Height', 80);

так как в Вашем случае может возникнуть ситуация, когда высота элемента может измениться уже до проверки второго условия (хотя на практике это случается очень редко).

Либо тогда "дождаться" изменения высоты и написать так:

if Trunc(Height) = 80 then AnimationFloatWait('Height', 150);
if Trunc(Height) = 150 then AnimationFloat('Height', 80);

 

Спасибо, но как я уже писал, что код я уже сделал путем его усложнения. И конечно же почти таким же методом.

Вообще на Andoid (именно для него я делал эту анимацию и на Win не проверял), возникала проблема другого рода, иногда (редко), анимация приводила не к точным значениям (150 и 80), будь то просто  AnimationFloat или AnimationFloatWait.

И по итогу значение не было 150, и даже не было 150.000000147 или типа того, бывало и вот так - 149,999989.....

Для решения пришлось использовать только AnimationFloatWait, и сразу следом за ним делать Height := 150.00;

 

Итогом всего этого стало самовольное решение уйти от такого подхода в программе в целом, ибо если уже все не так изящно, как хотелось бы, то значит надо пересилить себя и искать иной поход. Ну и кстати по другому оказалось куда удобнее и быстрее. :)

Ссылка на комментарий

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить на вопрос...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...