Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить

Представление чисел, что лучше.

Ср апр 02, 2014 14:44:41

Всем привет!
Представьте себе 32-битный регистр. Мне нужно использовать этот регистр для математических вычислений. Для этого в него пишем необходимое значение и производим математические действия.
К примеру, мне нужно вписать в этот регистр число 632,626
Есть два выхода:
1) интерпретировать этот регистр, как беззнаковое целое число, с ценой одного разряда равной 0,001 (10^-3) Т.е. записать в регистр число 632,626/0,001 = 632626 = 0x0009A732.
2) интерпретировать этот регистр, как число фиксированной запятой, с ценой одного разряда равной 0,0009765625 (2 ^ -10) = 1/65536 Т.е. записать в регистр число 632,626/(2^-10) = 647809,024 =~ 647809 = 0x0009E281
так вот вопрос : что лучше использовать?
хочу послушать мнения.

Re: Представление чисел, что лучше.

Ср апр 02, 2014 16:08:04

может записывать как вещественные числа: http://uchebnik1.narod.ru/chislo.html

Re: Представление чисел, что лучше.

Ср апр 02, 2014 16:15:02

ibiza11 писал(а):так вот вопрос : что лучше использовать?

То, что поддерживает архитектура. Которая, кстати, не указана :)

Re: Представление чисел, что лучше.

Ср апр 02, 2014 16:40:26

ibiza11 писал(а):с ценой одного разряда равной 0,0009765625 (2 ^ -10) = 1/65536
По мне, 1/2^10=1/1024=0,0009765625. По вопросу - я бы выбрал первый вариант. Главное, правильный порядок выполнения операций, чтобы не было потери значимости и переполнения.

Re: Представление чисел, что лучше.

Ср апр 02, 2014 22:22:36

За статью по представлению чисел спасибо, но ничего нового для себя я из нее не извлек. Понятно, что вещественные числа можно представоять в разных форматах, в том числе в виде числас плавающей и фиксированной запятой. Но вопрос был не о том как можно, а как лучше, узнать мнения остальных.

Целевая платформа ARM cortex m3, 32 бита. Имеет аппаратные делитель и умножитель, но не имеет FPU.

(2^ -10) конечно же равно 1/1024, ошибся, не перепроверил.
Я пока тоже склоняюсь к первому варианту, привычнее как то....

Re: Представление чисел, что лучше.

Ср апр 02, 2014 23:48:13

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

Re: Представление чисел, что лучше.

Чт апр 03, 2014 00:06:13

ibiza11 писал(а):Я пока тоже склоняюсь к первому варианту, привычнее как то....

Честно... не понимаю причин... или что-то недоговаривается...

Re: Представление чисел, что лучше.

Чт апр 03, 2014 07:22:47

Ща спою... :)) Некоторые моменты (по памяти и по логике вещей).

Два способа: с "десятичным" и "двоичным" весом младшего разряда.
При наличии FPU, по скорости разница будет не очень велика между этими способами.
По точности в ходе операций - зависит от способа представления и того, как реализовать операции. Так как при реализации "в лоб" потенциально неизбежна потеря точности с одной стороны и переполнение с другой.

Если вам нужны только операции сложения и вычитания, то тут всё просто в обеих случаях.

Если требуется умножение, то чуть сложнее.
При умножении надо будет поделить результат, чтобы сдвинуть точку.
Например (с отбрасыванием дробной части).
25,364 * 7,659 = 194,262
(25364 * 7659) / 1000 = 194262
Конкретно в этом примере требуется деление на 1000.
В случае с "двоичным" представлением это сводится к простому сдвигу.

Про деление на память не расскажу - давно это было. :)
Добавил спустя пару минут: Если моё смутное воспоминание меня не подводит, то деление обратно делается.
25,364 * 7,659 * 3,311
25364 * 1000 / 7659 = 3311
Деление Умножение или сдвиг - аналогично.

Для "десятичного" варианта проще преобразование в человеко читаемый вид - itoa, printf("%d") и т.д. с вставкой точки в нужное место.
Для "двоичного" нужен соответствующий алгоритм. Например, сначала привести к "десятичному" варианту с требуемой точностью...
Последний раз редактировалось Kavka Чт апр 03, 2014 11:41:00, всего редактировалось 1 раз.

Re: Представление чисел, что лучше.

Чт апр 03, 2014 10:26:55

ploop писал(а):Второй вариант, кажется, будет точнее при различных математических операциях.
кажется или точнее? как по мне, точность зависит от самого числа, кратно оно "цене деления" в текущем представлении или нет. (0.001 и 0,0009765625 в первом и втором случаях соответственно)
HHIMERA писал(а):Честно... не понимаю причин... или что-то недоговаривается...
не понимаете причин, почему я склоняюсь к первому варианту? Если да, то все просто: я никогда не работал с фиксированной точкой)
Kavka писал(а):Для "десятичного" варианта проще преобразование в человеко читаемый вид - itoa, printf("%d") и т.д. с вставкой точки в нужное место.
Для "двоичного" нужен соответствующий алгоритм. Например, сначала привести к "десятичному" варианту с требуемой точностью...
Именно!) Отличный вывод! Мне нужно чаще вычисления, чем вывод на человеко-читаемый терминал ( :) ). Вычисления должны быть по возможности быстрые. Сдвиг на ARM выполняется одной командой, поэтому второй вариант выгоднее в плане времени выполнения. Спасибо, Kavka)
Всем спасибо! :beer:

Re: Представление чисел, что лучше.

Чт апр 03, 2014 16:22:37

Я бы отталкивался от того, насколько критична точность, а про это не сказано, кажется, ни слова.
Чтобы, скажем, при операции 0,998 + 0,001 не получить на выходе 1,000.

Re: Представление чисел, что лучше.

Чт апр 03, 2014 19:00:23

Да, про точность я и не писал.
Очень сильно зависит от задачи, от потребностей, конкретного алгоритма.
Это в ведении автора вопроса. Ему и решать.

Re: Представление чисел, что лучше.

Чт апр 03, 2014 23:21:43

Gudd-Head, скажите, среди этиих двух вариантов, разве есть лидер, отличающийся точностью? Какой из них?

Re: Представление чисел, что лучше.

Пт апр 04, 2014 00:03:40

Да не серьёзно всё это... всё нужно проверять... можно в симуляторе, но лучше в железе...
А float или double... уже по скорости или точности...

Re: Представление чисел, что лучше.

Пт апр 04, 2014 00:28:17

когда -то на програмистском форуме слышал крик души - никогда не используйте для денежных расчетов (рубли - копейки ) float...
Потом работал на атс и выдавал данные с базы в бюстгальтерию по расчетам с клиентами - сам убедился - лучше не стОит.
:)

Re: Представление чисел, что лучше.

Пт апр 04, 2014 06:04:30

urry, это только подтверждает то, что конкретное представление чисел с ограниченной точностью (фикс. точка) сильно зависит от задачи.
С копейками - это да, наверное, самый яркий пример. Кто это "прочувствовал" на практике - понимают. :)
Т.е. с копейками надо, как раз, обеспечить жёсткую, фиксированную точность. Чтобы ни при каких обстоятельствах не было 1.259998 руб, а было всегда 1.26 руб. А то может из-за таких "9998" в итоге недобор случиться. Т.е. в реале А+Б=В, а на компе может получиться А+Б меньше B. И чем больше операций с неточными представлениями чисел (типа с 9-ми в конце) тем больше будет разница. Тут нужен "десятичный" вариант представления.
В случае же, например, с каким нибудь PID регулятором - такие ситуации побоку. Там просто нужна достаточная точность, чтобы хватало для устойчивых вычислений. Соответственно, для PID и "двоичный" вариант подойдёт.

Да, и не забывайте, что не всегда можно сравнивать дробные числа на равенство. Особенно в "двоичном" варианте. Желательно сравнивать с диапазоном (плюс-минус эпсилон). На величину младшего разряда или больше. Опять же, сильно зависит от конкретного случая.

Re: Представление чисел, что лучше.

Пт апр 04, 2014 10:34:43

Сферический конь в вакууме в гривне всегда компактнее... :))) :)))
Чтобы ни при каких обстоятельствах не было 1.259998 руб, а было всегда 1.26 руб.

Сколько там видов округлениия... ась??? Там только банковских несколько...

Re: Представление чисел, что лучше.

Пт апр 04, 2014 12:30:49

О существовании этих способов округления надо знать и использовать их во всех операциях относящихся к делу.
К тому же "денежные" округления, как правило, компилятором не делаются и их надо ручками в программе делать.
Ну, может быть, foxpro или им подобные с явной спецификой под такие операции и делают это автоматом.
А многие только столкнувшись с этим на практике понимают с чем имеют дело.
Так что, если вот это
HHIMERA писал(а):Сколько там видов округлениия... ась??? Там только банковских несколько...
рассматривать как призыв включить мозги и подумать, то я только за.

Re: Представление чисел, что лучше.

Пт апр 04, 2014 13:34:55

Kavka писал(а):С копейками - это да, наверное, самый яркий пример. Кто это "прочувствовал" на практике - понимают. :)

Есть байка : американский программер доли цента, которые при расчетах отбрасываются, переводил себе на счет. Пока посадили, нехило накапало.
А вообще вопрос ТС из серии : "Что лучше - шашлык по-карски или трактор "Беларус" ?" Точность, быстродействие, диапазон возможных величин и т.д. и пр. - смотря по обстоятельствам. Один мой знакомец делал 3-байтовую плавучку : один байт - знак и порядок, 2 байта - мантисса. Ему хватало... Сишную арифметику обставлял по скорострельности раза в 4.

Re: Представление чисел, что лучше.

Пт апр 04, 2014 13:59:28

Я обычно на более слабых камнях (AVR, PIC и прочих восьмибитках) использую как целое число. Со знаком или без.

Спойлер
Код:
// Показометр
//*************************************************************
int32_t ReadShuntCurrent(void)
{
         
        int32_t III 
= 0;
        uint16_t Ip = 0;
        uint16_t In = 0;
        
        Ip 
= adc_read(INP_I_POS);
        if(Ip >= 33){Ip -= CR_P_BIAS;} 
        else
{Ip = 0;}  
               
        In 
= adc_read(INP_I_NEG);
        if(In >= 33){In -= CR_N_BIAS;}
        else{In = 0;}
        
        if
(Ip > 0)
        {
            III = (int32_t)(Ip * 10);
            III *= setup.ip_mul_coeff;
            III /= setup.ip_div_coeff;
        }
        else
        
{
            if(In > 0)  
            
{
                III = (int32_t)(In * 10);
                III *= setup.in_mul_coeff;
                III /= setup.in_div_coeff;
                III = -III;
            }
            else
            
{
                III = 0;
            }
        }
        return III;
}
 



На более мощных (STM32, A20, OMAP и прочих) пользуюсь float'ом, где это требуется.
Спойлер
Код:
//Показометр получше
//*************************************************************
float ReadShuntCurrent(void)
{
         
        int32_t III 
= 0;
        uint16_t Ip = 0;
        uint16_t In = 0;
        
        Ip 
= adc_read(INP_I_POS);
        if(Ip >= 33){Ip -= CR_P_BIAS;} 
        else
{Ip = 0;}  
               
        In 
= adc_read(INP_I_NEG);
        if(In >= 33){In -= CR_N_BIAS;}
        else{In = 0;}
        
        if
(Ip > 0)
        {
            III = ((setup.ADC_Vps * Ip) / setup.IP_Kamp) / t_init.Kshunt;
        }
        else
        
{
            if(In > 0)  
            
{
                III = ((setup.ADC_Vps * In) / setup.IN_Kamp) / t_init.Kshunt;
                III = -III;
            }
            else
            
{
                III = 0;
            }
        }
        return III;
}
 

Re: Представление чисел, что лучше.

Пт апр 04, 2014 16:28:02

Какой-то странный подход... к тривиальному приведению данных...
Ответить