Vaclav_ Ответов: 2

Очень простой, древний вопрос C об автоматическом преобразовании типов


Прилагаемый фрагмент кода C работает только так, как указано

scale = 1/2;          does not work
        scale =(float)  1/2; works
        glScalef(scale, scale, scale);


Переменная "шкала" имеет тип float, то есть
glScalef(scale, scale, scale);

Функция OpenGL ожидает поплавков. Когда это не удается , приложение запускается, но OpenGL просто игнорирует
glScalef(scale, scale, scale);
функция.

Не слишком ли это простой случай для С
Automatic Type Conversion
делать свою работу?

Вот о чем я спрашиваю.

Меня не волнует, что определение
scale = 1/2;   does not work 


Что я уже пробовал:

Спросила миссис Гугл о чем
Automatic Type Conversion
, не нужно больше никаких ссылок RTFM.

Richard MacCutchan

"не нужно больше ссылок RTFM."
О да, вы знаете; как насчет того, чтобы начать со спецификации языка Си?

2 Ответов

Рейтинг:
0

Richard Deeming

Без актерского состава, буквального 1 является целым числом, как и литерал 2 Следовательно, вы выполняете целочисленное деление и 1 / 2 == 0.

Целое число 0 затем преобразуется в a float и хранится в вашей переменной.

Вам нужно либо привести числитель, либо знаменатель к float до выполнение деления или использование литерала 0.5 вместо.


Рейтинг:
0

KarstenK

действительно древний, но простой для понимания.

"1 / 2" понимает компилятор как "деление целого числа 1 на целое число 2". Результат-0.

"(float) 1/2" понимает компилятор как "разделить float 1 на 2 как поплавок Так что получается 0,5.

Попробуйте обе версии с 3/2. Вы можете прочитать об Оператор модуля Это также отличный учебник по C++.


k5054

Цитата:"(float) 1/2" понимает компилятор как "разделить float 1 на 2 как float ". Так что получается 0,5.

Более подробно

(float)1/2
эквивалентно
(float)1/(int)2
То, что компилятор делает здесь, - это преобразование (int)2 к (float)2 затем выполняется деление.
Однако в наши дни компилятор, вероятно, преобразует и то, и другое (float)1 и (int)2 к double, выполняет деление, а затем выполняет еще одно преобразование из double к float.

В общем, я думаю, что рекомендация состоит в том, чтобы использовать double для значений с плавающей запятой, если у вас нет ограничений памяти или есть некоторые проблемы в вашей проблемной области, которые делают float хорошее соответствие. На самом деле, в современном C/C++ литерал с плавающей запятой, такой как 2.71 это double, если только к нему не прилагается суффикс f или F для float или l или L для long double

Rick York

Действительно ли какой-либо компилятор поддерживает long double? Я знаю, что Visual Studio этого не делает. Он присваивает им псевдонимы в виде простого двойника, а sizeof возвращает 8.

k5054

gcc под linux и clang FreeBSD оба сообщают о длинном двойнике с размером как 12. Интересно, что говорит Мингв.

Обновление: это было для 32 - битных исполняемых файлов. gcc для 64 битных отчетов sizeof long double as 16

Обновление 2: MinGW-64 также сообщает о длинном двойнике как 16 байт.

Обновление 3: Обсуждение длинных двойников MSVC и MinGW здесь: MinGW-w64 - для 32 и 64 битных Windows / ошибки / #675 разница между способом vc++ и gcc преобразует ascii в длинный двойной, gcc неправильно[^

Vaclav_

Если я правильно читаю Реальные ответы - тип шкалы не имеет никакого отношения к автоматическому преобразованию типа, когда масштаб = 1/2; я полагаю, что пример автоматического преобразования типа принесет еще один RTFM - "ответ". Дело закрыто.