Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Несколько вопросов по работе с вещественными числами


Goorus ©   (2005-07-12 13:18:00) 

1. Возможно ли получать числа, округленные в меньшую сторону? Например число 0.1 на самом деле 0.100000001490116, а возможно ли без дополнительных операций получать 0.9999999...
2. Если первое не возможно, то как можно уменьшить число на наименьшую величину, т.е. аналог "Dec" для вещественных чисел? А то умножение на 0.99999 (пока так работает) не всегда может дать нужный результат.
3. Возможно ли не получать ошибки "Floating point overflow", а результат имел бы значение Infinite или 0?
4. Как получить порядок числа? Т.е. числа хранятся в виде 1.2e-23, 3.3+37, так вот необходимо получить -23 и 37 соответственно.

Помогите, пожалуйста :)


Goorus   (2005-07-13 18:17:00) [1]

>> Amoeba
И эту читал :(

>> Alex Konshin
Вообще-то нет, у меня это работает :)

>> sniknik
Как всегда, потому что у меня ошибка в другом юните! :)


Amoeba   (2005-07-13 17:09:00) [2]

Автору вопроса рекомендую прочесть вот эту статью:
http://www.delphikingdom.com/asp/viewitem.asp?catalogid=374


Alex Konshin   (2005-07-13 14:14:00) [3]

Goorus ©   (13.07.05 04:10) [9]
Но ведь идея та же. Разве здесь большая разница?

Большая разница. У тебя цикл на ровном месте.


sniknik   (2005-07-13 10:54:00) [4]

там нет "борьбы" с вещественными числами. интересно почему?


Goorus   (2005-07-13 10:31:00) [5]

По этой статье и делаю.


sniknik   (2005-07-13 08:51:00) [6]

http://www.gamedev.ru/articles/?id=30109


Goorus   (2005-07-13 04:10:00) [7]

>> uny
Думал над этим, похоже прийдётся делать именно так.

>> Defunct
Но ведь идея та же. Разве здесь большая разница?

TimeFirst := (m2 - m1) / speed * 0.999999
TimeFirst := (m2 - m1) / speed - E

>> Скажите прямо, что конкретно Вы расчитываете
:) Для проверки на столкновения, реализую "Метод разделяющих осей". Проблема в процедуре, находящей время столкновения на оси. Нужно вычислить время точно, либо меньше, чем реальное время столкновения, иначе объекты войдут друг в друга, а уже потом это столкновение будет обрабатываться.


Defunct   (2005-07-12 22:42:00) [8]

Goorus ©   (12.07.05 19:28) [6]
Опять ведь ерунду пишете.

что мешает просто взять и решить неравенство:
(m1 + TimeFirst * speed) > m2      (1)
TimeFirst*speed > m2 - m1          (2)
TimeFirst > (m2 - m1)/speed        (3)

а теперь расчитываем TimeFirst в одно действие:
TimeFirest := (me - m1)/speed + E  (4)
E добавляет строгостии определяется Вами как обычная константа, например, (E = 0.000001)
А вообще, сформулируйте лучше Вашу главную задачу, а не какие-то попутные проблемы с 0.99999. Скажите прямо, что конкретно Вы расчитываете и, вероятно, дельных ответов прибавится.

Goorus ©   (12.07.05 19:28) [6]
>> Defunct
> Не смешно.

Кому как, знакомым ребятам было смешно. Вам, разумеется - не смешно, ну что ж, уж извините. А вообще не давайте повода для насмешек -  задавая вопрос перечитайте его как следует раз пять.

PS: Ваша проблема, с моей точки зрения, выглядит надумано. Может быть имеет место ошибка в алгоритме, которая привела Вас к таким тупиковым ситуациям.


uny   (2005-07-12 19:44:00) [9]

[6] Goorus ©   (12.07.05 19:28)
не знаю правильно это или нет, скорее нет, но работает -
можно extended "разобрать". он состоит из 10 байт = двух 32 битных целых чисел - "мантиса" и 16 битное число со знаком - "порядок".
Разобрав число, получите прямой доступ к внутренности числа и сможете ровнять как душе угодно. и записывать обратно в число.

достать любое из этих состовляющих легко - искать рядом с адресом extended. (pointer на него)
например адрес = А,
1-е 32-битное число можно считать из памяти по адресу A
2-е по адресу A+4
порядок - A+8
я проделылывал это для удовольствия :), в asm вставках.
Печатаю на память, возможны неточности, но сам принцип действующий.


Goorus   (2005-07-12 19:28:00) [10]

Пояснение к 1, 2. Дело в том, что в результате вычислений получается приблизительное число. Возможно проверить больше оно или меньше правильного результата (через обратную функцию). Но необходимо, чтобы это число было именно меньше! Или равно, но не в коем случае не превышало искомого значения. Пока у меня такой код:

while (m1 + TimeFirst * speed) > m2 do
     TimeFirst := TimeFirst * 0.999999;

Ну не нравится мне это "* 0.999999", а как правильно сделать не знаю :(

>> Defunct
Не смешно.

>> TUser
2-ое интересно, но не то. Если в моём случае TimeFirst будет порядка e+6 и будет отниматься e-36 (или -37 не помню точно), то будет бесконечный цикл, т.к. в этом случае это вычитаени эффекта иметь не будет.
3. Хорошо бы.. А отлаживать как? Эта процедура должно вызываться много-много-много.. раз в секунду, а на Д2005 я пока не хочу переходить, а в 7-ом или вообще отказаться от сообщений компилятора, или каждый раз нажимать на Ф9, что не реально.
4. Log10(TimeFirst) тоже выдаёт эту ошибку "Floating point overflow", поэтому я сюда и обратился.

>> DiamondShark
Точно?

>> uny
Я понимаю проблему, я не знаю как её решить.

Сижу, читаю сравку..


uny   (2005-07-12 18:22:00) [11]

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


DiamondShark   (2005-07-12 17:22:00) [12]


> Т.е. числа хранятся в виде 1.2e-23, 3.3+37

Не хранятся они в таком виде.


TUser   (2005-07-12 16:52:00) [13]

1. Format и другие аналогичные функции
2. ??
function TechEpsilon: double;
var j: double;
begin
 result:=0.00001; j:=result;
 while j > 0 do begin
   result:=j;
   j:=j/2;
   end;
end;

3. try..except?
4. Логарифмы?


Defunct   (2005-07-12 16:23:00) [14]

> Юрий Зотов
Попробую интерпретировать вопросы:
1. А можно ли писать программы сразу с багами?
2. А то багов пока не хватает...


Юрий Зотов   (2005-07-12 15:53:00) [15]

1. Вопрос не понял.
2. Вопрос не понял.
3. Посмотрите Get/SetExceptionMask в модуле Math и в справке.
4. Посмотрите Frexp там же.


Наверх

Титульная страница Поиск, карта сайта Написать письмо