реклама на сайте
подробности

 
 
> Применение целочисленной арифметики
Яrik
сообщение Feb 6 2007, 00:15
Сообщение #1


Частый гость
**

Группа: Новичок
Сообщений: 110
Регистрация: 8-01-07
Из: Украина
Пользователь №: 24 216



Добрый вечер!

Для деления чисел с плавающей запятой необходимо много памяти МК. Но знаю, что эту операцию можно сделать, используя целочисленую арифметику.
Подскажите, пожалуйста, кто знает как обращаться с этим зверем. biggrin.gif
Go to the top of the page
 
+Quote Post
2 страниц V   1 2 >  
Start new topic
Ответов (1 - 27)
umup
сообщение Feb 6 2007, 00:28
Сообщение #2


Местный
***

Группа: Свой
Сообщений: 226
Регистрация: 2-06-06
Пользователь №: 17 720



очень просто - при вычислениях просто используйте целые числа, домноженные на нужное число 10ток после запятой, например для отбражения числа 1.4 с одним знаком после запятой получится 14, с двумя - 140. Ясно что при умножениях/делениях и других операциях это нужно учитывать, например 1.4 * 1.5 = 2.1, а 14 * 15 = 210, то есть после умножения нужно еще разделить на 10 чтобы получить 21
Go to the top of the page
 
+Quote Post
mihask
сообщение Feb 6 2007, 05:45
Сообщение #3


Частый гость
**

Группа: Validating
Сообщений: 80
Регистрация: 7-12-05
Пользователь №: 11 905



Цитата(Яrik @ Feb 6 2007, 03:15) *
Добрый вечер!

Для деления чисел с плавающей запятой необходимо много памяти МК. Но знаю, что эту операцию можно сделать, используя целочисленую арифметику.
Подскажите, пожалуйста, кто знает как обращаться с этим зверем. biggrin.gif


Что-то мне кажется что одним делением не обойдется smile.gif, я конечно не знаю условий вашей задачи , но скорей всего придется всю математику или ,по крайней мере, наиболее ресурсоемкую часть перевести
на целочисленную арифметику, а то можно много потерять на преобразовании переменных из одного формата в другой. От себя добавлю пример со сложением smile.gif
1 + 0.35 =1.35 в целочисленном формате 100 + 35 =135 - подразумеваем что у нас два знака после
запятой. Деление - наиболее эффективно методом сдвига , так это помоему называется smile.gif, алгоритма не
помню, могу дать исходник функции целочисленного деления на asm 51- ого процессора smile.gif.
Кстати деление в столбик, которое здесь тоже можно применить, - это очень медленный вариант.

Эффективные алгоритмы целочисленного деления описаны в книге - "Алгоритмические трюки для программистов" - в сети можно скачать точно, если не удастся найти, могу дать.

Сообщение отредактировал mihask - Feb 6 2007, 06:02
Go to the top of the page
 
+Quote Post
umup
сообщение Feb 6 2007, 09:42
Сообщение #4


Местный
***

Группа: Свой
Сообщений: 226
Регистрация: 2-06-06
Пользователь №: 17 720



еще посмотрите на http://umup.narod.ru/#books_cs_arith - есть кое-что по комп.арифметике
Go to the top of the page
 
+Quote Post
gormih
сообщение Feb 6 2007, 09:49
Сообщение #5


nofb
***

Группа: Свой
Сообщений: 430
Регистрация: 18-05-06
Из: Москва, Зеленоград
Пользователь №: 17 218



Цитата(mihask @ Feb 6 2007, 03:15) *
Эффективные алгоритмы целочисленного деления описаны в книге - "Алгоритмические трюки для программистов" - , если не удастся найти, могу дать.


если можно вот сюда


--------------------
Это не то что вы подумали ...

Go to the top of the page
 
+Quote Post
Wild007
сообщение Feb 6 2007, 09:59
Сообщение #6


Местный
***

Группа: Свой
Сообщений: 226
Регистрация: 25-03-05
Из: Беларусь
Пользователь №: 3 672



2 gormih здесь:
Алгоритмические трюки для программистов


--------------------
Ничто так не ограничивает полет мысли программиста, как компилятор
Go to the top of the page
 
+Quote Post
mse
сообщение Feb 6 2007, 10:05
Сообщение #7


Знающий
****

Группа: Свой
Сообщений: 709
Регистрация: 3-05-05
Пользователь №: 4 693



Цитата(Яrik @ Feb 6 2007, 00:15) *
Добрый вечер!

Для деления чисел с плавающей запятой необходимо много памяти МК. Но знаю, что эту операцию можно сделать, используя целочисленую арифметику.
Подскажите, пожалуйста, кто знает как обращаться с этим зверем. biggrin.gif

Ничё не понял...чего это вдруг "много"? Плывучка, кстати, будет занимать "меньше" места и времени, по сравнению с аналогичной по динамицкому диапазону представления чисел, целочисленкой. Умножение-деление - в разы. Сложение-вычитание, разве что, проиграет. Тоже в разы. 5...8 тактов против 10-20-50.
Другое дело, если операнды реально укладываются в слово-два-три процессора. Тогда смысл есть.
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Feb 6 2007, 11:53
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Цитата(mse @ Feb 6 2007, 11:05) *
Ничё не понял...чего это вдруг "много"? Плывучка, кстати, будет занимать "меньше" места и времени, по сравнению с аналогичной по динамицкому диапазону представления чисел, целочисленкой. Умножение-деление - в разы. Сложение-вычитание, разве что, проиграет. Тоже в разы. 5...8 тактов против 10-20-50.
Другое дело, если операнды реально укладываются в слово-два-три процессора. Тогда смысл есть.


Совершенно согласен. Я это проверял. Единственное что усложняет работу с флоат это ввод/вывод в десятичной с.с. А сама арифметика просто прекрасно считается. Тем более у AVR команды есть соответствующие. Тоже применял.

Так что всё зависит от разрядности чисел и необходимости их отображения. А на счёт памяти не парьтесь - и регистрами обойдётесь.
Go to the top of the page
 
+Quote Post
Яrik
сообщение Feb 6 2007, 19:25
Сообщение #9


Частый гость
**

Группа: Новичок
Сообщений: 110
Регистрация: 8-01-07
Из: Украина
Пользователь №: 24 216



Цитата
Единственное что усложняет работу с флоат это ввод/вывод в десятичной с.с


Да, да какраз это... Я думал, что используя целочисленную арифметику удастся уменьшить объем занимаемой програмой. Но теперь понял, что ошибался.
Я питался выводить на LCD результат измереного АЦП напряжения. В результате использования команды printf, объем памяти занимаемой программой сотавил 50% имеющейся в ATmega8.
Может кто поделится своими наработками? Зарание благодарю.
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Feb 7 2007, 03:21
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Но результат АЦП - целочисленный. blink.gif

Пожалуйста, если хотите получить полный ответ, задайте полный вопрос.
Go to the top of the page
 
+Quote Post
mse
сообщение Feb 7 2007, 09:50
Сообщение #11


Знающий
****

Группа: Свой
Сообщений: 709
Регистрация: 3-05-05
Пользователь №: 4 693



Цитата(Яrik @ Feb 6 2007, 19:25) *
Цитата
Единственное что усложняет работу с флоат это ввод/вывод в десятичной с.с


Да, да какраз это... Я думал, что используя целочисленную арифметику удастся уменьшить объем занимаемой програмой. Но теперь понял, что ошибался.
Я питался выводить на LCD результат измереного АЦП напряжения. В результате использования команды printf, объем памяти занимаемой программой сотавил 50% имеющейся в ATmega8.
Может кто поделится своими наработками? Зарание благодарю.

http://www.telesys.ru/wwwboards/mcontrol/2...es/141026.shtml
сразу в АSCII http://www.telesys.ru/wwwboards/mcontrol/2...es/141922.shtml
Go to the top of the page
 
+Quote Post
lazycamel
сообщение Feb 7 2007, 17:02
Сообщение #12


Участник
*

Группа: Свой
Сообщений: 48
Регистрация: 5-11-04
Пользователь №: 1 053



Цитата(mse @ Feb 6 2007, 11:05) *
Плывучка, кстати, будет занимать "меньше" места и времени, по сравнению с аналогичной по динамицкому диапазону представления чисел, целочисленкой.


Обычный пример для плавучки - ATAN(ADC0/ADC1)*PI
ИМХО целочиcленка и CORDIC будут не просто в разы, а на порядок быстрее.
Go to the top of the page
 
+Quote Post
umup
сообщение Feb 7 2007, 17:08
Сообщение #13


Местный
***

Группа: Свой
Сообщений: 226
Регистрация: 2-06-06
Пользователь №: 17 720



я пользуюсь этим :

http://electronix.ru/forum/index.php?showt...mp;#entry188097

ilcd_ks066_pul(data, buf, options) - вывод беззнакового long с фиксированной точкой в память
ilcd_ks066_psl(data, buf, options) - вывод знакового long

а из памяти - на LCD
Go to the top of the page
 
+Quote Post
mse
сообщение Feb 7 2007, 17:31
Сообщение #14


Знающий
****

Группа: Свой
Сообщений: 709
Регистрация: 3-05-05
Пользователь №: 4 693



Цитата(lazycamel @ Feb 7 2007, 17:02) *
Обычный пример для плавучки - ATAN(ADC0/ADC1)*PI
ИМХО целочиcленка и CORDIC будут не просто в разы, а на порядок быстрее.

Обычный пример для плывучки: 0.000076538435*25484135е3
Без ИМХОв: плывучка оденет целочисленку, пусть не на порядок, но в разы.
На порядок она оденет при делении лонг-лонг на его-же.
И кто мешает реализовать ATAN() таблично? КОРДИК тихо удавится в сортире. Без разницы, целочисленно или вплавь. Тем более, непонятно, кто мне запретит реализовать его вплавь?
Не надо путать алгоритм с операндом.
Go to the top of the page
 
+Quote Post
Яrik
сообщение Feb 7 2007, 18:25
Сообщение #15


Частый гость
**

Группа: Новичок
Сообщений: 110
Регистрация: 8-01-07
Из: Украина
Пользователь №: 24 216



Цитата
Пожалуйста, если хотите получить полный ответ, задайте полный вопрос.

Да, результат преобразования целое число (от 0 до 1023), но на LCD мне нужно вывести выраженый в вольтах. Для перевода внутреним опорним напряжением, я пользуюсь следующей формулой:Прикрепленное изображение
Go to the top of the page
 
+Quote Post
umup
сообщение Feb 7 2007, 19:25
Сообщение #16


Местный
***

Группа: Свой
Сообщений: 226
Регистрация: 2-06-06
Пользователь №: 17 720



Яrik
Вот сказали бы это сразу и не было бы столько споров, а то уже начали приводить примеры которые на контроллерах почти не встречаются (типа 0.000076538435*25484135е3), в большинстве случаев достаточно 16 или 32 битных целых с фиксированной точкой.
Для вашего случая достаточно 2х сдвигов вправо (*256 - это сдвиг влево на 8 разрядов, /1023 - почти сдвиг вправо на 10 разрядов, итого на 2 вправо), и не нужно никаких делений/умножений. Точку между цифрами, надеюсь, сами нарисуете ?
А для перевода чисел в строку есть стандартная функция кажется itoa()

Сообщение отредактировал umup - Feb 7 2007, 19:30
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Feb 8 2007, 00:51
Сообщение #17


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Цитата(umup @ Feb 7 2007, 20:25) *
Яrik
Вот сказали бы это сразу и не было бы столько споров, а то уже начали приводить примеры которые на контроллерах почти не встречаются (типа 0.000076538435*25484135е3), в большинстве случаев достаточно 16 или 32 битных целых с фиксированной точкой.
Для вашего случая достаточно 2х сдвигов вправо (*256 - это сдвиг влево на 8 разрядов, /1023 - почти сдвиг вправо на 10 разрядов, итого на 2 вправо), и не нужно никаких делений/умножений. Точку между цифрами, надеюсь, сами нарисуете ?
А для перевода чисел в строку есть стандартная функция кажется itoa()


Для таких случаев бывает формула не очень подходит. Используется бывает коррекция. Если наблюдается нелинейность. Тогда табличным методом.

Если хотите всётаки полностью по формуле, то лучше целочисленным методом. Умножение на 256 Вам сказали как (сдвигов конечно не надо, просто результат читаете в байт 1 и 2 (а байт 0 - обнуляете) а деление к примеру так

Код
;========================================================================
; Поделить 32 бита (ddt:ddl) на 32 бита (dv3:dv0).
;------------------------------------------------------------------------
; Входные  регистры: ddt:ddl,dv3:dv0
; Выходные регистры: ddt:ddl(частное), w3:w2:wh:wl(остаток)
; Портятся регистры: tmp

div32:
    clrq    w                    ; очистить остаток и перенос
    ldi        tmp,33                ; инициализировать счетчик цикла
du_1:
    rolq    dd                    ; делимое/результат сдвинуть влево
    dec        tmp                    ; умньшить на единицу счетчик цикла
    brne    du_2                ; переход, если не ноль
    ret                            ; выйти
du_2:
    rolq    w                    ; остаток сдвинуть влево
    subq    w,dv                ; остаток= остаток - делитель
    brcc    du_3                ; если результат < 0
    addq    w,dv                ; восстановить остаток
    clc                            ; сбросить перенос для формирования результата
    rjmp    du_1                ; иначе
du_3:
    sec                            ; установить перенос для формирования результата
    rjmp    du_1                ; вернуться назад

где


;****************************************************************
;*   Команда SUB для 32-ух битных чисел в регистрах.             *
;****************************************************************

.macro        subq                ; Два параметра "Имя регистров"

    sub        @0l,@1l                ; загрузить регистр 0
    sbc        @0h,@1h                ; загрузить регистр 1
    sbc        @0d,@1d                ; загрузить регистр 2
    sbc        @0t,@1t                ; загрузить регистр 3
.endm

;****************************************************************
;*   Команда ADD для 32-ух битных чисел в регистрах.             *
;****************************************************************

.macro        addq                ; Два параметра "Имя регистров"

    add        @0l,@1l                ; загрузить регистр 0
    adc        @0h,@1h                ; загрузить регистр 1
    adc        @0d,@1d                ; загрузить регистр 2
    adc        @0t,@1t            ; загрузить регистр 3
.endm    

;****************************************************************
;*   Команда CLR для 32-ух битных чисел в регистрах.             *
;****************************************************************

.macro        clrq                ; один параметр "Имя регистров"

    clr        @0l                    ; загрузить регистр 0
    clr        @0h                    ; загрузить регистр 1
    clr        @0d                    ; загрузить регистр 2
    clr        @0t                    ; загрузить регистр 3
.endm

;****************************************************************
;*   Команда ROL для 32-ух битных чисел в регистрах.             *
;****************************************************************

.macro        rolq                ; один параметр "Имя регистров"

    rol        @0l                    ; загрузить регистр 0
    rol        @0h                    ; загрузить регистр 1
    rol        @0d                    ; загрузить регистр 2
    rol        @0t                    ; загрузить регистр 3
.endm

;****************************************************************
;*   Команда LD для 32-ух битных чисел в регистрах.                 *
;****************************************************************

.macro        ldq                    ; Два параметра "Имя регистров" и "параметр".

    ld        @0l,@1                ; загрузить регистр 0
    ld        @0h,@1                ; загрузить регистр 1
    ld        @0d,@1                ; загрузить регистр 2
    ld        @0t,@1                ; загрузить регистр 3
.endm

;****************************************************************
;*   Команда ST для 32-ух битных чисел в регистрах.                 *
;****************************************************************

.macro        stq                    ; Два параметра "Имя регистров" и "параметр".

    st        @0,@1l                ; загрузить регистр 0
    st        @0,@1h                ; загрузить регистр 1
    st        @0,@1d                ; загрузить регистр 2
    st        @0,@1t                ; загрузить регистр 3
.endm
Go to the top of the page
 
+Quote Post
Яrik
сообщение Feb 8 2007, 11:27
Сообщение #18


Частый гость
**

Группа: Новичок
Сообщений: 110
Регистрация: 8-01-07
Из: Украина
Пользователь №: 24 216



Цитата
Для таких случаев бывает формула не очень подходит. Используется бывает коррекция. Если наблюдается нелинейность. Тогда табличным методом.

Если хотите всётаки полностью по формуле, то лучше целочисленным методом. Умножение на 256 Вам сказали как (сдвигов конечно не надо, просто результат читаете в байт 1 и 2 (а байт 0 - обнуляете) а деление к примеру так

Спасибо! А нет ли у Вас примера на СИ, потму что попытка сделать асеммблерную вставку в CodeVisionAvr у меня не увенчалась успехом.
Go to the top of the page
 
+Quote Post
mse
сообщение Feb 8 2007, 11:49
Сообщение #19


Знающий
****

Группа: Свой
Сообщений: 709
Регистрация: 3-05-05
Пользователь №: 4 693



Цитата(umup @ Feb 7 2007, 19:25) *
Яrik
Вот сказали бы это сразу и не было бы столько споров, а то уже начали приводить примеры которые на контроллерах почти не встречаются (типа 0.000076538435*25484135е3), в большинстве случаев достаточно 16 или 32 битных целых с фиксированной точкой.

Вот в том-то и дело, что в ряде случаев, плывучка с 8-16 битной мантиссой и 8-бит экспонентой уделает и по скорости, и по динамике 32 битную целочисленку. Повторюсь. Это актуально для 8-битников. И чем горбатее 8-битник в плане арифметики, тем актуальнее. Для АРМа, например, смысла в плывучке реально нет вообще.
А что встречается, а что почти не встречается, так то смотря какие задачи кем решаются. Кое кто из плывучки мож и не вылазит.
Go to the top of the page
 
+Quote Post
=GM=
сообщение Feb 8 2007, 19:04
Сообщение #20


Ambidexter
*****

Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282



To SasaVitebsk. I've rearranged your code a bit. It looks better and quicker now.
Sorry for english text, this bl@$dy hell keyboard..

Код
;========================================
; Поделить 32 бита (ddt:ddl) на 32 бита (dv3:dv0).
;------------------------------------------------------------------------
; Входные  регистры: ddt:ddl,dv3:dv0
; Выходные регистры: ddt:ddl(частное), w3:w2:wh:wl(остаток)
; Портятся регистры: tmp

div32:       clrq         w                   ; очистить остаток и перенос
             ldi          tmp,32              ; инициализировать счетчик цикла
du1:         subq         w,dv                ; остаток= остаток - делитель
             brcc         du2                 ; если результат < 0
             addq         w,dv                ; восстановить остаток
du2:         rolq         dd                  ; делимое/результат сдвинуть влево
             rolq         w                   ; остаток сдвинуть влево
             dec          tmp                 ; умeньшить на единицу счетчик цикла
             brne         du1                 ; переход, если не ноль
             comq         dd                  ; invert the quotient
             ret                              ; выйти



--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
AndreyKeil
сообщение Feb 8 2007, 21:27
Сообщение #21


Частый гость
**

Группа: Свой
Сообщений: 96
Регистрация: 16-11-05
Из: г.Екатеринбург
Пользователь №: 10 930



Извиняюсь, если мой вопрос не в тему, скажите алгоритм преобразования целого числа в формат плавающей точки и наоборот - плавающего в целое?
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Feb 8 2007, 21:30
Сообщение #22


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Цитата(Яrik @ Feb 8 2007, 12:27) *
Спасибо! А нет ли у Вас примера на СИ, потму что попытка сделать асеммблерную вставку в CodeVisionAvr у меня не увенчалась успехом.


Ну Вы и даёте. smile.gif А на си это выглядит в точности как Вы написали.

Res=adc_res*256/1023;
Go to the top of the page
 
+Quote Post
rezident
сообщение Feb 8 2007, 22:16
Сообщение #23


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(Яrik @ Feb 6 2007, 21:25) *
Да, да какраз это... Я думал, что используя целочисленную арифметику удастся уменьшить объем занимаемой програмой. Но теперь понял, что ошибался.
Я питался выводить на LCD результат измереного АЦП напряжения. В результате использования команды printf, объем памяти занимаемой программой сотавил 50% имеющейся в ATmega8.
Может кто поделится своими наработками? Зарание благодарю.

Дык это не плавучая арифметика столько памяти жрет, а сама функция printf! excl.gif Уже неоднократно и многими подчеркивался тот факт, что printf и sprintf требуют для работы от сотни байт до 1,5 килоБайт стековой памяти, то бишь ОЗУ. Так что советую оставить плавучку в покое, а лишь написать собственную функцию перевода числа в символьное представление.
Когда-то делал устройство, поддерживающее пакетную связь по RS-485, обработку клавиатуры и вывод на два четырехсимвольных семисегментника двух дробных чисел. Также долго мучал printf, пока не понял, что на имеющихся 256 байтах ОЗУ нельзя ее пользовать. Для вывода даже одного числа с фиксированной точкой и двумя знаками после запятой printf использовал больше 100 байт стека. А в распоряжении было всего около 50 байт smile.gif В результата написал свою функцию типа поразрядного деления на степень 10, которая использовала не более 8 байт на стеке. За скоростью вычислений в таких случаях гнаться не нужно. Потому что обновлять информацию на индикаторе чаще 3 раз в секунду нет никакого смысла. Во-первых, человеческий глаз инертен. Во-вторых, наблюдателю нужно еще время чтобы осознать наблюдаемое число. Так что, используйте на здоровье плавучку и не используйте printf. wink.gif
Go to the top of the page
 
+Quote Post
mse
сообщение Feb 8 2007, 23:01
Сообщение #24


Знающий
****

Группа: Свой
Сообщений: 709
Регистрация: 3-05-05
Пользователь №: 4 693



Цитата(AndreyKeil @ Feb 8 2007, 21:27) *
Извиняюсь, если мой вопрос не в тему, скажите алгоритм преобразования целого числа в формат плавающей точки и наоборот - плавающего в целое?

Будете смеяться, но тупо до безобразия. Не буду рассказывать про форматы ИЕЕЕ. В ембеддед приложениях смысла в ихней упаковке нет никакого. Если што, сами найдёте. А общий смысл такой: целое число нужно привести к формату 1,хх...хх. Это называецца мантисса. Что соответствует диапазону 111...11 до 100..00. Или, в десятичном эквиваленте, от 1,9..99 до 1. И в комплект дать експоненту, т.е. тупой множитель вида 2^N, где N, я, для удобства, принимаю как ±0х3f. Ехп содержится в отдельном байте. Старший бит которого является знаком числа в целом. Таким образом плавучее число прецтавляет из себя такую конструкцию: Мант*(2^Ехп). Нуль, когда в мантиссе нуль. Это ессно.

Пример. Вначале имеете число, пусть 8р. И ему в соотв. ставим експоненту. Вначале=7. Бо это номер старшево бита.
Далее, сдвигаем влево и соотвецтвенно декрементируем ехпоненту. До тех пор, пока старший разряд не станет =1. Или не кончится ехпонента. Если подвинули 7 раз, а 1 в старшем разряде нет, тоды имеем нуль. Судьба.
Пример 0х80 -> 0х80 мантисса и 7-експонента. Проверяем: 0х80 это 1,0. Множим его на 2^7, получаем 128. Или 0х80 целочисленно.
0х01-> 0х80мантисса и 0-експонента. Проверяем:0х80 это1,0. Множим его на 2^0, получаем 1. Оба-на, совпадло!
Плывучее в целое - строго наоборот. Сдвигаем на число разрядов в ехп, предварительно отняв от неё номер старшево бита мантиссы. Если ехп получилась отриццательная, то вправо. Если положительная, то влево. Т.е. результат может быть сильно больше исходной мантиссы! Или наоборот, 0.
Пример. М=0х80, Е=0х7. Тогда отымем от Е 0х7. Получим нуль. Сдвинем 0х80 на нуль влево, получим 0х80. Опять совпадло! Чюдо!
Пример нумер2: М=0х80, Е=0х0. Отымаем от Е 0х7. Получаем Е=-7. Помним, что старший бит ехп - знак числа в целом. Для удобства его упаковывают в Е на время хранения. Но в работе он должен храниться отдельно для упрощения арифметики. Но отсюда вытекает проблема: в результате любых манипуляций Е должна находиться в пределах ±0х3F, или 0x3f...0xc0. Если вылетает за, значить у нас произошло исключение - результат стал равен ±бесконечность или ± не-число. Что тут делать - думайте сами. Итак, число 0х80 сдвигаем на -7 разрядов влево, т.е. вправо. Получаем 0х1. Совпало. Кто бы сомневался.
Go to the top of the page
 
+Quote Post
add
сообщение Feb 9 2007, 12:48
Сообщение #25


Местный
***

Группа: Свой
Сообщений: 345
Регистрация: 10-10-05
Пользователь №: 9 459



mse, немогли бы Вы пояснитьследующее, если к примеру взять число 56 (0b00111000) после двух смещений влево получили 224 (0b11100000) и E=5. Это как считать? 1,96*2^5 в десятичке? несовсем понятно?!
заранее пасиба за ответ.


--------------------
Если задачу можно решить, то не надо тревожиться. А если нельзя решить, то тревожиться бесполезно.
Go to the top of the page
 
+Quote Post
mse
сообщение Feb 9 2007, 13:13
Сообщение #26


Знающий
****

Группа: Свой
Сообщений: 709
Регистрация: 3-05-05
Пользователь №: 4 693



Цитата(add @ Feb 9 2007, 12:48) *
mse, немогли бы Вы пояснитьследующее, если к примеру взять число 56 (0b00111000) после двух смещений влево получили 224 (0b11100000) и E=5. Это как считать? 1,96*2^5 в десятичке? несовсем понятно?!
заранее пасиба за ответ.

Всё верно. ;О) тока интертрепаццыя не та. 0хе0/2^7(!!!)=1,75. 1,75*2^5=56
Go to the top of the page
 
+Quote Post
Яrik
сообщение Feb 10 2007, 00:15
Сообщение #27


Частый гость
**

Группа: Новичок
Сообщений: 110
Регистрация: 8-01-07
Из: Украина
Пользователь №: 24 216



Цитата
Дык это не плавучая арифметика столько памяти жрет, а сама функция printf! Уже неоднократно и многими подчеркивался тот факт, что printf и sprintf требуют для работы от сотни байт до 1,5 килоБайт стековой памяти, то бишь ОЗУ. Так что советую оставить плавучку в покое, а лишь написать собственную функцию перевода числа в символьное представление.
Когда-то делал устройство, поддерживающее пакетную связь по RS-485, обработку клавиатуры и вывод на два четырехсимвольных семисегментника двух дробных чисел. Также долго мучал printf, пока не понял, что на имеющихся 256 байтах ОЗУ нельзя ее пользовать. Для вывода даже одного числа с фиксированной точкой и двумя знаками после запятой printf использовал больше 100 байт стека. А в распоряжении было всего около 50 байт В результата написал свою функцию типа поразрядного деления на степень 10, которая использовала не более 8 байт на стеке. За скоростью вычислений в таких случаях гнаться не нужно. Потому что обновлять информацию на индикаторе чаще 3 раз в секунду нет никакого смысла. Во-первых, человеческий глаз инертен. Во-вторых, наблюдателю нужно еще время чтобы осознать наблюдаемое число. Так что, используйте на здоровье плавучку и не используйте printf.


Понял. А не могли бы Вы привести пример или алгоритм собственно самого переобразования в текст? Я как то уже спрашивал на форуме по этому поводу, но неполучил врозумительного ответа. Спасибо.
Go to the top of the page
 
+Quote Post
rezident
сообщение Feb 10 2007, 01:16
Сообщение #28


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(Яrik @ Feb 10 2007, 02:15) *
Понял. А не могли бы Вы привести пример или алгоритм собственно самого переобразования в текст? Я как то уже спрашивал на форуме по этому поводу, но неполучил врозумительного ответа. Спасибо.

Вот из "пустыни" целая ветка примерно на эту же тему http://caxapa.ru/79812.html?todo=full
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 12:40
Рейтинг@Mail.ru


Страница сгенерированна за 0.01656 секунд с 7
ELECTRONIX ©2004-2016