Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.71/7: Рейтинг темы: голосов - 7, средняя оценка - 4.71
0 / 0 / 0
Регистрация: 18.04.2019
Сообщений: 20
1

Про решения погрешности float

08.08.2019, 22:51. Показов 1335. Ответов 6
Метки нет (Все метки)

1)Допустим есть такой вот вечный цикл:
C++
1
for (float a = 0.0; a < 10000000.0; a += 0.1f);
Есть варианты работоспособной страховки кроме ассерта после if (a == (a + 0.1f)) и double? Т.е как получить минимальное значение для инкремента?

2)Работаю с Directx, и матрицами с 32-битными элементами. Менять разрядность не хотелось бы по соображениям производительности и потребления памяти. Будет ли хорошим выходом из ситуации хранить исходные координаты в double, а для отрисовки трансформировать их относительно камеры (например, камера имеет позицию по оси X - 90050.1, а объект - 90000.1, для отрисовки использовать для камеры 50.1, а объекта - 0.0)? Если миновать подобные трюки, то погрешность при отрисовке дает о себе знать.

3)Как получить погрешность при сложении двух float в double?
0

Помощь в написании контрольных, курсовых и дипломных работ здесь.

Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
08.08.2019, 22:51
Ответы с готовыми решениями:

опять ошибка.на этот раз cannot convert `float (*)(float)' to `float' in argument passing
#include&lt;stdio.h&gt; #include&lt;stdlib.h&gt; #include&lt;math.h&gt; float f1(float x)/*vira*enie 1*/ ...

Чем отличаются float преобразования (float)var от float(var)
Здравствуйте! Подскажите, чем отличается (float)var от float(var)

invalid types `float[float]' for array subscript
void SEARCH(float vol, float price, int i) { if (i&gt;N) { if(price&gt;maxprice) ...

Неправильное приведение void* к *float а далее к float
Почему когда привожу void* к int* потом к int то все работает, данные не бьются и работают...

6
4339 / 2397 / 995
Регистрация: 07.02.2019
Сообщений: 6,288
09.08.2019, 00:52 2
Хостес, если вы моделируете галактику и хотите обрабатывать перемещения и физику в масштабе 0,1м, например, то это не очень разумно, для этих целей используют декорации, которые предварительно рендерят в другом масштабе, а потом "натягивают на небо".
Посмотрите эту статью, может будет полезно: http://davenewson.com/posts/20... cales.html
2
2146 / 691 / 265
Регистрация: 10.02.2018
Сообщений: 1,622
09.08.2019, 15:43 3
Цитата Сообщение от Хостес Посмотреть сообщение
как получить минимальное значение для инкремента?
Это значение будет зависеть от экспоненты числа, грубо говоря, от порядка числа. Чем больше порядок, тем больше шаг. Для числа 10000000 шаг равен 512.
Кликните здесь для просмотра всего текста
Тест:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <conio.h>
#include <stdio.h>
 
int main()
{
    union TestFloat
    {
        float val;
 
        struct
        {
            unsigned int s : 1;
            unsigned int e : 8;
            unsigned int m : 23;
        } bits;
    };
 
    TestFloat test;
    test.val = 10000000.f;
 
    printf("float=%f\n", test.val);
    //printf("double=%f\n", ((test.bits.s) ? -1.0 : 1.0) * ((test.bits.e) ? (test.bits.m | 0x800000) : (test.bits.m << 1)) * pow(2, 127 - test.bits.e));
 
    printf("s=%d, e=%d, m=%d\n", test.bits.s, test.bits.e, test.bits.m);
 
    printf("m++\n");
    test.bits.m++;
 
    printf("s=%d, e=%d, m=%d\n", test.bits.s, test.bits.e, test.bits.m);
 
    printf("float=%f\n", test.val);
    //printf("double=%f\n", ((test.bits.s) ? -1.0 : 1.0) * ((test.bits.e) ? (test.bits.m | 0x800000) : (test.bits.m << 1)) * pow(2, 127 - test.bits.e));
 
    return 0;
}
Результат:
Код
float=10000000.000000
s=0, e=64, m=2460747
m++
s=0, e=64, m=2460748
float=10000512.000000

Согласен с zayats80888, для подобных задач лучше поискать качественно иной подход, а не наращивать разрядность.

Добавлено через 2 часа 9 минут
Накосячил в тесте выше с порядком полей. Для 10'000'000 шаг получается равен 1.
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <conio.h>
#include <stdio.h>
#include <math.h>
 
int main()
{
    union TestFloat
    {
        float val;
 
        struct
        {
            unsigned int m : 23;
            unsigned int e : 8;
            unsigned int s : 1;
        } bits;
    };
 
    TestFloat test;
    test.val = 100000000.f;
 
    printf("float=%f\n", test.val);
    //printf("double=%f\n", ((test.bits.s) ? -1.0 : 1.0) * ((test.bits.e) ? (test.bits.m | 0x800000) : (test.bits.m << 1)) * pow(2.0, test.bits.e - 150.0));
 
    printf("s=%d, e=%d, m=%d\n", test.bits.s, test.bits.e, test.bits.m);
 
    printf("m++\n");
    test.bits.m++;
 
    printf("s=%d, e=%d, m=%d\n", test.bits.s, test.bits.e, test.bits.m);
 
    printf("float=%f\n", test.val);
    //printf("double=%f\n", ((test.bits.s) ? -1.0 : 1.0) * ((test.bits.e) ? (test.bits.m | 0x800000) : (test.bits.m << 1)) * pow(2.0, test.bits.e - 150.0));
 
    return 0;
}


Результат:
Код
float=10000000.000000
s=0, e=150, m=1611392
m++
s=0, e=150, m=1611393
float=10000001.000000
0
Don't worry, be happy
17173 / 10056 / 1935
Регистрация: 27.09.2012
Сообщений: 25,053
Записей в блоге: 1
09.08.2019, 15:54 4
Цитата Сообщение от Ygg Посмотреть сообщение
Накосячил в тесте выше с порядком полей
C++
1
std::nextafter(10000000.0f, std::numeric_limits<float>::infinity())
2
2146 / 691 / 265
Регистрация: 10.02.2018
Сообщений: 1,622
09.08.2019, 16:08 5
Croessmah, всё уже придумано до нас, нужно только знать где
0
0 / 0 / 0
Регистрация: 18.04.2019
Сообщений: 20
10.08.2019, 20:28  [ТС] 6
Цитата Сообщение от zayats80888 Посмотреть сообщение
если вы моделируете галактику и хотите обрабатывать перемещения и физику в масштабе 0,1м
Я моделирую небольшой мирок, с размерами в пределах 10x10 км, и при перемещениях в десятую миллиметра за фрейм (100 фреймов в секунду для физики) и менее начинаются проблемы со скоростью вплоть до её полного отсутствия. Это особенность инкремента float, так что наверное все же перейду на числа с фиксированной запятой.

Цитата Сообщение от zayats80888 Посмотреть сообщение
Посмотрите эту статью, может будет полезно
Спасибо, думаю именно это и решит проблему с выводом графики.
0
6738 / 4537 / 1839
Регистрация: 07.05.2019
Сообщений: 13,725
Записей в блоге: 1
10.08.2019, 20:47 7
Цитата Сообщение от Хостес Посмотреть сообщение
Я моделирую небольшой мирок, с размерами в пределах 10x10 км, и при перемещениях в десятую миллиметра за фрейм (100 фреймов в секунду для физики) и менее начинаются проблемы со скоростью вплоть до её полного отсутствия. Это особенность инкремента float, так что наверное все же перейду на числа с фиксированной запятой.
Тебе там вообще не нужна арифметика с плавающей точкой. Там все должно влазить в 32-битное целое.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
10.08.2019, 20:47

cannot convert `float' to `float*. Почему так происходит?
всем привет, помогите исправить ошибки... а то голова мало варит уже, а завтра надо сдать уже ...

Оценка погрешности решения СЛАУ
Добрый вечер всем. Есть СЛАУ - 4 неизвестных, 4 уравнения, которую необходимо решить и оценить...

Определения по теме Погрешности и методы решения СЛАУ
Добрый день. 1. Подскажите пожалуйста литературу для понимания Матриц. Вчера проходили методы:...

про float элементы и их родителя
я уверен что этот вопрос очень прост, однако, почему при такой структуре у main не задается фон...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.