Форум: "Основная";
Текущий архив: 2005.07.31;
Скачать: [xml.tar.bz2];
ВнизНесколько вопросов по работе с вещественными числами Найти похожие ветки
← →
Goorus © (2005-07-12 13:18) [0]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 соответственно.
Помогите, пожалуйста :)
← →
Юрий Зотов © (2005-07-12 15:53) [1]1. Вопрос не понял.
2. Вопрос не понял.
3. Посмотрите Get/SetExceptionMask в модуле Math и в справке.
4. Посмотрите Frexp там же.
← →
Defunct © (2005-07-12 16:23) [2]> Юрий Зотов
Попробую интерпретировать вопросы:
1. А можно ли писать программы сразу с багами?
2. А то багов пока не хватает...
← →
TUser © (2005-07-12 16:52) [3]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. Логарифмы?
← →
DiamondShark © (2005-07-12 17:22) [4]
> Т.е. числа хранятся в виде 1.2e-23, 3.3+37
Не хранятся они в таком виде.
← →
uny © (2005-07-12 18:22) [5]автор, числа в двоичном виде хранятся, все получаемые числа - степени двойки. попробуйте вручную сделать что Вы хотите,
например переведите 0.1 в двоичный вид. сразу идеи будут. это не шутка.
← →
Goorus © (2005-07-12 19:28) [6]Пояснение к 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 19:44) [7][6] Goorus © (12.07.05 19:28)
не знаю правильно это или нет, скорее нет, но работает -
можно extended "разобрать". он состоит из 10 байт = двух 32 битных целых чисел - "мантиса" и 16 битное число со знаком - "порядок".
Разобрав число, получите прямой доступ к внутренности числа и сможете ровнять как душе угодно. и записывать обратно в число.
достать любое из этих состовляющих легко - искать рядом с адресом extended. (pointer на него)
например адрес = А,
1-е 32-битное число можно считать из памяти по адресу A
2-е по адресу A+4
порядок - A+8
я проделылывал это для удовольствия :), в asm вставках.
Печатаю на память, возможны неточности, но сам принцип действующий.
← →
Defunct © (2005-07-12 22:42) [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: Ваша проблема, с моей точки зрения, выглядит надумано. Может быть имеет место ошибка в алгоритме, которая привела Вас к таким тупиковым ситуациям.
← →
Goorus © (2005-07-13 04:10) [9]>> uny
Думал над этим, похоже прийдётся делать именно так.
>> Defunct
Но ведь идея та же. Разве здесь большая разница?
TimeFirst := (m2 - m1) / speed * 0.999999
TimeFirst := (m2 - m1) / speed - E
>> Скажите прямо, что конкретно Вы расчитываете
:) Для проверки на столкновения, реализую "Метод разделяющих осей". Проблема в процедуре, находящей время столкновения на оси. Нужно вычислить время точно, либо меньше, чем реальное время столкновения, иначе объекты войдут друг в друга, а уже потом это столкновение будет обрабатываться.
← →
sniknik © (2005-07-13 08:51) [10]http://www.gamedev.ru/articles/?id=30109
← →
Goorus © (2005-07-13 10:31) [11]По этой статье и делаю.
← →
sniknik © (2005-07-13 10:54) [12]там нет "борьбы" с вещественными числами. интересно почему?
← →
Alex Konshin © (2005-07-13 14:14) [13]Goorus © (13.07.05 04:10) [9]
Но ведь идея та же. Разве здесь большая разница?
Большая разница. У тебя цикл на ровном месте.
← →
Amoeba © (2005-07-13 17:09) [14]Автору вопроса рекомендую прочесть вот эту статью:
http://www.delphikingdom.com/asp/viewitem.asp?catalogid=374
← →
Goorus © (2005-07-13 18:17) [15]>> Amoeba
И эту читал :(
>> Alex Konshin
Вообще-то нет, у меня это работает :)
>> sniknik
Как всегда, потому что у меня ошибка в другом юните! :)
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2005.07.31;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.033 c