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

 
 
> Type conversions в CodeVision, unsigned char->float
Gogan
сообщение Dec 28 2007, 13:21
Сообщение #1


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

Группа: Участник
Сообщений: 83
Регистрация: 25-10-07
Из: Киев
Пользователь №: 31 728



Есть вот такой проргамный код для АВР(например):

unsigned char a = 100;
float b = 20;

далее в программе

if( b < -a ){...}

так вот оказывается, в таком случаее условие выполняется.
Если кастовать вот так :

if( b < - (int) a ) {...}

тогда все ок. Объясните почему? Я не могу понять, что с чем сравнивается, если не кастовать, и почему так происходит?
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
ReAl
сообщение Dec 28 2007, 20:57
Сообщение #2


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(Gogan @ Dec 28 2007, 15:21) *
unsigned char a = 100;
float b = 20;

далее в программе

if( b < -a ){...}

так вот оказывается, в таком случаее условие выполняется.
Если кастовать вот так :

if( b < - (int) a ) {...}

тогда все ок. Объясните почему? Я не могу понять, что с чем сравнивается, если не кастовать, и почему так происходит?

На мой взгляд, компилятор не прав. Согласно стандарту С он должен оба эти if-а обрабаотывать одинаково и так, как второй. Есть такая штука, как integer promotion rules (integer promotions), согласно им любой целочисленный тип, который меньше int-а, должен приводиться к int перед вычислением выражений. Даже для
Код
char a,b,c;
a = b + c;
- привести к int, сложить, результат усечь и присвоить a.
Это требования к "абстрактной машине", дальше можно дать свободу и не делать приведение к int, но только в случае, если от такого неделания результат не изменится.
В данном случае -a это уже подвыражение с унарным минусом, перед его вычислением компилятору надо было привести a к int (что во втором примере сделано вручную), потом применить минус, потом, согласно правилам автоматических преобразований типов, результат привести к float и сравнить.
Так что тут компилятор не имел права делать -a в пределах байта.

Цитата(Gogan @ Dec 28 2007, 20:33) *
eeprom unsigned char edata[20][8]={{90,0,...},{}...};
unsigned int a;

далее в тексте
a=edata[0][0]+edata[0][1]<<8;

т.е. интегер хранится в двух первых байтах, сначала младший потом старший. Компилер выдал, что edata[0][1]<<8 получится в любом случае 0. Я переписал
a=(int)edata[0][0]+edata[0][1]<<8;

опять неправильно. Компилер не ругался, но результат был 90х256=23040. Правильным вариантом оказалось:
a=edata[0][0]+(int)edata[0][1]<<8;

Выбрось каку!!!
Правильный компилятор (соответствующий стандарту) во всех трёх приведённых тобой вариантах должен был дать одинаковый результат, впрочем, не тот, который ты ожидаешь smile.gif
Приведение к int делать вообще не нужно, оно должно было быть сделано согласно integer promotions самим компилятором.
А вот дальше - у оператора сложения приоритет выше, чем у операции сдвига (с моей точки зрения, приоритет сдвигов должен бы быть между приоритетами *% и +-, но K&R когда-то решили иначе и стандарт есть стандарт), поэтому
a + b << 8;
должно вычисляться всегда как
( a + b ) << 8;

А то, что хотелось сделать, следует записывать как
a + ( b << 8 );


p.s. Не понимаю, как можно пользоваться компилятором, настолько не соответствующим стандарту...
Или он позиционируется как "компилятор С-подобного языка программирования" ???


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- Gogan   Type conversions в CodeVision   Dec 28 2007, 13:21
- - Kuzmi4   2 Gogan - последний вариант - как бы правильней - ...   Dec 28 2007, 13:25
- - sergik_vrn   Цитата(Gogan @ Dec 28 2007, 16:21) Есть в...   Dec 28 2007, 14:33
|- - defunct   Цитата(sergik_vrn @ Dec 28 2007, 17:33) т...   Dec 28 2007, 15:15
|- - sergik_vrn   Цитата(defunct @ Dec 28 2007, 18:15) Логи...   Dec 29 2007, 06:54
- - Gogan   Огромное спасибо за ответы! Теперь уяснил. Сег...   Dec 28 2007, 18:33
|- - Gogan   Цитата(ReAl @ Dec 28 2007, 22:57) А то, ч...   Dec 29 2007, 06:25
|- - Палыч   Цитата(ReAl @ Dec 28 2007, 23:57) Приведе...   Dec 29 2007, 08:38
|- - ReAl   Цитата(Палыч @ Dec 29 2007, 10:38) ISO989...   Dec 29 2007, 09:15
- - WHALE   Выбрось каку!!! Обьясните тупому,плиз...   Dec 29 2007, 06:25
- - Qwertty   Имхо правильный вариант: eeprom unsigned int edata...   Dec 29 2007, 06:47
- - WHALE   Дык я про это и пишу.В вашем примере это несомненн...   Dec 29 2007, 07:15
|- - sergik_vrn   Цитата(WHALE @ Dec 29 2007, 10:15) [..] а...   Dec 29 2007, 08:21
- - WHALE   То есть если у меня сложная составная операция с д...   Dec 29 2007, 08:29
- - sergik_vrn   Цитата(WHALE @ Dec 29 2007, 11:29) То ест...   Dec 29 2007, 08:39


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

 


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


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