Форум программистов
 
Контакты: о проблемах с регистрацией, почтой и по другим вопросам пишите сюда - alarforum@yandex.ru, проверяйте папку спам! Обязательно пройдите активизацию e-mail.

Вернуться   Форум программистов > Инженерный раздел > Микроконтроллеры, робототехника, схемотехника, 3D принтеры
Регистрация

Восстановить пароль
Повторная активизация e-mail

Ответ
 
Опции темы
Старый 16.04.2018, 14:39   #1
avd
Форумчанин
 
Регистрация: 06.06.2010
Сообщений: 79
Репутация: 21
По умолчанию Сравнение знаковых и беззнаковых значений

Здравствуйте.
IDE Atmel Studio 7.
Я понимаю, что лучше не сравнивать знаковые и беззнаковые значения.
Но всё же ...

Код:

  volatile int8_t a; 
  volatile uint8_t b;	
	
  a = 5; b = 7;
	
  if ((a - b) > 1)
  {
    .....
  }

Если переменные однобайтные - условие не выполняется.
Если двухбайтные (int16_t и uint16_t) - выполняется.

Боюсь заработаю гексакосиойгексеконтагексафобию.

Последний раз редактировалось avd; 16.04.2018 в 16:19.
avd вне форума   Ответить с цитированием
Старый 16.04.2018, 17:41   #2
Alter
Профессионал
 
Аватар для Alter
 
Регистрация: 06.08.2007
Адрес: Пустота
Сообщений: 2,210
Репутация: 982
По умолчанию

createlink.gif Вот тут написано почему так не надо
Цитата:
ПРАВИЛО #8 – Целые числа со знаком и без
Целые числа со знаком не должны сочетаться с целыми числами без знаков в сравнениях или выражениях. Десятичные константы, не подразумевающие наличие знаков, должны быть описаны с 'u' на конце.

Код:

// Так делать нельзя...
uint8_t  a = 6u;
int8_t   b = -9;

if (a + b < 4)
{
   // если бы -9 + 6 было -3 < 4 как ожидалось.
   // была бы выполнена эта ветвь
}
else
{
   //но поскольку -9 + 6 это  (0x100 - 9) + 6 = 253
   //то будет выполнена эта ветвь
}

Аргументация: Некоторые детали управления целочисленными данными со знаком зависят от реализации (то есть от от конкретного компилятора). Кроме того, в результате смешивания знаковых и беззнаковых данных могут возникать информационно-зависимые ошибки.
__________________
DelphiWorld 6, АVL 2.0.1.3

Последний раз редактировалось Alter; 16.04.2018 в 18:23.
Alter вне форума   Ответить с цитированием
Старый 16.04.2018, 17:56   #3
avd
Форумчанин
 
Регистрация: 06.06.2010
Сообщений: 79
Репутация: 21
По умолчанию

Alter, спасибо.
Но почему программа выполняется по разному с однобайтными и двухбайтными числами?
avd вне форума   Ответить с цитированием
Старый 16.04.2018, 18:04   #4
Аватар
Модератор
Заслуженный модератор
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Адрес: Северодонецк.ua
Сообщений: 17,349
Репутация: 6038
По умолчанию

Если результат вычитания трактуется как беззнаковый, то больше 1, если знаковый то меньше. И как там еще компилятор с единицей сравнивает. Это у разрабов компилятора нужно спрашивать ))
__________________
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар на форуме   Ответить с цитированием
Старый 16.04.2018, 19:12   #5
Alter
Профессионал
 
Аватар для Alter
 
Регистрация: 06.08.2007
Адрес: Пустота
Сообщений: 2,210
Репутация: 982
По умолчанию

Возможно это:
Сравнение знаковых и беззнаковых чисел - C++
Цитата:
16.12.2011, 22:22 #2
Ну, здесь производится арифметическое преобразование типов, согласно которому операнд "меньшего" типа приводится к типу операнда "большего" типа. В иерархии типов "большим" считается тот тип, который может представить большее положительное значение.
О размерности данных в программах для микроконтроллеров

Типы описаны в stdint.h
Например: C:\Program Files\Arduino\hardware\tools\avr\av r\include\stdint.h

Нескольно простых вопросов о программировании AVR на Си.
Цитата:
ptr128 Сб дек 24, 2016 19:39:08
С точки зрения подавляющего большинства CPU (предположу даже, что всех современных) и AVR в том числе, целые числа в памяти вообще не разделяются на знаковые или беззнаковые. С точки зрения CPU и uint8_t и int8_t - одно и тоже. Просто байт. Восемь бит.
Однако для работы со знаковыми и безнаковыми числами существуют различные машинные команды. Беззнаковые команды оперируют целиком с 8 битами. А вот знаковые анализируют самый старший бит. Если этот бит нулевой - число не отрицательное (положительное или ноль). Еcли единица - то отрицательное. Причем отрицательное в дополнительном коде.
То есть, значения от 0 до 127 будут считаться знаковой командой положительными. А вот уже беззнаковое 128 будет считаться знаковым -128. Беззнаковое 255 будет считаться знаковой -1.
Иными словами сравнивая два байта, содержащие значения 200 и 100, как беззнаковые числа, Вы получите, что первое больше второго. Сравнивая эти же два байта, как знаковые числа, результат будет противоположным - первое меньше второго.
Чуть не забыл. Сравнить знаковое число с беззнаковым у Вас вообще не получится по той простой причине, что если в выражении компилятор встречает знаковое и беззнаковое число, то знаковое будет преобразовано в беззнаковое. То есть сравнение знакового числа с беззнаковым всегда эквивалентно сравнению беззнаковых чисел.
_
Вот эксперимент на ARDUINO 1.8.5, Arduino Nano 3.0 (ATmega328):
Код:

void setup() {

  Serial.begin(9600);
///////////////////////////////////
  Serial.println("volatile int8_t a; volatile uint8_t b;");
  volatile int8_t a; 
  volatile uint8_t b; 
  volatile uint8_t cuint8t; 
  volatile int8_t cint8t;   

  a = 5; b = 7;

  Serial.print("SizeOf(a) = "); Serial.print(sizeof(a)); Serial.print("; a="); Serial.print(a); Serial.println(";");
  Serial.print("SizeOf(b) = "); Serial.print(sizeof(b)); Serial.print("; b="); Serial.print(b); Serial.println(";"); 
   cuint8t = a - b;
   cint8t  = a - b;
  Serial.print("volatile uint8_t cuint8t: a - b = "); Serial.println(cuint8t);
  Serial.print("volatile int8_t cint8t: a - b = "); Serial.println(cint8t);
  Serial.println(" ");
  Serial.print("a - b = "); Serial.println(a - b);
  
  if ((a - b) > 1)
  {
    Serial.println("Result: (a - b) > 1");
  }
   else
  {
    Serial.println("Result: (a - b) < 1");
  }
  Serial.println("_________________________________________________________");
  Serial.println(" ");
///////////////////////////////////
  Serial.println("volatile int16_t a2; volatile uint16_t b2;");
  volatile int16_t a2; 
  volatile uint16_t b2; 
  volatile uint16_t c2uint16t; 
  volatile int16_t c2int16t;  

  a2 = 5; b2 = 7;

  Serial.print("SizeOf(a2) = "); Serial.print(sizeof(a2)); Serial.print("; a2="); Serial.print(a2); Serial.println(";");
  Serial.print("SizeOf(b2) = "); Serial.print(sizeof(b2)); Serial.print("; b2="); Serial.print(b2); Serial.println(";"); 
   c2uint16t = a2 - b2;
   c2int16t  = a2 - b2;
  Serial.print("volatile uint16_t c2uint16t: a2 - b2 = "); Serial.println(c2uint16t);
  Serial.print("volatile int16_t c2int16t: a2 - b2 = "); Serial.println(c2int16t);
  Serial.println(" ");
  Serial.print("a2 - b2 = "); Serial.println(a2 - b2);
  
  if ((a2 - b2) > 1)
  {
    Serial.println("Result: (a2 - b2) > 1");
  }
   else
  {
    Serial.println("Result: (a2 - b2) < 1");
  }
  Serial.println(" ");
  Serial.println(" ");  
///////////////////////////////////  
}

void loop() {

}

Результат:
Цитата:
volatile int8_t a; volatile uint8_t b;
SizeOf(a) = 1; a=5;
SizeOf(b) = 1; b=7;
volatile uint8_t cuint8t: a - b = 254
volatile int8_t cint8t: a - b = -2

a - b = -2
Result: (a - b) < 1
___________________________________ ______________________

volatile int16_t a2; volatile uint16_t b2;
SizeOf(a2) = 2; a2=5;
SizeOf(b2) = 2; b2=7;
volatile uint16_t c2uint16t: a2 - b2 = 65534
volatile int16_t c2int16t: a2 - b2 = -2

a2 - b2 = 65534
Result: (a2 - b2) > 1
__________________
DelphiWorld 6, АVL 2.0.1.3

Последний раз редактировалось Alter; 16.04.2018 в 20:38.
Alter вне форума   Ответить с цитированием
Старый 16.04.2018, 21:09   #6
avd
Форумчанин
 
Регистрация: 06.06.2010
Сообщений: 79
Репутация: 21
По умолчанию

Благодарю.
Торжественно обещаю больше не сравнивать знаковые и беззнаковые величины.
avd вне форума   Ответить с цитированием
Ответ

Опции темы

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Сравнение знаковых чисел Herly Assembler 5 12.06.2013 00:31
Сравнение значений vajtek Общие вопросы Delphi 2 23.08.2011 19:53
Сравнение значений в 2х столбцах и удаление лишних значений.. Tyr Microsoft Office Excel 2 16.12.2010 19:19
вычисление для знаковых и беззнаковых целых чисел!!!! senna_ololo Assembler 1 07.06.2010 23:38
Вычисление для знаковых и без знаковых целых чисел в asm. kup9 Assembler 2 06.06.2010 18:21


21:35.


Powered by vBulletin® Version 3.8.8 Beta 2
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.

RusProfile.ru


Справочник российских юридических лиц и организаций.
Проекты отопления, пеллетные котлы, бойлеры, радиаторы
интернет магазин respective.ru