| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Для новичков > float или double ? |
| Автор: hoz 13.7.2013, 20:48 |
| В С++ имеется тип переменных как float так и double. Переменные типа double могут хранить значения на много больше ежели переменные типа float, и с большей точностью. Возник вопрос. Зачем тогда нужен тип float вообще? |
| Автор: volatile 13.7.2013, 22:37 |
Места в 2 раза меньше занимает. |
| Автор: hoz 13.7.2013, 22:44 |
А где об этом говорится? вообще. До какого значения можно использовать float ? |
| Автор: volatile 13.7.2013, 23:25 | ||||
ну само имя double - что-то да значит (смотрите перевод, если что... Ну и в реале, так оно и есть почти везде.
в стандарте об этом ничего конктретного, как всегда не говорицца... Так что смотреть стандарт - терять время. Нужно смотреть доку компилятора или чтоб не морочить долго голову, просто написать небольшую программку, и все сразу станет ясно.
http://codepad.org/byh5i3L2 Добавлено через 4 минуты и 19 секунд В студии, кстати, точно также. |
| Автор: hoz 13.7.2013, 23:52 |
| Cheloveck, так там написано же что мол каждый последующий из типов float - double - long double хранит значение переменных большей величины. Множество значений float является подмножеством значений double, и множество значений double является подмножеством значений long double. floatiing-point определяемые-реализацией... Это что за такое? Integral и floating-типы называются более верно арифметическими типами. Согласно специализации классов std::numeric_-limits 18.2 определены максимальные и минимальные значения каждого арифметического типа согласно их применения. Перешёл я в ту спецификацию 18.2 и не нашёл там рамок для соответствующих типов данных. Поясните, пожалуйста, как это правильно искать там? |
| Автор: volatile 14.7.2013, 00:08 |
| hoz, мою програку смотрели на codepad.org, там показано как использовать numeric_limits Сам стандарт, как я уже говорил, никаких границ не дает. Все зависит от реализации компилятора. |
| Автор: mes 14.7.2013, 00:09 |
грубо означает что нужно смотреть не в стандарт языка, а в стандарт который выбрала реализация, например сюда : http://ru.wikipedia.org/wiki/IEEE_754-2008 |
| Автор: volatile 14.7.2013, 00:21 |
Стрго говоря, (раз уж здесь все так офигенно стрго, как я погляжу). Нужно сначала выяснить в той же доке компилятора, что он использует именно IEEE_754-2008 в качестве реализации плавющих типов. Что вовсе не обязательно. А уже потом, при положительном ответе, можно и смотреть туда, куда вы указали. только сколько это все займет время у новичка интересно... |
| Автор: mes 14.7.2013, 00:33 |
да, правда что ли ? но простите, а я что написал ?? или опять упреки в софистике посыплятся ? |
| Автор: hoz 14.7.2013, 00:37 | ||||
Хм. Я пока что Ваш код не совсем понял, хотя с большего, конечно, логика проста. Но С++ изучаю пока что с нуля (после примитивного mql4), так что сложновато на данном этапе. Вот, есть момент.
Переменная size указывает на количество символов в значении, верно? А range, как видно диапазон. Тока вот что значит запись 1.17549e-38 не понимаю.. |
| Автор: mes 14.7.2013, 00:37 |
как это соотносится с вопросом на который и был ответ ? или Вы предлагаете кому то другому посмотреть доку компилятора новичка и определить нужный стандарт ? не пойму только кому... Добавлено через 4 минуты и 4 секунды https://ru.wikipedia.org/wiki/%D0%AD%D0%BA%D1%81%D0%BF%D0%BE%D0%BD%D0%B5%D0%BD%D1%86%D0%B8%D0%B0%D0%BB%D1%8C%D0%BD%D0%B0%D1%8F_%D0%B7%D0%B0%D0%BF%D0%B8%D1%81%D1%8C |
| Автор: hoz 14.7.2013, 00:48 | ||
Не предлагаю, я писал тот пост до того как volatile ответил. Но меня реально грузит всё это. Такое ощущение, что там всё спецом так запудрили. Лезть в доку компилятора я и не собирался. Раньше я даже не знал, что придётся... |
| Автор: mes 14.7.2013, 01:01 |
hoz, Добавлено через 2 минуты и 10 секунд да потому что в принципе в первую очередь операции с плаваюшей запятой зависят от процессора, а не языка.. |
| Автор: hoz 14.7.2013, 01:12 | ||
Так странно. Если:
Получается, что sizeof возвращает размер его операнда, а range согласно коду диапазоны макс. и мин. Но size=4, а у range размеры огромных пределах, я даже не представляю себе эти числа. Но там далеко не 4... (для float). Как это понимать? |
| Автор: volatile 14.7.2013, 01:14 |
--- Ребята хорош грузить новичка. Вы конечно все очень правы, особенно длинная цитата из стандарта Это напомнило мне старый анедот. Как-то летели Холмс с Ватсоном на воздушном шаре. И заснули. Просыпаются над какой-то незнакомой местностью, видят - внизу какой-то мужик коров пасет. Снизились они и спрашивают мужика: - Скажите, сэр, где мы находимся? - (хорошенько подумав) На воздушном шаре. - Спасибо, сэр! - и поднялись вверх. Холмс задумчиво говорит: - Интересная местность, Ватсон! Программист пасет коров! - Но, Холмс, с чего вы взяли, что он программист? - Элементарно, Ватсон! Во-первых, он ответил, хорошенько подумав. Во-вторых, его ответ - Абсолютно точен. Ну и в третьих - Абсолютно бесполезен! |
| Автор: mes 14.7.2013, 01:20 |
почитать про https://ru.wikipedia.org/wiki/%D0%A7%D0%B8%D1%81%D0%BB%D0%BE_%D1%81_%D0%BF%D0%BB%D0%B0%D0%B2%D0%B0%D1%8E%D1%89%D0%B5%D0%B9_%D0%B7%D0%B0%D0%BF%D1%8F%D1%82%D0%BE%D0%B9 |
| Автор: borisbn 14.7.2013, 05:48 |
| > Получается, что sizeof возвращает размер его операнда, а range согласно коду диапазоны макс. и мин. Но size=4, а у range размеры огромных пределах ИМХО для начала нужно разобраться хотя бы с целыми числами. Там такая же фигня. При size равном 1 байт range от 0 до 255. И ещё, смысл double не в хранении больших чисел, а в большой точности при хранении чисел. Кстати, на некоторых процессорах double вообще нет. Есть только float. Например, на некоторых GPU. |
| Автор: mes 14.7.2013, 11:27 |
имелось в виду "в большей" ? |
| Автор: borisbn 15.7.2013, 08:36 |
| > имелось в виду "в большей" ? Ну... Я там обыгрывал "большие числа" vs "большая точность", но и так можно |
| Автор: Wuffur 15.7.2013, 09:20 |
| 1.17549*10^-38=1,9999 9259*2^-127=1, 1111 1111 1111 1111 1000 011*2^-127. Причем старшая 1 в мантиссу не пишется. Так? |
| Автор: Alexeis 15.7.2013, 09:22 |
| Я думаю, что флоаты в первую очередь нужны для скорости. Одно дело вычислять ~7 знаков акртангенса для флоата, и совсем другое 14 знаков для дабла. Оно конечно зависит от реализации в процах, но по опыту даблы будут раз в 10 дольше вычисляться если не хуже. Поэтому графику считают флоатами, тем более что флоаты лучше оптимизируются SSE . Я бы сказал, что скорее даблы не нужны чем флоаты, но они безусловно нужны для научных вычислений где требуется сохранение точности. |
| Автор: Wuffur 15.7.2013, 09:38 |
| Зависит от задачи - когда для скорости, а когда, чтобы вместились в память. Если вы CUDA программист, то там производительность сравнима, здесь: http://www.nvidia.com/object/tesla-servers.html пиковая производительность на кеплере. А здесь просто про floating point на CUDA^ https://developer.nvidia.com/sites/default/files/akamai/cuda/files/NVIDIA-CUDA-Floating-Point.pdf K20 Peak double precision floating point performance 1.17 Tflops Peak single precision floating point performance 3.52 Tflops PU Computing Applications Reservoir simulation, CAE (structural analysis), Molecular dynamics, Numerical analytics, Computational visualization (ray tracing) Вполне возможно, что если вам нужно отрисовывать сложную сцену, то без double не обойдешься. |
| Автор: akizelokro 15.7.2013, 10:11 | ||
| Вопрос исторический и поэтому немного риторический. Надо смотреть, как появлялись float и double. Смотреть аллюзии с fortran'ом, потому что первоначально он в основном использовался для научных расчётов, a C рассматривался как системный язык (точность нецелочисленных вычислений в fortran'е была побольше. PS. Как сейчас, не знаю.) А дальше уже идут вопросы переносимости кода. Стандарт языка, кажется, на то и стандарт языка, чтобы в нём не рассматривалась трендовая текущая ситуация с hardware и software, а важна универсальность. Даже до сих пор есть DJGPP, который компилит код под 386 процессором и, пусть и единичные, но у людей возникают задачи что-то написать и откомпилить, работающее даже на 286 процах. Не говоря про многообразие UNIX'оидных тачек. Добавлено через 8 минут
В большом ряде научных расчётов такая точность может оказаться недостаточной. Так что не грузите новичка, а расскажите ему так, как оно есть на самом деле. "Как к такой жизни пришли" и почему оно до сих пор так, а не по другому. |
| Автор: Wuffur 15.7.2013, 11:43 |
| akizelokro, А вот если я ему скажу, что на два это число делить можно, а на большее целое будет ноль - это будет ответ на вопрос? Может он сам додумает? С вашим ответом, что в DJGPP всё устроено как в 286 и 386 вряд ли понятнее станет. Я вот знаю, что сопроцессор для вычислений с плавающей точкой появился только на 386 DX-2 и там ни о каких double речи не шло. Просто Doom 2 быстрее стал идти. |
| Автор: hoz 15.7.2013, 13:56 | ||||||
| Мда. Пользуюсь уже год как числами с запятой, а ничего про них не знал до этого момента В принципе, вы было сказано верно, double больше float по сайзу в байтах в 2 раза, но long double относительно double уже не в 2.. хотя значения его в диапазоне на порядок больше предшественника, как в нормализованном виде, так и в денормализованном виде. Есть пару моментов. 1. Ведь переменная у которой мантисса с порядком имеет значение 1,2·10−38 или 1,2·10−38 это уже 38 запятых в ту или иную сторону. Зачем больше? Как программист прикидывает всё-таки необходимость использования того или иного типа? Лично я не представляю, где можно использовать такие числа... с такой точностью. А выше и подавно. Очень интересно понять. 2. https://ru.wikipedia.org/wiki/%D0%A7%D0%B8%D1%81%D0%BB%D0%BE_%D1%81_%D0%BF%D0%BB%D0%B0%D0%B2%D0%B0%D1%8E%D1%89%D0%B5%D0%B9_%D0%B7%D0%B0%D0%BF%D1%8F%D1%82%D0%BE%D0%B9 сказано, что:
Это как понять? 3. Ещё там есть такое:
Разве может быть мантисса отрицательной? Ведь, если так, то вид:
Будет правильным? |
| Автор: feodorv 15.7.2013, 14:42 |
Нет))) Это значит, что порядок числа может быть от -38 до +38, но вот число значащих цифр - всего 7-8 (у double - 15-16). А точнее? Может: -1.0... Нет. -0,1·e3 |
| Автор: hoz 15.7.2013, 15:17 | ||||
Хм. Я так понял, Вы из той таблицы взяли? Для long double согласно той таблицы будет от 19-20 знаков.. Выходит, что нас интересует именно точность! Теперь понял. Я уже исправил в своём посте, вот что я имел ввиду:
Читал, читал.. но не очень понятно, что они имеют ввиду под терминами фиксированной и относительной точности. Хотя да. Верно. |
| Автор: feodorv 15.7.2013, 16:34 | ||||
Нет, это довольно известные факты))) Да! Можете http://www.cyberforum.ru/cpp-beginners/thread693674.html на строение float Ну вот всё тоже самое))) Число бит под мантиссу фиксировано, значит, Вы можете, к примеру, различать числа x=1.0eN и y=1.000001eN (где N - какой-то порядок); а 1.0eN и 1.0000001eN уже не различаются (не хватает разрядности мантиссы и 0.0000001 отбрасывается). Поэтому (максимально достижимая) относительная точность
не зависит от порядка числа и зависит только от разрядности мантиссы. В то же абсолютная точность
просто совпадает с x*1e-6 и изменяется вместе с x (и его порядком). |
| Автор: hoz 16.7.2013, 20:42 | ||
Ничего там непонятно вообще, если честно. Думал что всё понятно, а как начал там читать, так затуманило. Наверное лучше оставить "как есть", ведь различия в применении типов переменных я выяснил, а дальше уже дебри.. Который пугают
Во втором варианте, Вы имеете в виду, что там N-не порядок мантиссы, а множитель что-ли? |
| Автор: bsa 16.7.2013, 21:07 |
А чего непонятного? Число с плавающей точкой состоит из 3-х частей: знак (-1 или +1), мантисса (от 0 до 1) и экспонента (от -128 до +127). Фактическое число получается так: s * m * 2 ^ e. Подробнее в https://ru.wikipedia.org/wiki/%D0%A7%D0%B8%D1%81%D0%BB%D0%BE_%D0%BE%D0%B4%D0%B8%D0%BD%D0%B0%D1%80%D0%BD%D0%BE%D0%B9_%D1%82%D0%BE%D1%87%D0%BD%D0%BE%D1%81%D1%82%D0%B8 |
| Автор: akizelokro 16.7.2013, 22:47 | ||||
Не знаю. Я помню, что в fortran'e тогда были float, и double precision, и все равно не хватало, стали вводить huge. Но с huge слава богу дело так и не пошло, сейчас глянул, там есть extended precision c 16 байтами под число. Добавлено через 10 минут и 35 секунд
так будет лучше всего. просто знай вот эту разницу, а если ты не занимаешься конкретной тематикой, где нужна точность, тебе это знание может и не пригодиться никогда. Выпавший зуб даю! Просто прими как данное, что для универсальности в С/C++, да и не только есть много вещей, которые, создавайся язык прямо сейчас, были бы не нужны 15-20 лет назад чуть ли не байты считались, чтобы уменьшить размер исполняемой программы. Поэтому, imho, тогда и была введена разница между int и long, например. Но остались и старые программы кое-где и старый код. Остаётся либо жертвовать обратной совместимостью и универсалностью, либо сейчас думать, зачем нужно такое конкретное разделение между целочисленными int и long, когда на современной технике возможная разница между ними уже ничего не значит. Почти не значит. |
| Автор: hoz 17.7.2013, 00:14 | ||
Вот скрин страницы учебника:![]() Как выше обсуждалось, неявное приведение типов отрабатывается в случает надобности, если того требует ситуация (наличие переменные разного типа в выражении). Тут то ли перевод нечёткий, то ли автор не так выразился. Решил я переспросить. Там сказано, что:
Но точность переменных типа float 7-8 знаков, а значит 1000.0 и .05 вполне потянет тип float, а значит не разумно производить неявные преобразования и расчёт с данными переменными в таком виде... Я прав? Ведь 1000.0 - тут порядок мантиссы 1, а у .05 - 2. Как раз float тут самое то, т.к. по скорость расчёта, так и потому, что он поддерживает данную точность. А автор учебника утверждает, что типа нет судя по контексту. |
| Автор: feodorv 17.7.2013, 07:02 | ||||||
| "Структура for"? В смысле "управляющая структура кода" (или "структурный оператор")? Почему не просто "оператор цикла for" - получилось бы два раза рядом стоящих слова "оператор"? Потянет.
Наверное, он всё-таки хотел иметь в виду другое. Математические функции, определённые в заголовке http://ru.wikipedia.org/wiki/Math.h, практически все работают с double, в том числе и pow. Особого смысла (в данном примере) преобразовывать float-аргумент к double, а затем результат из double во float, нет. Поэтому будем работать с double:
А то, что дальше
мне видится как копипаст от предыдущего утверждения. Какие проблемы. Пробуйте с float. Потом сравните результаты с double. Для большого числа лет результат должен заметно отличаться... Для 10 - незначительно... |
| Автор: hoz 17.7.2013, 12:18 | ||||
Как это пробывать? Ведь сказано же http://ru.wikipedia.org/wiki/Math.h, что:
Получается, преобразование происходит даже когда нет необходимости.. Я вот заметил, что это не разумно. Потому и спросил. Ведь если не требуется высокая точность, а расчёт её учитывает, как это иначе понимать? |
| Автор: Alexeis 17.7.2013, 12:39 |
| На самом деле сопроцессор можно настроить на точность вычислений. Можно сделать так, чтобы он считал даблы с точностью флоатов (библиотеки DirectX так и делают) . Вообще, преобразование операция простая, так что можно не париться. |
| Автор: feodorv 17.7.2013, 13:54 | ||
Напишите свою fnpow
Необходимость есть, и связана она с типом аргумента функции pow. Вот если была бы библиотечная функция fpow(float,float), тогда другое дело. Но что есть, то есть. Мне всё же не понятно возмущение по поводу double. Ныне (если не брать в рассмотрение особые случаи) это стандартная единица для представления чисел с плавающей точкой. Современные (со)процессоры работают именно с double (хотя Вам кажется, что с float). То есть даже если вы будете пользоваться float, процессор всё равно преобразует float в double (а то и в long double), и уже потом будет складывать, вычитать, умножать, делить etc. Даже printf не умеет печатать float, минимум double (хотя scanf умеет работать с float). |
| Автор: hoz 17.7.2013, 14:21 | ||||
Получается тут "виновник торжеств" не функция pow, а аргументы... Автор выразился видимо не особо внятно, по крайне мере я так подумал. Теперь понял. Хотя проще же было сделать по дефолту, чтоб типы данных в аргументах функции pow были пользовательскими. Это же логично..
Получается, опять же float как тип уже не востребован, что и требовалось доказать. Если уж его игнорят современные процы. |
| Автор: Alexeis 17.7.2013, 14:31 | ||
Это давнее заблуждение. То что регистры двойной точности еще не значит, что вычисления выполняются одинаково быстро. Арифметические плюс минус умножить делить, возможно, да и то деление и умножение наверняка с флоатми заметно быстрее. А если перейти к тригонометрическим функциям, то картина меняется кардинально. Время вычисления тригонометрических функций растет значительно быстрее чем точность. В некоторых компиляторах отсутствуют функции sinf, точнее они реализуются через sin , поэтому там нет разницы float/double, но это нифига не правило. На отдельных алгоритмах с использованием функций типа sin/arctan/sqrt у меня получалась разница в 50 раз и больше. Это небо и земля. |
| Автор: Wuffur 17.7.2013, 14:38 |
| Машинное эпсилон для IEEE 08 float32: 2^-24 = 5.96e-08 , так что почему нельзя 1.000001eN, где 0.000 0001 = 1*10^-7 я не знаю. Для самообразования: http://en.wikipedia.org/wiki/Machine_epsilon |
| Автор: feodorv 17.7.2013, 16:02 | ||
Я написал: "к примеру" Ок))) Ну почему. Если Вам критично использование памяти и не критична точность с расширенным диапазоном, тогда float является спасением (если, конечно, на Вашей платформе float "в два раза меньше места занимает"))). Вот и Alexeis говорит, что кое-где весьма бережно относятся к float. И таки дают функции с float'ами. Ещё выше писали про графику, SSE и т.д. float используется, и используется активно))) |
| Автор: Alexeis 17.7.2013, 17:31 | ||
У кого есть поновее компилятор под рукой проверьте следующий код
Старичок VS2005 выдал флоаты в 2 раза медленнее даблов, но есть подозрение, что у него нет sinf . С графикой я четко замечал влияние _control87(_MCW_PC, _PC_ХХ); Т.е. несмотря на 64х битность сопроцессора он вполне умеет считать и с пониженной точностью для флоатов. |
| Автор: hoz 17.7.2013, 22:31 | ||
| Тема разраслась, начались вещи писаться, который уже за гранью темы и моего понимания в частности. Я выше уже спрашивал про то, как понять:
Например, берём числа: 123245.84, 457235.1, 235,6882347 У каждого из них будет фиксированная точность и изменяющаяся? Я сколько не читаю про это, что-то не въезжаю. |
| Автор: feodorv 18.7.2013, 08:30 | ||||
| Давайте так. Кроме представления чисел в форме "числа с плавающей точкой" есть представление числа в форме "http://ru.wikipedia.org/wiki/%D0%A7%D0%B8%D1%81%D0%BB%D0%BE_%D1%81_%D1%84%D0%B8%D0%BA%D1%81%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%BD%D0%BE%D0%B9_%D0%B7%D0%B0%D0%BF%D1%8F%D1%82%D0%BE%D0%B9". С точки зрения точности представления чисел эти две формы являются противоположными: Для чисел с фиксированной точкой
Конкретное число x в машинном представлении (в силу ограниченности возможностей представления различных чисел на ЭВМ) может являться совсем другим числом X (округлённым до ближайшего "машинного" числа). Поэтому возникает погрешность машинного представления: вместо x имеем X. Задача: оценить эту погрешность. Погрешность можно оценить в лоб: |x-X| - насколько расхождение абсолютно. Можно более тонко - соизмерять с исходным числом: |x-X|/|x| - это уже относительная погрешность. К примеру: в корпорации "РосМама" счётная палата выявила финансовую отчётность на 99 млрд рублей из 100 млрд финансирования, а в компании "ВасяПупкин" смогли оправдаться за 300 тысяч из 400 тыс бюджета. Вопрос: кто из них больший растратчик? Так вот с точки зрения относительной погрешности "РосМама" растратила всего 1%:
Вот причём здесь конкретное число? И куда делись основополагающие термины "относительная" и "абсолютная"? Для любого X в форме числа с плавающей точкой верно:
|
| Автор: volatile 18.7.2013, 12:46 | ||
Alexeis, так время измерять нельзя! Оптимизатор там просто вообще выбрасывает холостые циклы, так как результат никуда не используюцца. У меня ваш код выдавал крайне не стабильные результаты При добавления накопления и вывода результата, время вычислений возросло на 2 порядка (~100 раз)!!! (что явно свидетельствует что в вашем коде, оптимизатор просто выбрасывал не нужные вычисления) И время, после коррекции стало примерно одинаковым (+/-2%). Кроме того там есть и еще ошибки. Если не ошибаюсь, вы здесь перепутали местами маску и значение. То есть нужно писать наоборот:
http://msdn.microsoft.com/en-us/library/e9b52ceh(v=vs.80).aspx |
| Автор: feodorv 18.7.2013, 12:49 |
Для каждого числа будет определена абсолютная и относительная точность представления в форме числа с плавающей точкой:
|
| Автор: Wuffur 19.7.2013, 12:26 |
| Давайте ещё про long double похоливарим. |
| Автор: Alexeis 19.7.2013, 13:49 | ||
| Да, был неправ на счет тригонометрических функций. Для AMD64/x86 процов нет специальной реализации sinf/atanf . Сопроцессор считает их исключительно как double . У него просто нет аппаратных вычислительных блоков разрядности 32. Для тригонометрии получается double будет работать быстрее за исключением случаев не хватки кэша процессора. Но я вот провел другой эксперимент не зависящий от кэша проца. Для складирования использовал массивы небольшой размерности (на 100 элементов), так чтобы double и float были в равных условиях. Кроме того, чтобы компилятор не филонил, зарядил даже вывод результатов на экран. Вот такой получился код
Результат для float -в получился в 2 раза быстрее. Причем SSE2 мало влияет на результат, поскольку такой код не очень хорошо оптимизируется. Зато разница по скорости тем заметнее чем сложнее выражение. По-моему это явно указывает на то, что сопроцессору не все равно с одинарной или двойной точностью считать. |
| Автор: feodorv 19.7.2013, 16:00 |
| Alexeis, Только у Вас там стоит _PC_64, что на мой взгляд означает long double, а не просто double. |
| Автор: Alexeis 19.7.2013, 17:04 |
| Мантиса у дабла 53 бита? Нужно попробовать с _PC_53 тогда. |
| Автор: volatile 19.7.2013, 18:07 | ||
Вероятно да, это так. Но сам по себе выбор типа: float или double - никакой роли на точность сопроцессора, а следовательно на скорость, не оказывают. Например, если перед дабл-вычислением поставить _control87(_PC_24, _MCW_PC); то будет считать с такой - же скоростью как и float. (и вероятно, с такой-же реальной точностью.) В общем здесь весь фокус в инструкции _control87 (); Но это же чисто мелко-мягкая фича, как я понимаю? |
| Автор: Alexeis 19.7.2013, 21:29 | ||
Да, имеется такая пакость, когда имеешь на руках "половинные" даблы. Реально считается только половина цифр. И занимают кучу памяти и нифига не точные. А как можно повлиять на софтовом уровне на скорость операций? Мне кажется только аппаратно можно повлиять. |
| Автор: volatile 20.7.2013, 11:04 |
Ну вот в связи с этим, на вопрос новичка "зачем нужен float?" отвечать - для увеличения скорости, всеже не совсем верно. скорость увеличиваецца не от float, а от какиx-то аппартных (плохо/не переносимых) штучек. О которых новичку вовсе пока не нужно знать. Да и НЕ новичку кстати тоже (помним о "premature optimization"), только если уж совсем подопрет... Правильным-же ответом на вопрос "зачем нужен float?" все-же будет - экономия памяти. нет? |
| Автор: Alexeis 20.7.2013, 12:15 |
| volatile, ну если С++ это только AMD64 и x86 то да. Есть много железяк где нет 64х битного сопроцессора, на некоторых совсем нет никакого даже 32х битного и float-ы вычисляются программно через библиотеки идущие в комплекте с компилятором. В общем случае, float должен быть не медленнее double, a double не медленнее long double. Если пишется универсальный программный модуль, то это следует учитывать. |
| Автор: hoz 21.7.2013, 14:41 | ||||
| Мда. Вроде как уже не первый день программирую. По крайне мере, кой-чиво уже писал. А вот эти основы для меня самые трудные для понимания. Уже казалось бы, и так и сяк кручу и верчу. Но как-то не всё улаживается в голове. Взять хотя бы понятия абсолютная погрешность и относительная погрешность. О погрешностях я прочитал тут http://ru.wikipedia.org/wiki/%D0%9F%D0%BE%D0%B3%D1%80%D0%B5%D1%88%D0%BD%D0%BE%D1%81%D1%82%D1%8C_%D0%B8%D0%B7%D0%BC%D0%B5%D1%80%D0%B5%D0%BD%D0%B8%D1%8F Вот как у чисел с фиксированной точностью может быть так:
А у чисел с плавающей точкой (запятой) иначе:
Понять не выходить. Относительно чего всё это анализировать? Думаю, если оно не пригодится дальше, может вообще пропустить Хотя хочется уже добить этот момент и дальше свободно всё штудировать. |
| Автор: feodorv 21.7.2013, 15:38 | ||
Я бы забил)))
Ну, если охота пуще неволи... Что именно в этом абзаце не понятно: Для каждого числа будет определена абсолютная и относительная точность представления в форме числа с плавающей точкой:
Как видно, абсолютная погрешность представления меняется (в зависимости от представляемого числа), поэтому она "изменяющаяся". И "изменяющаяся" она не для конкретного выбранного числа (в зависимости от фаз Луны, что ли, сегодня одна, завтра - другая))), а меняется вместе с представляемым числом. В то же время относительная погрешность никак не меняется при выборе представляемого числа, поэтому она "фиксированная"... |
| Автор: hoz 21.7.2013, 16:03 | ||
Тут же e и есть эпсилон. Откуда там после 1.0е-2 будет ещё * эпсилон? p.s. Видать скоро точно сдамся |
| Автор: Wuffur 21.7.2013, 16:29 | ||||
О господи, e-2 - это порядок в десятичном представлении. 1.0 - мантисса в десятичном представлении. Разница между, к примеру float2, который 2^-8(если первая не значащая) последним битом и следующим в памяти за ним числом(предпоследний бит представлен для +inf,-inf и различных NaN, подробнее в википедии) и есть машинное эпсилон. Только сначала нужно перегнать всё в двоичное представление, а это сделано для простоты восприятия программистом. Feodorv, и ни надо новичкам в десятичном представлении числа с плавающей точкой показывать, пусть учатся, а то будет у них глупое представление, которое потом из них не выбьешь. К тому же сам немного ошибаешься. |
| Автор: feodorv 21.7.2013, 17:20 | ||||||||
Ээээ, нет. Постойте. Буковка e в записи числа указывает, что дальше пойдёт целое число, означающее прядок числа:
Эти примеры понятны? (.0 в записи числа с плавающей точкой - необязательны, но приведены для порядка). Что же такое эпсилон? Находим ссылку, которую дал Wuffur: Для самообразования: http://en.wikipedia.org/wiki/Machine_epsilon Заходим по ней, видим название статьи: Machine epsilon. Так вот он, какой эпсилон - машинный! Для float это значение равно 2 ^ -24 = 5.96e-08. Что это значит?
То есть для разницы машинного представления и первоначального числа: |X - x| < (X * 5.96e-08) или двойное неравенство X - (X * 5.96e-08) < x < X + (X * 5.96e-08) А с чего вдруг моё хорошее число x может превратиться в какое-то машинное X? И вот тут хочешь-не хочешь, а придётся разбираться с форматом представления чисел с плавающей точкой (ссылка от bsa: https://ru.wikipedia.org/wiki/%D0%A7%D0%B8%D1%81%D0%BB%D0%BE_%D0%BE%D0%B4%D0%B8%D0%BD%D0%B0%D1%80%D0%BD%D0%BE%D0%B9_%D1%82%D0%BE%D1%87%D0%BD%D0%BE%D1%81%D1%82%D0%B8) Внезапно выяснится, что и мантисса, и порядок находятся в двоичной системе счисления (а не в десятеричной!), что лидирующая единица не участвует в представлении числа, но держится в уме и т.д. и т.п. И вот с этого последнего и стОит начинать разговор. Всё остальное - лирика... Добавлено через 5 минут и 4 секунды Ух ты, пока писАл, Wuffur, уже ответил)))
Я жеж только за! Я и за полную и неприкрытую правду))) Где, в чём? |
| Автор: Wuffur 21.7.2013, 17:55 | ||
В том что если умножить 10^n это то же самое что 2^m, которое и указывает порядок. С помощью 1.0e-2 указывает, что на экран вывелось именно 10^-2, а не 2^-8. Мантисса (1),0100011, для float32. И машинное эпсилон надо умножать на 2^-8. |
| Автор: feodorv 21.7.2013, 18:28 | ||||
Ну да, надо было начинать с начала (с формата чисел), а не с конца... Хотел как лучше))) В каком смысле? Чешу репу))) Вот тут всё нормально: http://codepad.org/6J68wSlx Откомпилированное на MS VC 6.0 (какой уж под рукой))) даёт:
Это результат зверской оптимизации у Microsoft? |
| Автор: Wuffur 21.7.2013, 21:27 | ||||||
Ничего не знаю. Мой gcc:
Даёт:
Наверное msvc 6.0 слишком умный %f - float, %d - double. |
| Автор: hoz 22.7.2013, 09:47 |
| В общем-то, Благодарю всех за обсуждение! Буду дальше изучать язык. К этому вопросу вернусь позже, дабы полностью прояснить ситуацию. Пока что уже я и так понял разницу, и много того чего не знал, капаясь в вики. Но чтоб понять целостную картину, видимо нужно больше времени. |
| Автор: akizelokro 23.7.2013, 16:16 |
| Целостную картину можно было понять уже на первой странице. Просто гуроны (от слова "гуру") решили поблистать. И это достаточно понятное и нормальное побуждение. Мало какой эксперт не воспользуется ситуацией. А есть жёсткая прагматика. Если вопрос достаточно сложен (много информации), то, когда перестаёшь работать с ним постоянно, мелкие детали вымываются из памяти. И при возврате к ним всё равно снова приходится садиться за справочное пособие. |
| Автор: feodorv 23.7.2013, 16:39 | ||||
akizelokro, слишком много букв, да?
Повторение - мать учения))) Ой, да ладно. Блеска здесь не наблюдается. Но вот попробуйте доходчиво ответить на вопрос:
А я на Вас со стороны посмотрю |
| Автор: akizelokro 23.7.2013, 17:29 | ||
Вы бы лучше на меня в 90ых посмотрели, когда я смотрел на флаги форматирования функции printf., работая с float и double раз в сто лет в обед. И рассуждал так.. у int флаг i, у лонгов - l, у char - с, у unsigned - u, значит, у float - f, у double - d (это на память). Самое интересное, что f для float срабатывало, и потом я уже с полной уверенностью писал для double - d! (и черта с два интернета было под рукой, чтобы посмотреть, как оно надо). После выдачи с d неожиданного результата глаза собирались в кучу и озирали строку вывода) Кстати, для флага f тип по умолчанию double.
Ну, я смотрю на это философски. В моё время была хорошая математическая подготовка, сейчас больше, имхо, люди приходят с веб-программирования, там больше уклон уже не на математическую базу. Закономерный этап. |
| Автор: feodorv 23.7.2013, 22:53 |
Это особенность всех функций с переменным числом аргументов: float расширяется до double, и всё тут, живи как хочешь))) Ну да, в принципе могли бы и так сделать, оставив %d (от digital) для double, а %i для целых (от integer). Но история пошла другим путём... |
| Автор: volatile 23.7.2013, 23:57 | ||||
В данном случае нужно отсылать к учебнику за 4-5 класс средней школы. Человек не понимает разницы между "абсолютно" и "относительно". (не важно о чем речь, о погрешности, или о прибавке к зарплате...) А он именно этого не понимает. |
| Автор: hoz 25.7.2013, 00:41 | ||||
Вообще нет, не этого. Я не понял в том момент когда писал, что для чисел определённого типа применимы разные точности:
И, именно по этому, были заданы вопросы. Вышло так сказать, противоречие. |