0 / 0 / 0
Регистрация: 20.07.2012
Сообщений: 620
|
|
1 | |
24-х битная математика.29.01.2014, 15:59. Показов 17147. Ответов 38
Метки нет (Все метки)
Собственно сабж.
В стандартном avr-gcc нет 24-хбитных типов, что вызывает у меня печальку. Наверняка их можно как-нибудь дописать. Возможно ли доопределить их на голом си, или потребуется лезть в ассемблер? В общем, что для этого требуется?, или, возможно, есть готовые реализации?.
0
|
29.01.2014, 15:59 | |
Ответы с готовыми решениями:
38
64-х битная система думает, что она 32-х битная Дискретная математика - ложная наука. Математика должна быть радикально изменена 64 битная архитектура 64 битная не стартует |
2 / 2 / 0
Регистрация: 25.05.2010
Сообщений: 3,609
|
|
29.01.2014, 20:57 | 21 |
Сообщение от Sysorsky
0
|
0 / 0 / 0
Регистрация: 24.12.2010
Сообщений: 279
|
|
29.01.2014, 23:38 | 22 |
Дык не одним умножением пользуемся.. А операций с частями чисел меньше..
0
|
2 / 2 / 0
Регистрация: 25.05.2010
Сообщений: 3,609
|
|
30.01.2014, 02:02 | 23 |
Сообщение от 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 |
Вы уж меня простите, но занимаетесь какой-то херней. Частный случай прямо раздули, как нечто грандиозное. А почему, собственно, ограничиваться 24-битной математикой? Давайте разовьем 21-битную, 19-битную, 27-битную.
Все равно, что изобретать новый раздел арифметики на основании известного решения задачи, где получилось полтора землекопа.
0
|
2 / 2 / 0
Регистрация: 25.05.2010
Сообщений: 3,609
|
|
30.01.2014, 03:21 | 25 |
Сообщение от kytikot
Автор темы поднял вопрос, оговорившись при том, что "интерес здесь скорее теоретический". Вот и теоретизируем. Спокойно, лениво, без ажиотажа. Никто не говорит, что решаем мировую проблему.
0
|
0 / 0 / 0
Регистрация: 20.07.2012
Сообщений: 620
|
|
30.01.2014, 08:22 | 26 |
Сообщение от kytikot
0
|
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 222
|
|
30.01.2014, 10:42 | 27 |
Сообщение от Myrmyk
0
|
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 1,864
|
|
30.01.2014, 11:12 | 28 |
Кстати, раз уж пошли теоретизировать - нельзя ли оптимизировать вычисления, использовав вместо умножения в столбик метод Карацубы? Или 2 такта на умножение - это слишком мало, чтобы имело смысл уменьшать число умножений, увеличивая число сложений-вычитаний?
0
|
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
|
|
30.01.2014, 13:35 | 29 |
Может это спасёт.
https://cloud.mail.ru/public/78a3a52920 ... %D0%B2.pdf
0
|
0 / 0 / 0
Регистрация: 10.05.2010
Сообщений: 4
|
|
30.01.2014, 14:08 | 30 |
Как я вижу ситуацию - то поскольку Си не умеет работать с таким типом данных по определению, то все операции придётся прописывать через функции. В C++ поможет переопределение, но делать всё равно нужно. Вот мои "безобразия" на эту тему - вставка в Си проект, где посчитал 32 бита избыточной. но там из-за хранения результата в 64 бита, где можно было обойтись 32 бита, потому как реально значащих было 13 и 19 бит.
Код
// 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 | 31 |
Сообщение от okt
А 24 бита на 24 бита => 48 бита за 85 тактов. Вместе с загрузкой агрументов из памяти и с сохранением туда результятов. Код
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; }
0
|
1 / 1 / 0
Регистрация: 11.01.2013
Сообщений: 5,479
|
|
30.01.2014, 16:05 | 32 |
Сообщение от miyvir
0
|
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 222
|
|
30.01.2014, 16:42 | 33 |
miyvir Спасибо за код. Попробую разобрать его, хотя и нифига не понимаю в этих кыржиках.
0
|
0 / 0 / 0
Регистрация: 27.06.2010
Сообщений: 405
|
|
30.01.2014, 17:10 | 34 |
Сообщение от OtyxPM
0
|
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 222
|
|
04.02.2014, 11:16 | 35 |
Здравствуйте. Попробовал перевести на 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 | 36 |
Полезно... Спасибо.
0
|
1 / 1 / 0
Регистрация: 28.01.2010
Сообщений: 537
|
|
05.02.2014, 01:25 | 37 |
Вставлю свои 5 коп. 24-битная арифметика с плавающей точкой. Калькулятор со стековым принципом работы.
Это первая прога написанная мной для МК (мега103). Если чего не так, то извините. Валяется без дела уже 10 лет. Прект завалили :( Может где-либо и кому-либо пригодится. [129.72 Кб]
0
|
0 / 0 / 0
Регистрация: 01.07.2021
Сообщений: 1
|
|
01.07.2021, 15:14 | 38 |
Я так и не понял, что помешало автору использовать встроенные типы: __uint24 __int24
0
|
01.07.2021, 15:45 | 39 |
Здесь бесполезно спрашивать. Эту тему
Ищите автора там и спрашивайте у него.
0
|
01.07.2021, 15:45 | |
01.07.2021, 15:45 | |
Помогаю со студенческими работами здесь
39
битная обработка 64-х битная арифметика 8-битная музыка Математика для программиста, Выш.мат, Дискретная математика, Мат.Статистика OutOfMemory и 32'битная Java Бывает ли Миранда 64-битная? Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |