Форум программистов, компьютерный форум, киберфорум
C для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.64/25: Рейтинг темы: голосов - 25, средняя оценка - 4.64
6 / 6 / 4
Регистрация: 14.01.2016
Сообщений: 164

Изменить знаковость переменной

26.06.2020, 13:54. Показов 6290. Ответов 80
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте!
Существует ли возможность в языке Си изменять знаковость переменной? То есть, допустим нужно узнать является ли значение некоторой переменной отрицательным числом, как в следующем примере:

C
1
2
3
4
5
6
7
8
9
10
#include <stdio.h>
 
typedef char Some_type; // Данная строчка может находится в другом модуле и
                        // содержать описание произвольного типа.
Some_type some_var;
 
int main(void)
{
    return some_var < 0;
}
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
26.06.2020, 13:54
Ответы с готовыми решениями:

Изменить имя переменной в зависимости от данных переменной
Задача такова: пользователь вводит сроку и нужно создать объект с именем, как в строке. Пробовал сам, но одни ошибки. Подскажите,...

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

изменить значение переменной
Есть file.php, в нем есть переменная $kku = &quot;156666&quot;; Есть страница, smenap.php &lt;form action=\&quot;\form.php&quot;&gt; ...

80
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13212 / 6845 / 1825
Регистрация: 18.10.2014
Сообщений: 17,325
26.06.2020, 23:28
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от asbvic Посмотреть сообщение
Пока эту проблему я решил так:
Ну то есть UINT_MAX и UCHAR_MAX у вас называются "отрицательными" значениями. Это довольно странное использование терминологии.

Но то, что вы пока написали, фактически просто пытается определять значение знакового бита в знаковой версии типа. По функциональности и портабельности ваш вариант ничем не отличается от прямой проверки знакового бита, предложенной Mane, а во всех остальных отношениях ваш вариант хуже.

Почему тогда вы отвергли вариант от Mane?

Вы написали "сама проблема заключается именно в изменении знаковости". И как же ваш вариант помогает вам лучше "изменять знаковость" (и что вообще имеется в виду)?
0
6 / 6 / 4
Регистрация: 14.01.2016
Сообщений: 164
26.06.2020, 23:45  [ТС]
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Ну то есть UINT_MAX и UCHAR_MAX у вас называются "отрицательными" значениями. Это довольно странное использование терминологии.
Неважно как изначально рассматриваются эти переменные: знаковые или беззнаковые. В этом примере они именно беззнаковые изначально. Но в дальнейшем они могут рассматривать как знаковые. Т.е. UINT_MAX и UCHAR_MAX у меня не рассматриваются как "отрицательные", поэтому ничего странного нет.

Цитата Сообщение от TheCalligrapher Посмотреть сообщение
По функциональности и портабельности ваш вариант ничем не отличается от прямой проверки знакового бита, предложенной Mane
По функциональности и переносимости скорее всего не отличается, но отличается по производительности. Проверка в моем случае происходит более естественно, так как и должно происходить.

Цитата Сообщение от TheCalligrapher Посмотреть сообщение
а во всех остальных отношениях ваш вариант хуже
Если есть возможность, то все же опишите чем именно хуже.

Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Почему тогда вы отвергли вариант от Mane?
Я не отвергал, и даже поблагодарил. Но если честно, в его решении нет ничего сложного. Если бы мне нужно было именно это, то я бы об этом здесь не писал. Я же говорю, проблема не в этом. Это лишь часть проблемы. Нужно именно изменение знаковости типов переменных.

Цитата Сообщение от TheCalligrapher Посмотреть сообщение
И как же ваш вариант помогает вам лучше "изменять знаковость"
Дак ведь мой вариант именно это и делает. Разве нет? Вы его проанализировали? Проверили?
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13212 / 6845 / 1825
Регистрация: 18.10.2014
Сообщений: 17,325
26.06.2020, 23:55
Цитата Сообщение от asbvic Посмотреть сообщение
Т.е. UINT_MAX и UCHAR_MAX у меня не рассматриваются как "отрицательные", поэтому ничего странного нет.
Запускаем ваш пример кода, который анализирует переменные со значениями UINT_MAX и UCHAR_MAX. Получаем вывод

Code
1
2
unsigned_char is negative
unsigned_int is negative
Смотрим на вашу цитату выше. Недоуменно переглядываемся и пожимаем плечами.

Цитата Сообщение от asbvic Посмотреть сообщение
Дак ведь мой вариант именно это и делает. Разве нет? Вы его проанализировали? Проверили?
Несколько сообщений выше вы сказали

"Лично у меня эта проблема сегодня возникла из-за реализации переносимости кода. Когда некий тип, определенный с помощью typedef в стороннем модуле (не моем), в другой архитектуре может быть определен с другим размером (например сменится с unsigned int на unsigned long). А в моем коде идет арифметика с переменной этого типа, но именно как знаковой. Получается код непереносимый. И это только один из множества случаев где подобное возникает. Относительно часто это так же возникает когда задумываешься об оптимизации кода."

Каким боком в решении этого вопроса может помочь то, что вы написали, в частности преобразование беззнаковых значений к знаковым того же размера (с потерей значения!) - в упор не ясно. По-прежнему все выглядит как XY проблема: вы задаете вопросы о деталях реализации некоего "решения", в то время как само это "решение" - это никакое не "решение", а заблуждение, которое ничего не решает.
0
12 / 10 / 2
Регистрация: 15.12.2017
Сообщений: 70
27.06.2020, 00:18
TheCalligrapher, asbvic, я кажется понял, нужно узнать как проверить состояние старшего бита в любой переменной?
0
6 / 6 / 4
Регистрация: 14.01.2016
Сообщений: 164
27.06.2020, 00:33  [ТС]
Цитата Сообщение от apostata Посмотреть сообщение
TheCalligrapher, asbvic, я кажется понял, нужно узнать как проверить состояние старшего бита в любой переменной?

Нет. Нужно изменять знаковость типа переменных.

Добавлено через 3 минуты
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Смотрим на вашу цитату выше. Недоуменно переглядываемся и пожимаем плечами.
Дак результат программы говорит не об отрицательности каких-то констант, а о том что изменение знаковости произошло. Вы что? Совсем элементарного не понимаете.

Добавлено через 3 минуты
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
(с потерей значения!)
Не понял. Где какие значения теряются?

Добавлено через 1 минуту
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
само это "решение" - это никакое не "решение", а заблуждение, которое ничего не решает
В таком случае, вы можете предложить свое решение, которое не будет заблуждением?
0
12 / 10 / 2
Регистрация: 15.12.2017
Сообщений: 70
27.06.2020, 00:37
Слепой, с глухим.

asbvic, мне интересно вы это придумали, и решили, что так может быть. Или это решено на каком-то ином языке программирования как вам надо, но вы тут просто си изучаете и не знаете как это реализовать в данном стандарте.
Если так то приведите исходное решение.
0
6 / 6 / 4
Регистрация: 14.01.2016
Сообщений: 164
27.06.2020, 00:45  [ТС]
Цитата Сообщение от apostata Посмотреть сообщение
мне интересно вы это придумали, и решили, что так может быть
А вы вообще поняли про что идет речь? Только честно.

Цитата Сообщение от apostata Посмотреть сообщение
Или это решено на каком-то ином языке программирования
К примеру, все языки с нестрогой типизацией лишены этой проблемы.

Цитата Сообщение от apostata Посмотреть сообщение
вы тут просто си изучаете
Я уже не изучаю.

Цитата Сообщение от apostata Посмотреть сообщение
не знаете как это реализовать в данном стандарте
Ну а вы то знаете как это реализовать? Ведь вопрос то об этом в первую очередь.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13212 / 6845 / 1825
Регистрация: 18.10.2014
Сообщений: 17,325
27.06.2020, 00:49
Цитата Сообщение от asbvic Посмотреть сообщение
Не понял. Где какие значения теряются?
Значение UCHAR_MAX (положительное) при приведении к типу signed char становится отрицательным. Это - потеря значения.
0
12 / 10 / 2
Регистрация: 15.12.2017
Сообщений: 70
27.06.2020, 00:52
asbvic,
А вы вообще поняли про что идет речь? Только честно.
ну вас пока никто не понял.
Ну а вы то знаете как это реализовать? Ведь вопрос то об этом в первую очередь.
Естественно нет, потому что " расскажи, не скажу что", так себе тема для разговора
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13212 / 6845 / 1825
Регистрация: 18.10.2014
Сообщений: 17,325
27.06.2020, 00:55
Цитата Сообщение от asbvic Посмотреть сообщение
В таком случае, вы можете предложить свое решение, которое не будет заблуждением?
Еще раз более четко опишите задачу. Вы сказали, что к вас откуда то извне могут приходить значения беззнакового типа, с которым вы хотите безопасно выполнять некие потенциально знаковые арифметические действия.

Для того, чтобы более-менее безопасно обрабатывать беззнаковые значения в знаковом контексте, их надо сначала привести к следующему по ширине знаковому типу и выполнять вычисления в рамках этого знакового типа. То есть значения uint8_t должны быть преобразованы к int16_t, uint16_t к int32_t и т.д.

Это не стопроцентная гарантия безопасности, но это обязательный шаг в этом направлении.

Вот, что вам нужно, согласно вашему описанию задачи. Зачем вы в рамках этой задачи бросились проверять знак каких-то переменных... мне не ясно.
0
6 / 6 / 4
Регистрация: 14.01.2016
Сообщений: 164
27.06.2020, 01:20  [ТС]
Цитата Сообщение от apostata Посмотреть сообщение
Естественно нет, потому что " расскажи, не скажу что", так себе тема для разговора
"не скажу что"? Я уже вторую страницу форума рассказываю. И при чем очень стараюсь.

Добавлено через 11 минут
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Значение UCHAR_MAX (положительное) при приведении к типу signed char становится отрицательным. Это - потеря значения.
Если перевести данное значение обратно, то значение будет прежним. Т.е. никакой потери не происходит. Для меня вообще в этом случае ничего не происходит, я просто таким образом пытаюсь объяснит компилятору что мне именно нужно. Мне кажется вы просто как бы строго находитесь в рамках языка высокого уровня. Я же пытаюсь смотреть на эти вещи всесторонне (как я уже говорил, и со стороны машины тоже).
Иногда во время выполнения каких-либо арифметических действий в переменной не может быть отрицательное число. А по завершению этих действий, результат может быть отрицательным. Можно конечно изначально рассматривать эту переменную как отрицательную, но тогда вы лишаетесь половины ее диапазона во время вычислений. А потом при переносимости вам может потребоваться изменить ее размер. Как быть? Весь код переписывать?
Ну это почти все тоже самое что я выше писал.

Добавлено через 53 секунды
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Для того, чтобы более-менее безопасно обрабатывать беззнаковые значения в знаковом контексте, их надо сначала привести к следующему по ширине знаковому типу и выполнять вычисления в рамках этого знакового типа. То есть значения uint8_t должны быть преобразованы к int16_t, uint16_t к int32_t и т.д.
Вы уж извините, но это банальщина. )
0
12 / 10 / 2
Регистрация: 15.12.2017
Сообщений: 70
27.06.2020, 01:24
asbvic, есть задача (промежуточная), она возникает при достижение цели (основной задачи)
Цель ремонт фундамента.
Задача передвинуть дом на время ремонта.

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

А бывает цель передвинуть дом. Просто я так хочу. Цель ради цели.

Разницу видите? Так вот я так понимаю, у вас последний случай.
И если это не олимпиадная зада, выкиньте в мусорку это цель.
Теория относительноти, вам быстрее в жизни пригодится, чем применение этого решение на практике.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13212 / 6845 / 1825
Регистрация: 18.10.2014
Сообщений: 17,325
27.06.2020, 01:29
Цитата Сообщение от asbvic Посмотреть сообщение
Если перевести данное значение обратно, то значение будет прежним.
А откуда вообще взялась тема "приведения обратно"? И зачем вообще делать приведение туда сюда?

После приведения беззнакового значения к знаковому типу дает иной результат при сравнении с 0. Было больше нуля - стало меньше нуля. Это - потеря значения.

После приведения беззнакового значения к знаковому типу оно дает иной результат в операциях умножения. Это - потеря значения.

После приведения беззнакового значения к знаковому типу оно дает иной результат после integral promotions. Это - потеря значения.

Все это приводит к необратимым потерям правильности результата вычислений и поведения программы.

Когда в комнате доминируют такие слоны, мне не ясно, какую вообще роль может играть несчастная Моська "сохранения значения при приведении обратно".

Цитата Сообщение от asbvic Посмотреть сообщение
Иногда во время выполнения какой-либо арифметических действий в переменной не может быть отрицательное число. А по завершению этих действий, результат может быть отрицательным. Можно конечно изначально рассматривать эту переменную как отрицательную, но тогда вы лишаетесь половины ее диапазона во время вычислений.
Вот именно поэтому правильное решение - на время знаковых вычислений переходить к знаковому типу большей ширины. Именно так это всегда и делается.

Ваш же подход неработоспособен в принципе.
0
6 / 6 / 4
Регистрация: 14.01.2016
Сообщений: 164
27.06.2020, 01:31  [ТС]
apostata, спасибо за мнение.

Добавлено через 1 минуту
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Вот именно поэтому правильное решение - на время знаковых вычислений переходить к знаковому типу большей ширины. Именно так это всегда и делается.
А если шире уже некуда?
0
12 / 10 / 2
Регистрация: 15.12.2017
Сообщений: 70
27.06.2020, 01:32
asbvic,
как я уже говорил, и со стороны машины тоже
Иногда во время выполнения каких-либо арифметических действий в переменной не может быть отрицательное число. А по завершению этих действий, результат может быть отрицательным.
что ты такое несёшь?
вам в раздел assembler, там вам быстро разжуют, что может и думает о вас машина. Это если у вас х86, а если вы думаете как машины, а ваши данные это некие значения из вне (датчики), то где то тут есть ветка и для этого.
0
6 / 6 / 4
Регистрация: 14.01.2016
Сообщений: 164
27.06.2020, 01:32  [ТС]
TheCalligrapher, я думаю бессмысленно продолжать. Я вас услышал. Спасибо. Но для убедительности нужно выслушать еще ни одно мнение. )
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13212 / 6845 / 1825
Регистрация: 18.10.2014
Сообщений: 17,325
27.06.2020, 01:34
Цитата Сообщение от asbvic Посмотреть сообщение
А если шире уже некуда?
Если ваши знаковые вычисления не помещаются в диапазон intmax_t, то вам нужно либо

1. Реорганизовать вычисления, чтобы избежать промежуточного переполнения.

2. Если 1 - невозможно, то переходить к длинной арифметике.

Но это все, как вы говорите, банальщина.

Однако я в упор не вижу, как ваши манипуляции смогут здесь чем-то помочь.
0
6 / 6 / 4
Регистрация: 14.01.2016
Сообщений: 164
27.06.2020, 01:35  [ТС]
apostata, у меня создается впечатления что мы с вами с разных планет. ) Возможно мы просто не можем друг друга понять. Я не вижу смысла продолжать. Спасибо.
0
12 / 10 / 2
Регистрация: 15.12.2017
Сообщений: 70
27.06.2020, 01:44
asbvic, вы хотите в один и тот же адрес памяти, ложить одновременно большие положительно числа (больше диапазона знакомого числа), и отрицательные. А компилятор должен догадываться, что вы туда сунули и адекватно на это реагировать?
0
6 / 6 / 4
Регистрация: 14.01.2016
Сообщений: 164
27.06.2020, 19:08  [ТС]
apostata, нет, вы смотрите на данную проблему поферхностно, совсем не стараясь вникнуть. В итоге вы видите какие-то через чур банальные вещи, о которых я не стал бы здесь заводить речь.

Добавлено через 5 минут
apostata, TheCalligrapher, специально для вас придумал еще одну формулировку вопроса.

Вот вы же в своих программах используете операторы приведения типов? Дак вот то что мне нужно, это и есть примерно то же самое. Только мне нужно при приведении типа менять не весь тип (размер и знаковость), а только его знаковость (размер должен оставаться прежним). Вот так я надеюсь будет максимально понятно.

И если вдруг у вас все равно возникает вопрос: "А зачем тебе это надо?" (это отсылка к XY-проблеме), ответьте тогда на вопрос: зачем вы в своих программах используете операторы приведения типов?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
27.06.2020, 19:08

Изменить содержимое переменной
Есть переменяя fileWay - это пути к загруженным файлам на сервере разделенные символом &quot;;&quot; тегом перевода строки пример: ...

Изменить букву в переменной
Доброго всем здравия, программа выводит наиболее встречаемую букву в шифротексте, допустим -t-, это зашифрованная буква -e-, английского...

Изменить значение переменной
Помогите пожалуйста. Как сделать так чтобы значение переменной менялось. Переменная num это значение которое отвечает за количество статей...

Изменить значение переменной?
Вот есть у меня страничка index.php там есть вот такой код: PHP код: &lt;?php $file =...

Изменить значение переменной в функции
Возможно ли изменить значение переменной, передаваемой в функцию? Как-то так: void anyfunc(int a1) { //здесь прибавление на...


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

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
Саморегулирующийся социальный контракт для сервера cross-section.
Hrethgir 14.08.2026
С кодом конечно таких глубоких размышлений пока не было, впрочем я уже привык к алгоритмизации. Суть предмета записи: снова в диалоге с нейросетью (я взял пока себе ник для учётки админа - Rector). . . .
Часы электронные
Uhbif79 12.08.2026
Выкладываю программу часов. Программа позволяет: 1. Использовать системное время и дату, 2. Есть возможность вводить время и дату вручную. 3. Реализованы 2 будильника: начало и конец рабочего дня. . . .
Часы с будильником на основе класса QLCDNumber
Uhbif79 12.08.2026
Всем добрый день, выкладываю программу часов с будильником на основе класса QLCDNumber. Здесь я пробовал самостоятельно создавал классы, впервые столкнулся с видимостью переменной одного класса из. . .
Установка MinGW GCC 16.2 и CMake
8Observer8 10.08.2026
VK Видео: https:/ / vkvideo. ru/ video-240781534_456239017 YouTube: eY5-5PyI9NM Текстовая версия
Неделя из жизни имитационной модели склада: мои кривые руки растут, откуда надо
anaschu 10.08.2026
Неделя из жизни имитационной модели склада: как я почти написал неправильную логику и что с этим делать Работаю сейчас над учебно-рабочим проектом: строю в AnyLogic имитационную модель процессов. . .
Калькулятор для расчета родства
russiannick 07.08.2026
1. Задача: Создать калькулятор для расчета родства. Родственных связей существует 8 ступеней, такие как: p - отец P - мать q - муж Q - жена b - брат B - сестра s - сын S - дочь
Мир по моей воле
kumehtar 07.08.2026
Когда-то кажется, что всё просто. Ты весь такой светлый. Причиняешь добро. Борешься за справедливость в этом тёмном мире. Потом начинаешь замечать одну неприятную вещь. Почти каждый хороший. . .
Кредитный калькулятор
Maks 05.08.2026
Решение задачи по прикладной информатике средствами 1С. Задача: Напишите приложение-калькулятор, которое помогает рассчитывать параметры кредита для аннуитетного и дифференцированного видов. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru