Если вы выбрали C++ в качестве языка программирования, то учить его придётся всю жизнь. Смиритесь. Или выбирайте другой язык.
Чего только стоят новые стандарты, появляющиеся каждые 3 года. И каждый раз с какими-то полезными нововведениями в синтаксисе! Как им только это удаётся?
Есть разные способы совершенствоваться в С++. Кто-то читает Страуструпа от корки до корки, а потом почитывает стандарты. Кто-то ничего не читает и программирует по наитию - тупиковый путь, на мой взгляд.
Мне же нравится читать крупицы мудрости, бережно сформулированные для понимания простых смертных каким-нибудь гуру программирования.
Одна из моих любимых таких вещей - Guru of the Week (GotW) Херба Саттера.
Написано остроумно. И сколько пользы для программистки! Некоторые статьи уже морально устарели: кому нужен auto_ptr в наши дни? Но большинство ценно и сегодня.
Приведу здесь перевод выпуска №67 "Double or Nothing" от 29 февраля 2000 года. Моё любимое место — про тепловую смерть конечно
"Сложность 4/10
Нет. Этот выпуск не об азартных играх. Он, впрочем, о разных видах "float" так сказать, и даёт вам возможность проверить навыки касающиеся базовых операций над числами с плавающей точкой в C и C++.
1) В чём разница между "float" и "double"?
Вопрос Гуру
2) Допустим следующая программа выполняется за 1 секунду, что неудивительно для современного настольного компьютера:
int main() {
double x = 1e8;
while (x > 0) { --x; }
return 0;
}
Как долго по-вашему она будет выполняться, если заменить "double" на "float"? Почему?
Цитата из секции 3.9.1/8 стандарта C++:
Существует три типа чисел с плавающей точкой: float, double и long double. Тип double предоставляет по меньшей мере такую же точность как float, а тип long double — по меньшей мере такую же точность как double. Множество значений типа float является подмножеством множества значений типа double; множество значений типа double является подмножеством множества значений типа long double.
Она будет выполняться или примерно 1 секунду (в конкретных реализациях float'ы могут быть быстрее, такими же быстрыми или медленнее, чем double'ы) или бесконечно, в зависимости от того может или нет тип float представлять все целые числа от 0 до 1e8 включительно.
Цитата из стандарта выше означает, что могут существовать такие значения, которые могут быть представлены типом double, но не могут быть представлены типом float. В частности, на многих популярных платформах и во многих компиляторах double может точно представить все целые числа в диапазоне [0, 1e8], а float — не может.
Что если float не может точно представить все целые числа в диапазоне от 0 до 1e8? Тогда изменённая программа начнёт обратный отсчёт, но в конце концов достигнет значения N, которое не может быть представлено и для которого N-1==N (из-за недостаточной точности чисел с плавающей точкой) ... и тогда цикл застрянет на этом значении пока машина, на которой запущена программа не разрядится (из-за проблем в локальной энергосети или ограничений батареи), её операционная система не сломается (некоторые платформы более подвержены этому, чем другие), Солнце не превратится в переменную звезду и спалит внутренние планеты или вселенная не погибнет тепловой смертью — любое, что произойдёт раньше*.
Хорошо, давайте процитируем стандарт ещё раз, на этот раз секцию 4.8/1:
rvalue [выражение справа от знака "=" - прим. переводчицы] типа с плавающей точкой может быть преобразовано к rvalue другого типа с плавающей точкой. Если исходное значение может быть точно представлено целевым типом данных, результатом преобразования будет являться то точное представление. Если исходное значение лежит между двух последовательных значений целевого типа данных, результат преобразования определяется реализацией в качестве одного из этих двух значений. Иначе поведение не определено.
Это означает, что константа типа double может быть неявно (то есть молчаливо) преобразована в константу типа float, даже если это действие приводит к потере точности (то есть данных). Этому было позволено остаться как есть по причине совместимости с C и удобства использования. Но стоит держать это в уме, когда делаете работу с типами с плавающей точкой.
Качественный компилятор предупредит вас, если вы попытаетесь сделать что-то, поведение чего не определено. Например, присвоить значение типа double, которое меньше минимального или больше максимального значения, представимого типом float, к сущности типа float. По-настоящему хороший компилятор выдаст опциональное предупреждение, если вы попытаетесь сделать что-то, поведение чего может быть определено, но что влечёт потерю информации. Например, присвоить значение типа double, которое лежит между минимальным и максимальным значением типа float, но не может быть в точности представлено типом float, к сущности типа float.
** Конечно, выполнение любой дополнительной работы, людьми ли или машинами, также увеличивает энтропию вселенной, приближая тепловую смерть. Это хороший аргумент, который нужно иметь ввиду, когда работодатель требует переработок."
Чего только стоят новые стандарты, появляющиеся каждые 3 года. И каждый раз с какими-то полезными нововведениями в синтаксисе! Как им только это удаётся?
Есть разные способы совершенствоваться в С++. Кто-то читает Страуструпа от корки до корки, а потом почитывает стандарты. Кто-то ничего не читает и программирует по наитию - тупиковый путь, на мой взгляд.
Мне же нравится читать крупицы мудрости, бережно сформулированные для понимания простых смертных каким-нибудь гуру программирования.
Одна из моих любимых таких вещей - Guru of the Week (GotW) Херба Саттера.
Написано остроумно. И сколько пользы для программистки! Некоторые статьи уже морально устарели: кому нужен auto_ptr в наши дни? Но большинство ценно и сегодня.
Приведу здесь перевод выпуска №67 "Double or Nothing" от 29 февраля 2000 года. Моё любимое место — про тепловую смерть конечно
"Сложность 4/10
Нет. Этот выпуск не об азартных играх. Он, впрочем, о разных видах "float" так сказать, и даёт вам возможность проверить навыки касающиеся базовых операций над числами с плавающей точкой в C и C++.
Проблема
Вопрос Йуного Гуру (JG)1) В чём разница между "float" и "double"?
Вопрос Гуру
2) Допустим следующая программа выполняется за 1 секунду, что неудивительно для современного настольного компьютера:
int main() {
double x = 1e8;
while (x > 0) { --x; }
return 0;
}
Как долго по-вашему она будет выполняться, если заменить "double" на "float"? Почему?
Решение
1) В чём разница между "float" и "double"?Цитата из секции 3.9.1/8 стандарта C++:
Существует три типа чисел с плавающей точкой: float, double и long double. Тип double предоставляет по меньшей мере такую же точность как float, а тип long double — по меньшей мере такую же точность как double. Множество значений типа float является подмножеством множества значений типа double; множество значений типа double является подмножеством множества значений типа long double.
Колесо Времени
2) Как долго по вашему программа из вопроса 2 будет выполняться, если заменить "double" на "float"? Почему?Она будет выполняться или примерно 1 секунду (в конкретных реализациях float'ы могут быть быстрее, такими же быстрыми или медленнее, чем double'ы) или бесконечно, в зависимости от того может или нет тип float представлять все целые числа от 0 до 1e8 включительно.
Цитата из стандарта выше означает, что могут существовать такие значения, которые могут быть представлены типом double, но не могут быть представлены типом float. В частности, на многих популярных платформах и во многих компиляторах double может точно представить все целые числа в диапазоне [0, 1e8], а float — не может.
Что если float не может точно представить все целые числа в диапазоне от 0 до 1e8? Тогда изменённая программа начнёт обратный отсчёт, но в конце концов достигнет значения N, которое не может быть представлено и для которого N-1==N (из-за недостаточной точности чисел с плавающей точкой) ... и тогда цикл застрянет на этом значении пока машина, на которой запущена программа не разрядится (из-за проблем в локальной энергосети или ограничений батареи), её операционная система не сломается (некоторые платформы более подвержены этому, чем другие), Солнце не превратится в переменную звезду и спалит внутренние планеты или вселенная не погибнет тепловой смертью — любое, что произойдёт раньше*.
Слово о Сужающих Преобразованиях
Некоторые люди могут интересоваться: "Хорошо, кроме всеобщей тепловой смерти нет ли здесь другой проблемы? Константа 1e8 имеет тип double. Тогда если мы просто заменим "double" на "float", программа не скомпилируется по причине сужающего преобразования, верно?"Хорошо, давайте процитируем стандарт ещё раз, на этот раз секцию 4.8/1:
rvalue [выражение справа от знака "=" - прим. переводчицы] типа с плавающей точкой может быть преобразовано к rvalue другого типа с плавающей точкой. Если исходное значение может быть точно представлено целевым типом данных, результатом преобразования будет являться то точное представление. Если исходное значение лежит между двух последовательных значений целевого типа данных, результат преобразования определяется реализацией в качестве одного из этих двух значений. Иначе поведение не определено.
Это означает, что константа типа double может быть неявно (то есть молчаливо) преобразована в константу типа float, даже если это действие приводит к потере точности (то есть данных). Этому было позволено остаться как есть по причине совместимости с C и удобства использования. Но стоит держать это в уме, когда делаете работу с типами с плавающей точкой.
Качественный компилятор предупредит вас, если вы попытаетесь сделать что-то, поведение чего не определено. Например, присвоить значение типа double, которое меньше минимального или больше максимального значения, представимого типом float, к сущности типа float. По-настоящему хороший компилятор выдаст опциональное предупреждение, если вы попытаетесь сделать что-то, поведение чего может быть определено, но что влечёт потерю информации. Например, присвоить значение типа double, которое лежит между минимальным и максимальным значением типа float, но не может быть в точности представлено типом float, к сущности типа float.
Примечания
*Действительно, раз программа оставляет компьютер работать впустую, она также впустую увеличивает энтропию вселенной, таким образом приближая упомянутую тепловую смерть. Вкратце, такая программа довольно недружественна к окружающей среде и должна считаться угрозой для нашего биологического вида. Не пишите так код**.** Конечно, выполнение любой дополнительной работы, людьми ли или машинами, также увеличивает энтропию вселенной, приближая тепловую смерть. Это хороший аргумент, который нужно иметь ввиду, когда работодатель требует переработок."
Double or Nothing
Если вы выбрали C++ в качестве языка программирования, то учить его придётся всю жизнь. Смиритесь. Или выбирайте другой язык. Чего только стоят новые стандарты, появляющиеся каждые 3 года. И каждый...
habr.com