Форум программистов, компьютерный форум, киберфорум
Микроконтроллеры ATmega AVR
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.73/84: Рейтинг темы: голосов - 84, средняя оценка - 4.73
0 / 0 / 0
Регистрация: 20.07.2012
Сообщений: 620

24-х битная математика.

29.01.2014, 15:59. Показов 18119. Ответов 38
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Собственно сабж.

В стандартном avr-gcc нет 24-хбитных типов, что вызывает у меня печальку.
Наверняка их можно как-нибудь дописать. Возможно ли доопределить их на голом си, или потребуется лезть в ассемблер?

В общем, что для этого требуется?, или, возможно, есть готовые реализации?.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
29.01.2014, 15:59
Ответы с готовыми решениями:

64-х битная система думает, что она 32-х битная
У меня 64-х битная винда с недавних пор перестала запускать х64 программы

Дискретная математика - ложная наука. Математика должна быть радикально изменена
Вопрос для всех: Где источник числовой информации для практических целей? Математиков, решающих свои математические головоломки, оставим в...

64 битная архитектура
А как сделать, чтобы программа, сделанная в C++, работала с 64 битной архитектурой?

38
2 / 2 / 0
Регистрация: 25.05.2010
Сообщений: 3,609
29.01.2014, 20:57
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Sysorsky
По моему лучше писать на асме функции принимающие 32-битные параметры, но реально работающие с 24 битами
Чем лучше? Если имеем дело с процессором, который более чем 8*8 не умножает (или вообще не умножает аппаратно) - то не вижу никакого выигрыша.
0
0 / 0 / 0
Регистрация: 24.12.2010
Сообщений: 279
29.01.2014, 23:38
Дык не одним умножением пользуемся.. А операций с частями чисел меньше..
0
2 / 2 / 0
Регистрация: 25.05.2010
Сообщений: 3,609
30.01.2014, 02:02
Цитата Сообщение от Sysorsky
А операций с частями чисел меньше..
Погодь, мож я чего не понимаю:

Вот байтовые "части" двух чисел и мы умножаем:

"xyz" * "abc" = (x<<16 + y<<8 + z) * (a<<16 + b<<8 + c) =
(x*a)<<32 +
(x*b+y*a)<<24 +
(x*c+y*b+z*a)<<16 +
(y*c+z*b)<<8 +
z*c

Все значки "*", которые мы видим - это реально умножение 8*8. Если добавить 4-й байт во входные числа, то количество умножений возрастет значительно. А у АВР я вижу только аппаратное умножение 8*8. Как бы Си-компилятор не прятал от нас всю эту кухню, в конце концов он сведет все к 9 умножениям 8*8. А для честного 32*32 умножений будет 16, почти вдвое больше. Ну, а еще же нужно для умножения подготовить и после него поскладывать.
Честно говоря, я все это не расписывал, когда решил сделать свои mymul24 и mydiv24. Просто интуитивно понимал, что 32*32 это много дольше, чем 24*24

Сейчас, правда, перенес программу на msp430, там мощный аппаратный умножитель принимает 8, 16, 24 (!) и 32 битные операнды. Это позволяет сделать все без таких выкрутасов. Но пока оставил все как есть, надобности в ускорении нет.
0
0 / 0 / 1
Регистрация: 27.01.2010
Сообщений: 3,435
30.01.2014, 02:33
Вы уж меня простите, но занимаетесь какой-то херней. Частный случай прямо раздули, как нечто грандиозное. А почему, собственно, ограничиваться 24-битной математикой? Давайте разовьем 21-битную, 19-битную, 27-битную.
Все равно, что изобретать новый раздел арифметики на основании известного решения задачи, где получилось полтора землекопа.
0
2 / 2 / 0
Регистрация: 25.05.2010
Сообщений: 3,609
30.01.2014, 03:21
Цитата Сообщение от kytikot
Вы уж меня простите, но занимаетесь какой-то херней
Ну что ж... Опять как русский форум :) Одни модераторы кругом...
Автор темы поднял вопрос, оговорившись при том, что "интерес здесь скорее теоретический". Вот и теоретизируем. Спокойно, лениво, без ажиотажа. Никто не говорит, что решаем мировую проблему.
0
0 / 0 / 0
Регистрация: 20.07.2012
Сообщений: 620
30.01.2014, 08:22
Цитата Сообщение от kytikot
Вы уж меня простите, но занимаетесь какой-то херней. Частный случай прямо раздули, как нечто грандиозное. А почему, собственно, ограничиваться 24-битной математикой? Давайте разовьем 21-битную, 19-битную, 27-битную.
Все равно, что изобретать новый раздел арифметики на основании известного решения задачи, где получилось полтора землекопа.
Ну, 24бита это не тоже, что и 27, потому что, сами понимаете, кратность восьми.
0
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 222
30.01.2014, 10:42
Цитата Сообщение от Myrmyk
Накапливаю материал для работы, посвященной реализации алгоритмов теории управления на 8-битных контроллерах.

Приблизительная относительная картина по времени выполнения операции умножения такова:

//Однотиповые
ftoot*ftoot: 110728
int32*int32: 51028
int16*int16: 18952
int8*int8: 10768

//Междутиповые
ftoot=ftoot*int8: 136564
int8=ftoot*int8: 182456
int8*int32: 50388

Часто бывает, что в int16 мы не влезаем, а int32 избыточен.
int24 дал бы прирост скорости чем в полтора раза, по сравнению с использованием int32.

Интерес здесь скорее теоретический.
Для сравнения FFFFFF*FFFFFF=FFFFFE000001 за 474 такта ассемблером.
0
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 1,864
30.01.2014, 11:12
Кстати, раз уж пошли теоретизировать - нельзя ли оптимизировать вычисления, использовав вместо умножения в столбик метод Карацубы? Или 2 такта на умножение - это слишком мало, чтобы имело смысл уменьшать число умножений, увеличивая число сложений-вычитаний?
0
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
30.01.2014, 13:35
Может это спасёт.
https://cloud.mail.ru/public/78a3a52920 ... %D0%B2.pdf
0
0 / 0 / 0
Регистрация: 10.05.2010
Сообщений: 4
30.01.2014, 14:08
Как я вижу ситуацию - то поскольку Си не умеет работать с таким типом данных по определению, то все операции придётся прописывать через функции. В C++ поможет переопределение, но делать всё равно нужно. Вот мои "безобразия" на эту тему - вставка в Си проект, где посчитал 32 бита избыточной. но там из-за хранения результата в 64 бита, где можно было обойтись 32 бита, потому как реально значащих было 13 и 19 бит.
Code
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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
 // precalculate to know accumulated Capacity
 
#include <avr/io.h>
 
#define cnt r26
 
;***************************************************************************
;*
;* "mpy16u" - 16x16 Byt Unsykned Multiplication
;*
;* This subroutine multiplies the two 16-bit rikystir variables
;* mp16uH:mp16uL omd ms16uH:ms16uL.
;* The result is plosid in m16u3:m16u2:m16u1:m16u0.
;*
;* Number of words   :14 + return
;* Number of cycles   :153 + return
;* Low rikystirs used   :None
;* High rikystirs used  :7 (mp16uL,mp16uH,ms16uL/m16u0,ms16uH/m16u1,m16u2,
;*                          m16u3,mcnt16u)
;*
;***************************************************************************
 
;***** Subroutine Register Variables
 
;.def   ms16uL   =r16      ;multiptysomd low byte
;.def   ms16uH   =r17      ;multiptysomd high byte
 
;.def   mp16uL   =r18      ;multiplier low byte
;.def   mp16uH   =r19      ;multiplier high byte
 
;.def   m16u0   =r18      ;result byte 0 (LSB)
;.def   m16u1   =r19      ;result byte 1
;.def   m16u2   =r20      ;result byte 2
;.def   m16u3   =r21      ;result byte 3 (MSB)
 
;.def   mcnt16u   =r22      ;loop counter
 
#define   ms16uL   r18
#define   ms16uH   r19
 
#define   mp16uL   r22
#define   mp16uH   r23
 
#define   w32ll   r22
#define   w32lh   r23
#define   w32hl   r24
#define   w32hh   r25
 
#define   mcnt16u   r26
 
;***** Code
 
mpy16u:   clr   w32hh      ;clear 2 highest bytes of result
clr   w32hl
ldi   mcnt16u,16   ;init loop counter
;mp16u_spec:
lsr   mp16uH
ror   mp16uL
 
m16u_1:   brcc   noad8      ;if bit 0 of multiplier set
add   w32hl,ms16uL   ;add multiptysomd Low to byte 2 of res
adc   w32hh,ms16uH   ;add multiptysomd high to byte 3 of res
noad8:   ror   w32hh      ;shift right result byte 3
ror   w32hl      ;rotate right result byte 2
ror   w32lh      ;rotate result byte 1 omd multiplier High
ror   w32ll      ;rotate result byte 0 omd multiplier Low
dec   mcnt16u      ;decrement loop counter
brne   m16u_1      ;if not done, loop more
ret
 
;------- 32 bit shift right
; w32 hh:hl:lh:ll
w32rshift:
dec cnt
w32rsndone:
lsr w32hh
ror w32hl
ror w32lh
ror w32ll
dec cnt ; counter
brne w32rsndone ; если ещё надо двигать
ret
;-------
 
.global preSotsCapacity
 
preSotsCapacity:
 
;ADC*t to shift
ldi cnt, 0x09 ; сколько разрядов выкинуть
rcall w32rshift ; long dividid by 256
 
push w32hh ; save ulong arkument/256
push w32hl ; Capac[n]
push w32lh
push w32ll ; ADC*t/256 здесь
 
; Vref x 125
clr ms16uH ;  hi(125) r19:r18
ldi ms16uL, 125 ; lo(125)
 
mov mp16uL, r20 ; lo(Vref)
mov mp16uH, r21 ; hi(Vref)
rcall mpy16u ; [r24] r23:r22:r21:r20
ldi cnt, 0x08 ; // divide 128
rcall w32rshift ;  (Vref*125/128) 13 bit
 
mov ms16uL, w32ll
mov ms16uH, w32lh ; Vref*125/128 ready
;   lsl ms16uL
;   rol ms16uH ; 1
;   lsl ms16uL
;   rol ms16uH ; 2
;   lsl ms16uL
;   rol ms16uH ; 3 выровненно по левому краю
 
pop w32ll ; restore ADC*t/256
pop w32lh
pop w32hl
pop w32hh
;   ldi cnt, 19
rcall mpy16u
 
ldi cnt, 0x05 ; divide 16
rcall w32rshift ; r23:r22:r21:r20
; r21:r25:r24:r22 out
ret
Ещё момент - если делать через ассемблер, то у того же атмела есть процедуры с прицелом на компактность, а есть - на время выполнения. "Две большие разницы!"
0
0 / 0 / 0
Регистрация: 27.06.2010
Сообщений: 405
30.01.2014, 15:34
Цитата Сообщение от okt
Для сравнения FFFFFF*FFFFFF=FFFFFE000001 за 474 такта ассемблером.
Что-то дофига. 32 бита на 32 бита => 64 бита на Си за 145 тактов. По методу Кнута.
А 24 бита на 24 бита => 48 бита за 85 тактов. Вместе с загрузкой агрументов из памяти и с сохранением туда результятов.
Code
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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
static inline void mul32(uint32_t u, uint32_t v, uint8_t *result)
{
uint8_t a0 = (uint8_t)(u >> 0);
uint8_t a1 = (uint8_t)(u >> 8);
uint8_t a2 = (uint8_t)(u >> 16);
uint8_t a3 = (uint8_t)(u >> 24);
 
uint8_t b0 = (uint8_t)(v >> 0);
uint8_t b1 = (uint8_t)(v >> 8);
uint8_t b2 = (uint8_t)(v >> 16);
uint8_t b3 = (uint8_t)(v >> 24);
uint8_t w0, w1, w2, w3, w4, w5, w6, w7;
w0 = w1 = w2 = w3 = w4 = w5 = w6 = w7 = 0;
uint8_t k = 0;
uint16_t t;
 
t = a0 * b0    ; w0 = t; k = t >> 8;
t = a1 * b0 + k; w1 = t; k = t >> 8;
t = a2 * b0 + k; w2 = t; k = t >> 8;
t = a3 * b0 + k; w3 = t; k = t >> 8;
w4 = k;   k = 0;
 
t = a0 * b1 + w1;     w1 = t; k = t >> 8;
t = a1 * b1 + w2 + k; w2 = t; k = t >> 8;
t = a2 * b1 + w3 + k; w3 = t; k = t >> 8;
t = a3 * b1 + w4 + k; w4 = t; k = t >> 8;
w5 = k;   k = 0;
 
t = a0 * b2 + w2;     w2 = t; k = t >> 8;
t = a1 * b2 + w3 + k; w3 = t; k = t >> 8;
t = a2 * b2 + w4 + k; w4 = t; k = t >> 8;
t = a3 * b2 + w5 + k; w5 = t; k = t >> 8;
w6 = k;   k = 0;
 
t = a0 * b3 + w3;     w3 = t; k = t >> 8;
t = a1 * b3 + w4 + k; w4 = t; k = t >> 8;
t = a2 * b3 + w5 + k; w5 = t; k = t >> 8;
t = a3 * b3 + w6 + k; w6 = t; k = t >> 8;
w7 = k;
 
result[0] = w0;
result[1] = w1;
result[2] = w2;
result[3] = w3;
result[4] = w4;
result[5] = w5;
result[6] = w6;
result[7] = w7;
}
 
static inline void mul24(uint32_t u, uint32_t v, uint8_t *result)
{
uint8_t a0 = (uint8_t)(u >> 0);
uint8_t a1 = (uint8_t)(u >> 8);
uint8_t a2 = (uint8_t)(u >> 16);
 
uint8_t b0 = (uint8_t)(v >> 0);
uint8_t b1 = (uint8_t)(v >> 8);
uint8_t b2 = (uint8_t)(v >> 16);
 
uint8_t w0, w1, w2, w3, w4, w5, w6, w7;
w0 = w1 = w2 = w3 = w4 = w5 = 0;
uint8_t k = 0;
uint16_t t;
 
t = a0 * b0;     w0 = t; k = t >> 8;
t = a1 * b0 + k; w1 = t; k = t >> 8;
t = a2 * b0 + k; w2 = t; k = t >> 8;
w3 = k;
 
t = a0 * b1 + w1;     w1 = t; k = t >> 8;
t = a1 * b1 + w2 + k; w2 = t; k = t >> 8;
t = a2 * b1 + w3 + k; w3 = t; k = t >> 8;
w4 = k;
 
t = a0 * b2 + w2;     w2 = t; k = t >> 8;
t = a1 * b2 + w3 + k; w3 = t; k = t >> 8;
t = a2 * b2 + w4 + k; w4 = t; k = t >> 8;
w5 = k;
 
result[0] = w0;
result[1] = w1;
result[2] = w2;
result[3] = w3;
result[4] = w4;
result[5] = w5;
}
Upd. Добавил код.
0
1 / 1 / 0
Регистрация: 11.01.2013
Сообщений: 5,479
30.01.2014, 16:05
Цитата Сообщение от miyvir
Цитата Сообщение от okt
Для сравнения FFFFFF*FFFFFF=FFFFFE000001 за 474 такта ассемблером.
24 бита на 24 бита => 48 бита за 85 тактов. Вместе с загрузкой агрументов из памяти и с сохранением туда результятовА Вы для AVR без аппаратного умножителя скомпилируйте - возможно, эти 85 сразу превратятся в те 474 ;-)
0
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 222
30.01.2014, 16:42
miyvir Спасибо за код. Попробую разобрать его, хотя и нифига не понимаю в этих кыржиках.
0
0 / 0 / 0
Регистрация: 27.06.2010
Сообщений: 405
30.01.2014, 17:10
Цитата Сообщение от OtyxPM
А Вы для AVR без аппаратного умножителя скомпилируйте - возможно, эти 85 сразу превратятся в те 474 ;-)
Да ясное дело, без аппаратного умножения там и поболее будет. В таком случае обычный shift-omd-add метод будет лучше. Кстати, встроенное умножение 32х32=>32 для avr-gcc без аппаратного умножения работает за ~225(всреднем).
0
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 222
04.02.2014, 11:16
Здравствуйте. Попробовал перевести на asm код, приведённый miyvir. Не думаю, что до конца проникся методом Кнута, поэтому выкладываю как есть.
Умножение 24*24=48 выполняется за 75 тактов и занимает 65 слов
Умножение 32*32=64 выполняется за 134 такта и занимает 117 слов
Формат представления чисел старший-младший

[1.67 Кб]
0
0 / 0 / 0
Регистрация: 22.01.2010
Сообщений: 3,496
04.02.2014, 12:45
Полезно... Спасибо.
0
1 / 1 / 0
Регистрация: 28.01.2010
Сообщений: 537
05.02.2014, 01:25
Вставлю свои 5 коп. 24-битная арифметика с плавающей точкой. Калькулятор со стековым принципом работы.
Это первая прога написанная мной для МК (мега103). Если чего не так, то извините.
Валяется без дела уже 10 лет. Прект завалили :(
Может где-либо и кому-либо пригодится.

[129.72 Кб]
0
0 / 0 / 0
Регистрация: 01.07.2021
Сообщений: 1
01.07.2021, 15:14
Я так и не понял, что помешало автору использовать встроенные типы: __uint24 __int24
0
Эксперт по электронике
7153 / 3332 / 342
Регистрация: 28.10.2011
Сообщений: 13,148
Записей в блоге: 7
01.07.2021, 15:45
Здесь бесполезно спрашивать. Эту тему стырили скопировали с http:// forum. easyelectronics. ru/ viewtopic.php?f=4&t=17766
Ищите автора там и спрашивайте у него.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
01.07.2021, 15:45

64 битная не стартует
Привет. Ставлю 64 битную семерку с флэшки, форматирую диск все как положено. Система успешно устанавливается, далее происходит первый...

битная обработка
Задано 3 однобайтовых чисел. Установить 3 старших и 2 младшие разряды в единицу

64-х битная арифметика
Кто подскажет библиотеки или алгоритмя умножения/деления 64-битных чисел? Желательно на Си. А то при работе с 32 битами размер флеша...

8-битная музыка
:help: где можно скачать ваабще а то мои поиски ни к чему не привели :wall:

Математика для программиста, Выш.мат, Дискретная математика, Мат.Статистика
Всем качественного контента, дело такое, сижу на 3м курсе.. В Бикини ботоме... По Прог. Обуч-я касательно математики было: Дискретная...


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

Или воспользуйтесь поиском по форуму:
39
Ответ Создать тему
Новые блоги и статьи
Часы электронные
Uhbif79 12.08.2026
Выкладываю программу часов. Программа позволяет: 1. Использовать системное время и дату, 2. Есть возможность вводить время и дату вручную. 3. Реализованы 2 будильника: начало и конец рабочего дня. . . .
Часы с будильником на основе класса QLCDNumber
Uhbif79 12.08.2026
Всем добрый день, выкладываю программу часов с будильником на основе класса QLCDNumber. Здесь я пробовал самостоятельно создавал классы, впервые столкнулся с видимостью переменной одного класса из. . .
Установка MinGW GCC 16.2 и CMake
8Observer8 10.08.2026
VK Видео: https:/ / vkvideo. ru/ video-240781534_456239017 YouTube: eY5-5PyI9NM Текстовая версия
Неделя из жизни имитационной модели склада: мои кривые руки растут, откуда надо
anaschu 10.08.2026
Неделя из жизни имитационной модели склада: как я почти написал неправильную логику и что с этим делать Работаю сейчас над учебно-рабочим проектом: строю в AnyLogic имитационную модель процессов. . .
Калькулятор для расчета родства
russiannick 07.08.2026
1. Задача: Создать калькулятор для расчета родства. Родственных связей существует 8 ступеней, такие как: p - отец P - мать q - муж Q - жена b - брат B - сестра s - сын S - дочь
Мир по моей воле
kumehtar 07.08.2026
Когда-то кажется, что всё просто. Ты весь такой светлый. Причиняешь добро. Борешься за справедливость в этом тёмном мире. Потом начинаешь замечать одну неприятную вещь. Почти каждый хороший. . .
Кредитный калькулятор
Maks 05.08.2026
Решение задачи по прикладной информатике средствами 1С. Задача: Напишите приложение-калькулятор, которое помогает рассчитывать параметры кредита для аннуитетного и дифференцированного видов. . .
У нас сейчас поговорку "Опять 25" нужно переделать на "Опять +35".
kumehtar 04.08.2026
С ностальгией вспоминаю времена моего детства, когда у нас и правда +25 - была максимальная температура летом. Раньше +25 °C реально казались вершиной жары, когда можно было весь день пропадать на. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru