The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

форумы  помощь  поиск  регистрация  майллист  вход/выход  слежка  RSS
"Использование NaN, inf как маркеров инициализации переменных"
Вариант для распечатки  
Пред. тема | След. тема 
Форумы Программирование под UNIX (Public)
Изначальное сообщение [ Отслеживать ]

"Использование NaN, inf как маркеров инициализации переменных"  +/
Сообщение от ghostinmachine email on 07-Окт-09, 21:15 
Здравствуйте.
В своих программах (числодробилки) мне приходиться иногда ставить маркеры неинециализированлости значения переменных. Есть идея применять константы типа NaN, Inf для обозначения таких чисел т.к. их легко отслеживать при отладке/запуске приложения. Вопрос в том грозит ли это чем-то самому коду (быстродействию, переносимости и т.п.) и как корректно присваивать такие значения переменным (скажем без деления на ноль) т.к. в манах нашел только проверку этих констант.
Спасибо.  
Высказать мнение | Ответить | Правка | Cообщить модератору

Оглавление

Сообщения по теме [Сортировка по времени | RSS]


1. "Использование NaN, inf как маркеров инициализации переменных"  +/
Сообщение от аноним on 07-Окт-09, 23:33 
С какой стати это должно чем-то грозить? Использование пограничных значений float'ов может даже прибавить скорости, если позволит выкинуть проверки каких-то флагов и избавиться таким образом от ветвлений. Другое дело, если у вас вдруг будет isnanf вызываться в каком-нибудь внутреннем цикле (что теоретически может быть медленее проверки флага) - но в таком случае можно порекоммендовать только больше никогда не писать числодробилки.
Что касается переносимости, в math.h определены все нужные константы, в частности NAN и INFINITY, точно это посмотреть можно в стандартах. Люниксовый math.h отсылает напрямую к

/*
*  ISO C99 Standard: 7.12 Mathematics  <math.h>
*/

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

2. "Использование NaN, inf как маркеров инициализации переменных"  +/
Сообщение от pavlinux (ok) on 08-Окт-09, 23:35 
>Здравствуйте.
>В своих программах (числодробилки) мне приходиться иногда ставить маркеры неинециализированлости значения переменных.
>Есть идея применять константы типа NaN, Inf для обозначения таких чисел
>т.к. их легко отслеживать при отладке/запуске

А толку,  НАН в дебугере светится как 0.0000, INF как 1.00000

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

3. "Использование NaN, inf как маркеров инициализации переменных"  +/
Сообщение от аноним on 12-Окт-09, 14:20 
>А толку,  НАН в дебугере светится как 0.0000, INF как 1.00000

Ну да, а 0xFF как 1, а 0 как 0xdeadbeef. Не пори чушь.

float a = NAN, b = INFINITY;
---
(gdb) print a
$1 = nan(0x400000)
(gdb) print b
$2 = inf

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

4. "Использование NaN, inf как маркеров инициализации переменных"  +/
Сообщение от pavlinux (ok) on 12-Окт-09, 15:41 
>[оверквотинг удален]
>
>Ну да, а 0xFF как 1, а 0 как 0xdeadbeef. Не пори
>чушь.
>
>float a = NAN, b = INFINITY;
>---
>(gdb) print a
>$1 = nan(0x400000)
>(gdb) print b
>$2 = inf

Докажи что это переменная "a", а не переполнение или не глюк (ядра, оперативки, проца, gdb )

А млин, и правда работает

Starting program: /tmp/a.out ;
main () at test.c:11
11       a = NAN; b = INFINITY;
(gdb) print a
$1 = 0
(gdb) print b
$2 = 0
(gdb) step
13      return 0;
(gdb) print b
$3 = inf
(gdb) print a
$4 = nan(0x400000)
(gdb) step
14      }
(gdb) step
0x00007f2804938b54 in __libc_start_main () from /lib64/libc.so.6


А в Netbeans сцука, именно 1.000 и 0.000 показывает.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

6. "Использование NaN, inf как маркеров инициализации переменных"  +/
Сообщение от svn (??) on 13-Окт-09, 10:33 
>А в Netbeans сцука, именно 1.000 и 0.000 показывает.

В нем вообще очень слабый отладчик С программ. Даже с сигналами работать не умеет.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

8. "Использование NaN, inf как маркеров инициализации переменных"  +/
Сообщение от ghostinmachine email on 13-Окт-09, 19:04 
>
>Докажи что это переменная "a", а не переполнение или не глюк (ядра,
>оперативки, проца, gdb )
>

Это не важно, если всплыл маркер - значит с кодом проблема, надо отлаживать.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

11. "Использование NaN, inf как маркеров инициализации переменных"  +/
Сообщение от аноним on 13-Окт-09, 20:01 
>Докажи что это переменная "a", а не переполнение или не глюк (ядра,
>оперативки, проца, gdb )

Тяжелый случай.

>А в Netbeans сцука, именно 1.000 и 0.000 показывает.

На бейсике пиши.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

5. "Использование NaN, inf как маркеров инициализации переменных"  +/
Сообщение от f00l (ok) on 13-Окт-09, 08:18 
>Вопрос в том грозит
>ли это чем-то самому коду (быстродействию, переносимости и т.п.)

Использование float и double в коде ведет к существенному замедлению работы программы. И когда нужна скорость выполнение применять не  следует.

P.S. да и вобше формат float бесполезный, всегда обходился без него. всего 6 значаших чисел, абсолютной точности нет , а 6 разрядов можно и через int обрабатывать .    

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

7. "Использование NaN, inf как маркеров инициализации переменных"  +/
Сообщение от ghostinmachine email on 13-Окт-09, 18:59 
>>Вопрос в том грозит
>>ли это чем-то самому коду (быстродействию, переносимости и т.п.)
>
>Использование float и double в коде ведет к существенному замедлению работы программы.
>И когда нужна скорость выполнение применять не  следует.
>
> P.S. да и вобше формат float бесполезный, всегда обходился без него.
>всего 6 значаших чисел, абсолютной точности нет , а 6 разрядов
>можно и через int обрабатывать .

Интересное ответвление: каков приюлизительно прирост производительности при переходе от float к int на AMD( Intell) x86_64? ведь надо покрывать проверку переполнения int, компенсирует ли?

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

10. "Использование NaN, inf как маркеров инициализации переменных"  +/
Сообщение от аноним on 13-Окт-09, 19:59 
См. ниже и не слушай идиотов.
Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

9. "Использование NaN, inf как маркеров инициализации переменных"  +/
Сообщение от аноним on 13-Окт-09, 19:58 
>Использование float и double в коде ведет к существенному замедлению работы программы.
>И когда нужна скорость выполнение применять не  следует.

Вообще-то, наоборот. Вот простой alpha blend.

#include <stdio.h>
#include <stdlib.h>
#include <sys/limits.h>
#include <sys/types.h>

#define SIZE    1024*1024
#define ITERS   512

#if defined FLOAT
# define TYPE float
#elif defined DOUBLE
# define TYPE double
#elif defined SHORT
# define TYPE unsigned short
# define MAX USHRT_MAX
#elif defined INT
# define TYPE unsigned int
# define MAX UINT_MAX
#else
#error please define FLOAT, DOUBLE, SHORT or INT
#endif

int main() {
        int i,j;
        srand(234234234);

        TYPE color1[SIZE];
        TYPE color2[SIZE];
        TYPE alpha[SIZE];
        TYPE output[SIZE];

        for (i = 0; i < SIZE; ++i) {
#if defined(FLOAT) || defined(DOUBLE)
                color1[i] = (float)rand()/(float)RAND_MAX;
                color2[i] = (float)rand()/(float)RAND_MAX;
                alpha[i] = (float)rand()/(float)RAND_MAX;
#else
                color1[i] = MAX*(float)rand()/(float)RAND_MAX;
                color2[i] = MAX*(float)rand()/(float)RAND_MAX;
                alpha[i] = MAX*(float)rand()/(float)RAND_MAX;
#endif
        }

        for (j = 0; j < ITERS; ++j)
                for (i = 0; i < SIZE; ++i)
#if defined(FLOAT) || defined(DOUBLE)
                        output[i] = (color1[i]*alpha[i] + color2[i]*(1-alpha[i]));
#elif defined(INT)
                        output[i] = ((uint64_t)color1[i]*alpha[i] + (uint64_t)color2[i]*(MAX-alpha[i]))/MAX;
#else
                        output[i] = (color1[i]*alpha[i] + color2[i]*(MAX-alpha[i]))/MAX;
#endif

#if defined(FLOAT) || defined(DOUBLE)
        printf("blend(%.4f, %.4f, %.4f) = %.4f\n", color1[0], color2[0], alpha[0], output[0]);
#else
        printf("blend(%.4f, %.4f, %.4f) = %.4f\n",
                        (float)color1[0]/(float)MAX,
                        (float)color2[0]/(float)MAX,
                        (float)alpha[0]/(float)MAX,
                        (float)output[0]/(float)MAX);
#endif

        return 0;
}

Вот так оно работает на 64bit машине. Как видите float всех рвет. Не буду приводить результат на 32бин машине, ибо 64бит арифметика убивает там все вообще нахрен (а без нее будем терять точность).

% make test
cc -O2 test.c -DFLOAT -o float
cc -O2 test.c -DDOUBLE -o double
cc -O2 test.c -DSHORT -o short
cc -O2 test.c -DINT -o int
time ./float
blend(0.2036, 0.0478, 0.8507) = 0.1803
        1,87 real         1,87 user         0,00 sys
time ./double
blend(0.2036, 0.0478, 0.8507) = 0.1803
        3,74 real         3,68 user         0,02 sys
time ./short
blend(0.2036, 0.0478, 0.8507) = 0.1803
        2,03 real         2,03 user         0,00 sys
time ./int
blend(0.2036, 0.0478, 0.8507) = 0.1803
        2,20 real         2,15 user         0,03 sys

> P.S. да и вобше формат float бесполезный, всегда обходился без него.
>всего 6 значаших чисел, абсолютной точности нет , а 6 разрядов
>можно и через int обрабатывать .

Да и вообще, вы ламер, хотя бы из-за категоричности высказываний и из-за бреда с 6 значащими числами (что вы вообще в виду имели?). Для любой задачи почти всегда можно точно сказать, что лучше использовать - float, fixed point или свою реализацию с произвольной точностью.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

12. "Использование NaN, inf как маркеров инициализации переменных"  +/
Сообщение от f00l (ok) on 14-Окт-09, 08:45 
>>Использование float и double в коде ведет к существенному замедлению работы программы.
>>И когда нужна скорость выполнение применять не  следует.
>
>Вообще-то, наоборот. Вот простой alpha blend.

Пример не корректный. при работе с int зачем то идет преобразование во float, если работаешь с int так и работай. Идет лишняя операция вот и падение производительности.
И потом тест длительностью 2 сек не о чем не говорит.
Вот сделай преобразование Фурье во float и int и прогони 10 мин звуковой информации вот там и увидишь реальную производительность.

>Да и вообще, вы ламер, хотя бы из-за категоричности высказываний и из-за
>бреда с 6 значащими числами (что вы вообще в виду имели?).
>Для любой задачи почти всегда можно точно сказать, что лучше использовать
>- float, fixed point или свою реализацию с произвольной точностью.

Читай внимательно стандарт IEEE 754. (Стандарты читать полезно)

Практически в любой задачи можно обойтись без float. Это просто нужно понимать задачу.

P.S. хотя есть процессоры где поддержка стандарта float реализована аппаратно там применение обосновано.    

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

14. "Использование NaN, inf как маркеров инициализации переменных"  +/
Сообщение от аноним on 14-Окт-09, 15:25 
> Пример не корректный.

Более, чем корректный.

>при работе с int зачем то идет преобразование
>во float, если работаешь с int так и работай.

Это называется fixed point, неуч. Числа только выводятся как float, чтобы результат одинаково выглядел.

>Идет лишняя операция вот и падение производительности.

Потеря в генерации и распечатке, когда blend выполняется в 512 раз больше? Не смеши.

>И потом тест длительностью 2 сек не о чем не говорит.

Бгыгы. Ну поменяй константы, ты же можешь. Вот с размером 1024 и миллионом итераций:

time ./float
blend(0.2036, 0.0478, 0.8507) = 0.1803
        1,99 real         1,99 user         0,00 sys
time ./double
blend(0.2036, 0.0478, 0.8507) = 0.1803
        2,02 real         2,02 user         0,00 sys
time ./short
blend(0.2036, 0.0478, 0.8507) = 0.1803
        3,77 real         3,77 user         0,00 sys
time ./int
blend(0.2036, 0.0478, 0.8507) = 0.1803
        3,71 real         3,71 user         0,00 sys
nice make test  11,66s user 0,05s system 92% cpu 12,644 total

Инты сливают еще больше.

> Вот сделай преобразование Фурье во float и int и прогони 10
>мин звуковой информации вот там и увидишь реальную производительность.

Думаешь, не делал? Какие там вообще инты нахрен? Возьми fftw3 и посмотри как там сделано и почему, если не веришь.

> Практически в любой задачи можно обойтись без float. Это просто нужно
>понимать задачу.

Ну разумеется, можно ведь написать свой класс на интах вместо FPU. Ты всегда так делаешь?

>P.S. хотя есть процессоры где поддержка стандарта float реализована аппаратно там применение
>обосновано.

Да, всем понятно что ты слил. Понимаешь, весь мир считает floating point на, как ни странно, FPU, а не ищет как заменить его на более торнозные инты.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

13. "Использование NaN, inf как маркеров инициализации переменных"  +/
Сообщение от f00l (ok) on 14-Окт-09, 11:15 
Еще немного:
В данном коде видна основная ошибка, человек мыслит как  математик а не как программист,
если есть задание получать числа в диапазоне от 0.0000 до 0.9999 то нужно работать с float по другому представить нельзя.
а если идет хранение в int, то идет постоянное преобразование, это медленно.

немного переработанный код:
int main(int argc, char * argv[])
{
  srand(234234234);
  for (i = 0; i < SIZE; ++i) {
     color1[i] = rand()/(RAND_MAX/9999);
     color2[i] = rand()/(RAND_MAX/9999);
     alpha[i] = rand()/(RAND_MAX/9999);
  }
   for (j = 0; j < ITERS; ++j)
     for (i = 0; i < SIZE; ++i)
        output[i] = (color1[i]*alpha[i] + color2[i]*(10000-alpha[i]));

    printf("blend(%.4f, %.4f, %.4f) = %.4f\n",
          (float)color1[0]/(float)10000,
          (float)color2[0]/(float)10000,
          (float)alpha[0]/(float)10000,
          (float)output[0]/(float)10000);
    return 0;
}

и результаты на 32 бит машине.

c int
~/work/test/float :> time ./int
blend(0.7010, 0.8640, 0.9905) = 0.7025
2.80user 0.01system 0:02.84elapsed 98%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (0major+4230minor)pagefaults 0swaps

~/work/test/float :> time ./float
blend(0.7011, 0.8641, 0.9906) = 0.7026
2.95user 0.01system 0:03.03elapsed 97%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (0major+4229minor)pagefaults 0swaps

получили немного лучший результат. но идет падением точности.

P.S. значения получились другие наверно машина 32 бит

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

15. "Использование NaN, inf как маркеров инициализации переменных"  +/
Сообщение от аноним on 14-Окт-09, 15:37 
>В данном коде видна основная ошибка, человек мыслит как  математик а
>не как программист

Ничего подобного.

>если есть задание получать числа в диапазоне от 0.0000 до 0.9999 то
>нужно работать с float по другому представить нельзя.

Ой, как же так, float ведь не нужен?

>а если идет хранение в int, то идет постоянное преобразование, это медленно.

Еще раз - где там преобразования? Если ты про из float и в начале и во float в конце, я уже сказал что это бред. Где еще?

>получили немного лучший результат. но идет падением точности.

Что за машина? Когда-то FPU вообще был отдельно от процессора, вот там float'ы действительно были медленнее. У тебя такой?
Я тестирую на core2duo, и 32 бита и 64. Вот тебе float, double и int на 32 битах, SIZE=1024, ITERS=1024*1024, чтобы тестировать числодробилку, а не память. Для int MAX=65535, чтобы не было вообще никаких преобразований, int64_t соответственно убран.

time ./float
blend(0.2036, 0.0478, 0.8507) = 0.1803
        1.37 real         1.37 user         0.00 sys
time ./double
blend(0.2036, 0.0478, 0.8507) = 0.1803
        1.38 real         1.38 user         0.00 sys
time ./int
blend(0.2036, 0.0478, 0.8507) = 0.1803
        2.03 real         2.02 user         0.00 sys

Дальше спорить будешь?

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

Архив | Удалить

Индекс форумов | Темы | Пред. тема | След. тема




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру