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

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> преобразования из дополнительного кода в прямой, есть хитрый способ?
skopus
сообщение Feb 16 2006, 12:16
Сообщение #1


Участник
*

Группа: Свой
Сообщений: 65
Регистрация: 31-08-05
Из: Moscow
Пользователь №: 8 124



Я написал вот такую вот функцию, но она работает слишком медленно (132 цикла при отключенной оптимизации). Может быть есть какой-то лаконичный алгоритм? Или придется переписать по такому же принципу но на асме?

//возвращает модуль числа
//отрицательное число преобразутся из обратного кода в прямой
int SignedToUnsigned(int sgnval)
{
if ((sgnval&0x8000)==0x8000) //если старший бит =1, то число отрицательное, следовательно записано в дополнительном коде
{
sgnval -= 0x0001; //отнять младшую 1
//инверсия
if ((sgnval&0x0001)==0x0001) sgnval=sgnval&0xFFFE; // 1111 1111 1111 1110
else sgnval=sgnval|0x0001; // 0000 0000 0000 0001
if ((sgnval&0x0002)==0x0002) sgnval=sgnval&0xFFFD; // 1111 1111 1111 1101
else sgnval=sgnval|0x0002; // 0000 0000 0000 0010
if ((sgnval&0x0004)==0x0004) sgnval=sgnval&0xFFFB; // 1111 1111 1111 1011
else sgnval=sgnval|0x0004; // 0000 0000 0000 0100
if ((sgnval&0x0008)==0x0008) sgnval=sgnval&0xFFF7; // 1111 1111 1111 0111
else sgnval=sgnval|0x0008; // 0000 0000 0000 1000

if ((sgnval&0x0010)==0x0010) sgnval=sgnval&0xFFEF; // 1111 1111 1110 1111
else sgnval=sgnval|0x0010; // 0000 0000 0001 0000
if ((sgnval&0x0020)==0x0020) sgnval=sgnval&0xFFDF; // 1111 1111 1101 1111
else sgnval=sgnval|0x0020; // 0000 0000 0010 0000
if ((sgnval&0x0040)==0x0040) sgnval=sgnval&0xFFBF; // 1111 1111 1011 1111
else sgnval=sgnval|0x0040; // 0000 0000 0100 0000
if ((sgnval&0x0080)==0x0080) sgnval=sgnval&0xFF7F; // 1111 1111 0111 1111
else sgnval=sgnval|0x0080; // 0000 0000 1000 0000

if ((sgnval&0x0100)==0x0100) sgnval=sgnval&0xFEFF;
else sgnval=sgnval|0x0100;
if ((sgnval&0x0200)==0x0200) sgnval=sgnval&0xFDFF;
else sgnval=sgnval|0x0200;
if ((sgnval&0x0400)==0x0400) sgnval=sgnval&0xFBFF;
else sgnval=sgnval|0x0400;
if ((sgnval&0x0800)==0x0800) sgnval=sgnval&0xF7FF;
else sgnval=sgnval|0x0800;

if ((sgnval&0x1000)==0x1000) sgnval=sgnval&0xEFFF;
else sgnval=sgnval|0x1000;
if ((sgnval&0x2000)==0x2000) sgnval=sgnval&0xDFFF;
else sgnval=sgnval|0x2000;
if ((sgnval&0x4000)==0x4000) sgnval=sgnval&0xBFFF;
else sgnval=sgnval|0x4000;
if ((sgnval&0x8000)==0x8000) sgnval=sgnval&0x7FFF;
else sgnval=sgnval|0x8000;
}
return sgnval;
}

Сообщение отредактировал skopus - Feb 16 2006, 12:20
Go to the top of the page
 
+Quote Post
BVU
сообщение Feb 16 2006, 12:34
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 301
Регистрация: 30-11-04
Из: Россия, Н.Новгород
Пользователь №: 1 264



А зачем так длинно-то?
http://ru.wikipedia.org/wiki/%D0%94%D0%BE%...%BA%D0%BE%D0%B4
Можно и так:
Диапазон отрицательный чисел известен? Делаем сравнение.
Далее из отрицательного числа в дополнительном коде вычитаем единицу и делаем побитовую инверсию частного (модуль значения).

P.S. А вообще-то, надо бы Вам, перечиталь алгебру логики и представление чисел для ЭВМ.


--------------------
Не корысти ради, не в целях наживы, а во исполнение велений души!
Go to the top of the page
 
+Quote Post
Camelot
сообщение Feb 16 2006, 12:39
Сообщение #3


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

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



может вместо if сделайте побитовый xor c FFFF?
Go to the top of the page
 
+Quote Post
zltigo
сообщение Feb 16 2006, 12:45
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(skopus @ Feb 16 2006, 14:16) *
Я написал вот такую вот функцию, но она работает слишком медленно (132 цикла при отключенной оптимизации).

Я многое видел, но оказалось передела нет

if( value < 0 )
value = ~value + 1;


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
prottoss
сообщение Feb 16 2006, 12:46
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Х = abs(X)


--------------------
Go to the top of the page
 
+Quote Post
Виктория
сообщение Feb 16 2006, 12:49
Сообщение #6


инженер
****

Группа: Свой
Сообщений: 520
Регистрация: 19-09-05
Из: Самара
Пользователь №: 8 701



smile.gifsmile.gifsmile.gifsmile.gifsmile.gif - бесконечно много раз

Извинения всем! Но второй раз такое увидеть (в течении всего лишь последних 2-х месяцев), откуда только этот код вспывает!

Scopus -> BVU и zltigo уже ответили. А вообще то это все следует из понятия "дополнительный код"

Сообщение отредактировал Vic1 - Feb 16 2006, 12:54
Go to the top of the page
 
+Quote Post
defunct
сообщение Feb 16 2006, 12:53
Сообщение #7


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата
int SignedToUnsigned(int sgnval)
{
if ((sgnval&0x8000)==0x8000) //


А с чего Вы взяли, что int занимает 2 байта?!
писали бы хотя бы short..

Цитата
Vic1
откуда только этот код вспывает!

Очевидно из серии примеров - "Как нельзя писать программы" smile.gif

Сообщение отредактировал defunct - Feb 16 2006, 13:02
Go to the top of the page
 
+Quote Post
zltigo
сообщение Feb 16 2006, 12:56
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(prottoss @ Feb 16 2006, 14:46) *
Х = abs(X)

Для данного случая, использование такого макроса (обычно) - не наглядно :-)

Сообщение отредактировал zltigo - Feb 16 2006, 12:57


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
BVU
сообщение Feb 16 2006, 13:08
Сообщение #9


Профессионал
*****

Группа: Свой
Сообщений: 1 301
Регистрация: 30-11-04
Из: Россия, Н.Новгород
Пользователь №: 1 264



Цитата(Vic1 @ Feb 16 2006, 15:49) *
Scopus -> BVU и zltigo уже ответили. А вообще то это все следует из понятия "дополнительный код"

Ответ на вопрос получен!
Во избежании дальнейшей сатирической критики и прочего, давайте считать эту тему ЗАКРЫТОЙ!
Кто из нас когда-то не начинал...

Сообщение отредактировал BVU - Feb 16 2006, 14:18


--------------------
Не корысти ради, не в целях наживы, а во исполнение велений души!
Go to the top of the page
 
+Quote Post
skopus
сообщение Feb 16 2006, 13:48
Сообщение #10


Участник
*

Группа: Свой
Сообщений: 65
Регистрация: 31-08-05
Из: Moscow
Пользователь №: 8 124



[quote name='zltigo' post='87847' date='Feb 16 2006, 15:56']
[quote name='prottoss' post='87840' date='Feb 16 2006, 14:46']
Х = abs(X)
[/quote]
Для данного случая, использование такого макроса (обычно) - не наглядно :-)
[/quote]

abs работает еще медленне
да и вообще сейчас компилер стал выдавать:

Error[Pe308]: more than one instance of overloaded function "abs" matches the argument list:
function "abs(double)"
function "abs(float)"
function "abs(long double)"
argument types are: (unsigned int __near)


[quote name='Vic1' post='87842' date='Feb 16 2006, 15:49']
smile.gifsmile.gifsmile.gifsmile.gifsmile.gif - бесконечно много раз

Извинения всем! Но второй раз такое увидеть (в течении всего лишь последних 2-х месяцев), откуда только этот код вспывает!

Scopus -> BVU и zltigo уже ответили. А вообще то это все следует из понятия "дополнительный код"
[/quote]


Уважаемый, я же вас не называю Vig1 или Vic0. Не надо каверкать мой ник


[quote name='defunct' date='Feb 16 2006, 15:53' post='87844']
[quote]int SignedToUnsigned(int sgnval)
{
if ((sgnval&0x8000)==0x8000) //[/quote]

А с чего Вы взяли, что int занимает 2 байта?!
писали бы хотя бы short..


а сколько же он по-вашему занимает? 10 ? может быть 4 ? smile.gif))

читайте мануал к компилятору
Go to the top of the page
 
+Quote Post
defunct
сообщение Feb 16 2006, 13:56
Сообщение #11


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата
а сколько же он по-вашему занимает? 10 ? может быть 4 ? smile.gif))

int - платформенно зависимый тип, он может занимать 1, 2, 4 байт и т.д., для получения оптимальной скорости на заданной аппаратной платформе. тип short - платформенно независимый 16-ти разрядный singed..

вашу функцию, с учетом примера zltigo можно описать так:

Код
short abs(short value)
{
  if( value < 0 )
    return ~value + 1;
  else
    return value;
}


если же разрядность чисел Вам не важна тогда для получения оптимальной скорости ставим вместо short - int.

Сообщение отредактировал defunct - Feb 16 2006, 13:59
Go to the top of the page
 
+Quote Post
skopus
сообщение Feb 16 2006, 14:03
Сообщение #12


Участник
*

Группа: Свой
Сообщений: 65
Регистрация: 31-08-05
Из: Moscow
Пользователь №: 8 124



Цитата(zltigo @ Feb 16 2006, 15:45) *
Цитата(skopus @ Feb 16 2006, 14:16) *

Я написал вот такую вот функцию, но она работает слишком медленно (132 цикла при отключенной оптимизации).

Я многое видел, но оказалось передела нет

if( value < 0 )
value = ~value + 1;


Спасибо. Все время забываю про оператор ~

Цитата(defunct @ Feb 16 2006, 16:56) *
Цитата
а сколько же он по-вашему занимает? 10 ? может быть 4 ? smile.gif))

int - платформено зависимый тип, он может занимать 1, 2, 4 байт и т.д., для получения оптимальной скорости на заданной аппаратной платформе. тип short - платформенно независимый 16-ти разрядный singed..

вашу функцию, с учетом примера zltigo можно описать так:

Код
short asb(short value)
{
  if( value < 0 )
    return ~value + 1;
  else
    return value;
}


если же разрядность чисел Вам не важна тогда для получения оптимальной скорости ставим вместо short - int.


Мы же в ветке AVR, правда? Не знаю как у вас. А у меня int - 2 байта.

Цитата из EWAVR Compiler Reference. страница 83

The compiler supports all ISO/ANSI C basic data types.
INTEGER TYPES
The following table gives the size and range of each integer data type:
Data type Size Range Alignment
signed char 8 bits -128 to 127 1
unsigned char 8 bits 0 to 255 1
short, int 16 bits -32768 to 32767 1

Signed variables are stored in two’s complement form.
Go to the top of the page
 
+Quote Post
KRS
сообщение Feb 16 2006, 14:08
Сообщение #13


Профессионал
*****

Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555



А почему просто унарный - нельзя использовать?

return (value<0) ? (-value) : value;
Go to the top of the page
 
+Quote Post
defunct
сообщение Feb 16 2006, 14:13
Сообщение #14


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(skopus @ Feb 16 2006, 16:03) *
Мы же в ветке AVR, правда? Не знаю как у вас. А у меня int - 2 байта.

Я же как раз и говорю о том что это платформено зависимый тип, в iar(ewavr) - int 2 байт, в avrgcc int - 2 байта, а в icc уже int - 1 байт (компиляторы под AVR). Захотите перенести вашу функцию на x86 там int либо 2 либо 4 байта, под arm - 4 байта.. Не проще ли сразу писать универсальную функцию, которую легко можно переносить на разные платформы. Плюс, претензию я предъявлял к конкретному коду:


Код
int SignedToUnsigned(int sgnval)
{
if ((sgnval&0x8000)==0x8000) //если старший бит =1, то число отрицательное, следовательно записано в дополнительном коде


Этот код и коментарий к нему теряет смысл и работоспособность в отрыве от конкретного компилятора/платформы. Компилятор вы не указали, так что зачем спорите?
Go to the top of the page
 
+Quote Post
Виктория
сообщение Feb 16 2006, 15:55
Сообщение #15


инженер
****

Группа: Свой
Сообщений: 520
Регистрация: 19-09-05
Из: Самара
Пользователь №: 8 701



Извините, skopus! Комичность ситуации привела к грамматическим ошибкам!

Цитата
Уважаемый, я же вас не называю Vig1 или Vic0. Не надо каверкать мой ник

Да, как душе угодно (Vik, Wik, Вик, ...). Лишь бы действительно с уважением и с учетом женского рода.
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 18th July 2025 - 07:02
Рейтинг@Mail.ru


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