Форум программистов, компьютерный форум, киберфорум
Наши страницы
Микроконтроллеры Atmega AVR
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.83/138: Рейтинг темы: голосов - 138, средняя оценка - 4.83
putmom
0 / 0 / 0
Регистрация: 05.02.2012
Сообщений: 35
1

Деление на 10.

09.01.2013, 10:03. Просмотров 25261. Ответов 67
Метки нет (Все метки)

Нашел тут статейку по методам деления на 10 (http://we.iosyitistromyss.ru/Soft/pr...ye-chisla.html).
Заинтересовал метод сдвигами и сложениями.
Цитирую:
Код:
struct divmod10_t
{
uint32_t quot;
uint8_t rem;
};
inline static divmod10_t divmodu10(uint32_t n)
{
divmod10_t res;
// умножаем на 0.8
res.quot = n >> 1;
res.quot += res.quot >> 1;
res.quot += res.quot >> 4;
res.quot += res.quot >> 8;
res.quot += res.quot >> 16;
uint32_t qq = res.quot;
// делим на 8
res.quot >>= 3;
// вычисляем остаток
res.rem = uint8_t(n - ((res.quot << 1) + (qq & ~7ul)));
// корректируем остаток и частное
if(res.rem > 9)
{
res.rem -= 10;
res.quot++;
}
return res;
}

Выглядит страшно и непонятно, но на самом деле всё просто. Сначала умножаем исходное число на 0.8 или 0.1100 1100 1100 1100 1100 1100 1100 1100 в двоичном представлении. Очень удобно, что дробь периодическая и удалось обойтись всего пятью сдвигами и четырьмя сложениями. Далее делим то, что получилось на 8, сдвигая на 3 разряда вправо. Получается исходное число делённое на 10 с точностью до единицы из-за ошибок округления.

Сижу и не понимаю, как всё таки на 0.8 умножать ? Какие то сдвиги вижу в коде, но Си не понимаю =(
Разжуйте пожалуйста как на ассемблере умножить на 0.8.
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
09.01.2013, 10:03
Ответы с готовыми решениями:

Задача про деление яблок (целочисленное деление)
Ребят,помогите с задачкой,как написать input.txt и output.txt? Помогите решить задачу. C++....

Умножение, деление и деление с остатком
Рассмотрим эти операции на примере. static void Main() { int i = 100, j = 15; double a =...

Деление знаковых чисел с выводом ошибки "Деление на ноль"
Собственно поставили передо мной задачу - написать прогу деления двух чисел, причем что бы...

Деление
Всем привет! Нужна помошь по математике :wacko: Нужно делить дробные числа. Максимальное число...

Деление
data SEGMENT a DW 20 b DW 6 c DW ? data ENDS code SEGMENT assume cs:code,ds:data...

67
YTYOUT
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
09.01.2013, 10:28 2
Плиз

[163.39 Кб]
0
putmom
0 / 0 / 0
Регистрация: 05.02.2012
Сообщений: 35
09.01.2013, 10:42 3
Цитата Сообщение от YTYOUT
Плиз
Спасибо, но тут не сдвигами деление на 10.
Такие процедуры для 8-ми битных переменных я делал.
Мне нужно быстрое деление на 10, как в примере в моём первом посте, но на ассемблере.
0
ptoop
0 / 0 / 0
Регистрация: 19.09.2010
Сообщений: 1,761
09.01.2013, 11:09 4
Есть процедура разложения 16-битного числа в десятичные цифры, там как раз делениями на 10 и выделением остатка. Надо?
Правда циклом.
0
Bytt
0 / 0 / 0
Регистрация: 22.08.2009
Сообщений: 525
09.01.2013, 11:11 5
[QUOTE="putmom"]Нашел тут статейку по методам деления на 10 (http://we.iosyitistromyss.ru/Soft/pr...ye-chisla.html).
Заинтересовал метод сдвигами и сложениями.
Цитирую:
[QUOTE="Цитата:[/QUOTE]
Код:
struct divmod10_t
{
uint32_t quot;
uint8_t rem;
};
inline static divmod10_t divmodu10(uint32_t n)
{
divmod10_t res;
// умножаем на 0.8
res.quot = n >> 1;
res.quot += res.quot >> 1;
res.quot += res.quot >> 4;
res.quot += res.quot >> 8;
res.quot += res.quot >> 16;
uint32_t qq = res.quot;
// делим на 8
res.quot >>= 3;
// вычисляем остаток
res.rem = uint8_t(n - ((res.quot << 1) + (qq & ~7ul)));
// корректируем остаток и частное
if(res.rem > 9)
{
res.rem -= 10;
res.quot++;
}
return res;
}

Выглядит страшно и непонятно, но на самом деле всё просто. Сначала умножаем исходное число на 0.8 или 0.1100 1100 1100 1100 1100 1100 1100 1100 в двоичном представлении. Очень удобно, что дробь периодическая и удалось обойтись всего пятью сдвигами и четырьмя сложениями. Далее делим то, что получилось на 8, сдвигая на 3 разряда вправо. Получается исходное число делённое на 10 с точностью до единицы из-за ошибок округления.

Сижу и не понимаю, как всё таки на 0.8 умножать ? Какие то сдвиги вижу в коде, но Си не понимаю =(
Разжуйте пожалуйста как на ассемблере умножить на 0.8.
Код
    res.quot = n >> 1;      //0.5x
res.quot += res.quot >> 1;    //0.75x
res.quot += res.quot >> 4;    //0.796875x
res.quot += res.quot >> 8;    //0.7999877929685x
res.quot += res.quot >> 16;   //0.79999999813735485076904296875x
Или нет?
0
YTYOUT
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
09.01.2013, 11:13 6
10=0xA=2^3+2= Всё осталось только воспользоваться сдвигами- догадаетесь как это сделать надеюсь сами.
0
putmom
0 / 0 / 0
Регистрация: 05.02.2012
Сообщений: 35
09.01.2013, 11:17 7
Цитата Сообщение от Bytt
Код:
res.quot = n >> 1; //0.5x
res.quot += res.quot >> 1; //0.75x
res.quot += res.quot >> 4; //0.796875x
res.quot += res.quot >> 8; //0.7999877929685x
res.quot += res.quot >> 16; //0.79999999813735485076904296875x
Или нет?
Я же выше писал, что Си не понимаю, мне пожалуйста тоже самое на ассемблере.
0
putmom
0 / 0 / 0
Регистрация: 05.02.2012
Сообщений: 35
09.01.2013, 11:18 8
Цитата Сообщение от ptoop
Есть процедура разложения 16-битного числа в десятичные цифры, там как раз делениями на 10 и выделением остатка. Надо?
Правда циклом.
Циклом я и сам написал, но долго работает, надо сдвигами.
0
putmom
0 / 0 / 0
Регистрация: 05.02.2012
Сообщений: 35
09.01.2013, 11:19 9
Цитата Сообщение от YTYOUT
10=0xA=2^3+2= Всё осталось только воспользоваться сдвигами- догадаетесь как это сделать надеюсь сами.
Так то оно так, это я понял, но как это реализовать в коде не понимаю, учусь еще, да и туповат маленько.
3 раза сдвинуть вправо это понятно, но как 2 получить ?
0
YTYOUT
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
09.01.2013, 11:24 10
lsr и ror = деление на 2
lsl & rol = умножение на 2
add & adc - сложение
Осталось раставить
subi xз,-2 прибавить
0
putmom
0 / 0 / 0
Регистрация: 05.02.2012
Сообщений: 35
09.01.2013, 11:36 11
Цитата Сообщение от YTYOUT
lsr и ror = деление на 2
lsl & rol = умножение на 2
add & adc - сложение
Осталось раставить
subi xз,-2 прибавить
Давайте попробуем как Вы говорите.
Допустим у нас число 210 (0b11010010)
делим его на 8
Код
ldi  temp, 210
lsr  temp
lsr  temp
lsr  temp
subi temp, -2
в результате получаем 28, на самом деле надо 2 вычитать т.к. делим, но тогда получим 24, что далеко от верного результата 21.
0
ptoop
0 / 0 / 0
Регистрация: 19.09.2010
Сообщений: 1,761
09.01.2013, 11:41 12
Верный - 26, получится тремя сдвигами. Это если на 8 :)
0
YTYOUT
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
09.01.2013, 11:42 13
Код
lsr  temp
lsr  temp
lsr  temp
Не правильно - читаем о каждой из приведённых мной команд и исправляем
0
Johmmy0007
1 / 1 / 0
Регистрация: 30.08.2011
Сообщений: 9,944
09.01.2013, 11:45 14
Цитата Сообщение от putmom
Цитата Сообщение от YTYOUT
Плиз
Спасибо, но тут не сдвигами деление на 10.
Такие процедуры для 8-ми битных переменных я делал.
Мне нужно быстрое деление на 10, как в примере в моём первом посте, но на ассемблере.
часто тупо в цикле вычитатают из числа 10, подсчитывая количество циклов, пока результат вычитания не станет меньше 0
0
ptoop
0 / 0 / 0
Регистрация: 19.09.2010
Сообщений: 1,761
09.01.2013, 12:00 15
Да и сомневаюсь я, что сдвигами выйдет быстрее.
0
putmom
0 / 0 / 0
Регистрация: 05.02.2012
Сообщений: 35
09.01.2013, 12:05 16
Цитата Сообщение от YTYOUT
Код:
lsr temp
lsr temp
lsr temp Не правильно - читаем о каждой из приведённых мной команд и исправляем
Я же намекнул, туповат я и учусь еще. Не пойму как надо исправлять, напишите лучше сами =)
0
ptoop
0 / 0 / 0
Регистрация: 19.09.2010
Сообщений: 1,761
09.01.2013, 12:05 17
http://www.microchip.ru/phorum/read.php ... 77&t=14577
И да, скольки разрядное число делить-то?
0
putmom
0 / 0 / 0
Регистрация: 05.02.2012
Сообщений: 35
09.01.2013, 12:06 18
Цитата Сообщение от Johmmy0007
Цитата Сообщение от putmom
Цитата Сообщение от YTYOUT
Плиз
Спасибо, но тут не сдвигами деление на 10.
Такие процедуры для 8-ми битных переменных я делал.
Мне нужно быстрое деление на 10, как в примере в моём первом посте, но на ассемблере.
часто тупо в цикле вычитатают из числа 10, подсчитывая количество циклов, пока результат вычитания не станет меньше 0
Такая процедура у меня есть, я её даже не искал нигде, она очевидна, и сразу её написал.
0
drvtos
1 / 1 / 0
Регистрация: 25.05.2010
Сообщений: 3,610
09.01.2013, 12:08 19
Цитата Сообщение от Johmmy0007
часто тупо в цикле вычитатают из числа 10, подсчитывая количество циклов, пока результат вычитания не станет меньше 0
+1
Я даже удивлен, что кого-то серьезно заинтересовало иначе делать :)
Так же и большое число преобразовать в 10-чное, только сначала пробуем отнимать самую большую степень десятки (например, 1000), потом, если отнимать нечего - 100, а после отнимания 10 получим последнюю цифру результата.

2 putmom: есди у тебя цель потрахаться с программированием - тогда да, можешь разбираться дальше. А все же метод отнимания дает результат - и поробуй его обругать, если хочешь. Ну, ТИПА, сравнить 2 метода. А мы посмотрим.

А, вижу ты не понял с многоразрядным. Ну, читай мой пост
0
YTYOUT
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
09.01.2013, 12:09 20
Цитата Сообщение от putmom
Цитата Сообщение от YTYOUT
Код:
lsr temp
lsr temp
lsr temp Не правильно - читаем о каждой из приведённых мной команд и исправляем
Я же намекнул, туповат я и учусь еще. Не пойму как надо исправлять, напишите лучше сами =)
Нет уж , если сами не найдёте решение, Вам не надо заниматся MC - там математика на каждом шаге
0
09.01.2013, 12:09
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
09.01.2013, 12:09

Деление на 0
Все говорят на 0 делить нельзя,но я поделил,в чем тут подвох #include &lt;iostream&gt; using...

Деление на 5
Дано число в шестнадцатеричной системе счисления. Число может быть очень большое. Требуется...

деление
подскажите. допустим в переменной типа string находится число 8192. требуется разделить это число...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru