LINUX.ORG.RU

C programming, float возвращает 0

 


0

2

Привет,

Пишу задание, несложное, но встретился с такой проблемой, если использовать integer то все считает правильно, но при использовании float, тупо возвращает 0. Может кто встречался с этой проблемой уже?

http://pastebin.com/U7YcjUf5



Последнее исправление: maxylopes (всего исправлений: 1)

Ответ на: комментарий от KennyMinigun

Дольше выполняется к тому же.

Не верю, что одинаковый код будет выполняться дольше. Вот больший размер бинарника — факт, но не такой важный.

note173 ★★★★★
()
Ответ на: комментарий от Boy_from_Jungle

читай Мейерса

Он говорит, что в данном случае макрос добро? Зачем тогда его читать?

andreyu ★★★★★
()
Ответ на: комментарий от KennyMinigun

Зачем так сразу? Всего-лишь для канонічности.

Угу, как удобно сделать две разные реализации и сказать, что реализация c++ сливает сишной по скорости.

andreyu ★★★★★
()
Ответ на: комментарий от Reset

в gcc есть костыли типа __typeof, которые позволяют избежать двойных вычислений

Ключевое слово «костыли»? Нет, спасибо.

andreyu ★★★★★
()
Ответ на: комментарий от Eddy_Em

Можно. Но как сказал тот же Reset, это таки костыль.

Вообще, интересная проблемка. Мне на практике не попадались «перегружаемые функции», так что любопытно узнать про способы её решения именно в С (помимо макрофункций).

DeVliegendeHollander ★★
()
Ответ на: комментарий от DeVliegendeHollander

это таки костыль

Ну, раз есть в gcc — то больше ничего и не надо.

А без макросов в сях не перегрузишь. Разве что если будешь создавать свои типы с идентификатором, тогда можно будет сделать промежуточную функцию, которая, анализируя идентификатор, вызовет нужную функцию из массива указателей на функцию (с номером, равным идентификатору).

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от andreyu

Угу, как удобно сделать две разные реализации и сказать, что реализация c++ сливает сишной по скорости.

Угу, как удобно писать на С, компилировать это С++ и говорить, что С++ не сливает по скорости выполнения С.

Идея была таковой: С++ реализация почти всегда будет несколько медленнее аналогичной реализации на чистом С.

KennyMinigun ★★★★★
()

Пишу задание, несложное, но встретился с такой проблемой, если использовать integer то все считает правильно, но при использовании float, тупо возвращает 0.

1. НИКОГДА НЕ СРАВНИВАЙ НА ТОЧНОЕ (НЕ)РАВЕНСТВО НЕЦЕЛЫЕ.

в данном случае функция max может выдать РАЗНЫЕ значения от ОДИНАКОВЫХ аргументов, потому как математики считают 4 == 3.9999999999(9), а вот процессор считает что таки НЕ равны. Ну уж извини, округления тупо нету. В итоге незначительная ошибка приводит к фатальной неоднозначности. Получается, что min(3,4) может иногда дать 3, а иногда 4. У тебя 3 может быть равно 3.9999999999999, и получится 3 после усечения(ответ 3), и может получится 4.000000000000, и в ответе очевидно 4.

2. не надо тип не писать.

Без изменения типа получилось-бы min(3.99999999999999,4) == 4.000000000000(при неправильном сравнении) или 3.9999999999999999, что в общем-то не важно.

drBatty ★★
()
Ответ на: комментарий от KennyMinigun

Идея была таковой

Правильный вопрос должен быть другой: каково отношение прироста скорости разработки к снижению производительности при написании ПО на С++, относительно С. Но ответ на него мы вряд ли получим, реальных больших проектов, переписанных с С на С++ я не встречал.

note173 ★★★★★
()
Ответ на: комментарий от dn2010

Можно просто обойтись лишними скобками в макросе вокруг «переменных»

к сожалению на ++n это НЕ действует. получится ++n < m ? ++n : n.

мат (:

drBatty ★★
()
Ответ на: комментарий от note173

Об этом тут часто пишут, но я не понимаю такую точку зрения. С++ включает в себя почти весь С, как он может быть хуже самого С?

это РАЗНЫЕ ЯП. Диаметрально противоположные. С это вывернутый наизнанку С++.

drBatty ★★
()
Ответ на: комментарий от KennyMinigun

Наверное да. И чуть ли не единственный :)

это не баг, а фича - больше неоднозначностей вылавливается, а это потенциальные глюки.

drBatty ★★
()
Ответ на: комментарий от KennyMinigun

Ради спортивного интереса, приведите пожалуйста пару примеров.

ну функция - это такая хрень, которая описывает операцию над данными, а класс это такой тип данных, который описывает методы с этим типом. как-то так...

drBatty ★★
()
Ответ на: комментарий от Eddy_Em

А в плюсах это будет через жопу.

ты ошибаешься. В плюсах это будет

cout << a << b;

конечно для типа A и типа B нужно описать, КАК выводить данные типы.

drBatty ★★
()
Ответ на: комментарий от Eddy_Em

А в плюсах это будет через жопу.

Зато чуток очевиднее:

    cout  << fixed << setprecision(2) << setw(5) << a
        << " " << setfill('0') << setw(3) << b  << " " << endl;

// пришлось погуглить fixed :)

KennyMinigun ★★★★★
()
Ответ на: комментарий от drBatty

да, но приоритет у него выше, чем у сравнения. т.к. другие переменные уже экранированы скобками, то всё в порядке, дополнительные скобки не нужны.

beastie ★★★★★
()
Ответ на: комментарий от Eddy_Em

А я их использовал в полиморфных классах.

note173 ★★★★★
()
Ответ на: комментарий от KennyMinigun

О-о, да, по сравнению с форматом printf это «чуток очевиднее», ага, ага. Насмешил.

А если строку формата в printf ещё посложнее взять, то тогда уж точно бульбец в кубе будет. :)

DeVliegendeHollander ★★
()
Ответ на: комментарий от Eddy_Em

А мне вот интересно, с чего бы вдруг в тред, название которого начинается с фразы «C programming...», набежали плюсовики и развели рекламную акцию уже безотносительно к основной теме? :)

DeVliegendeHollander ★★
()
Ответ на: комментарий от KennyMinigun

Это звиздец. На плюсах так только упоротые пишут.

Reset ★★★★★
()
Ответ на: комментарий от KennyMinigun

Идея была таковой: С++ реализация почти всегда будет несколько медленнее аналогичной реализации на чистом С.

Вы больны, и идеи ваши больны.

andreyu ★★★★★
()
Ответ на: комментарий от Eddy_Em

Это валидный C++ код. Можешь стандарт почитать, printf и stdio в нем есть.

Reset ★★★★★
()
Ответ на: комментарий от Eddy_Em

Ъ-C++-way будет таким

$ cat format.cpp
#include <boost/format.hpp>
#include <iostream>

int main()
{
        float a = 3.1415;
        int b   = 10;
        std::cout << boost::format("%5.2f %03d \n")%a%b;
}

Как видишь, принципиальных отличий по синтаксису от printf нет, однако тут есть огромное преимущество в виде type-safe. printf через ... может пропустить любую хрень и в лучшем случае это закончится сегфолтом, а в худшем трудноуловимой ошибкой. В данном случае, хрень просто не скомпилируется.

Reset ★★★★★
()
Последнее исправление: Reset (всего исправлений: 1)
Ответ на: комментарий от Eddy_Em

Если человек сам для себя этот макрос писал, то скобки не нужны вокруг a и b.

расскажи, ЗАЧЕМ нужен такой макрос? ИМХО он кроме трудноуловимых ошибок и потенциального уменьшения быстродействия ничего не даёт. Ошибки и тормознутость тут потому, что в выражении max(a,b) a и b вычисляются ОДИН раз, если не иметь под рукой определение макроса. А если он у тебя СЕЙЧАС в голове, то что ты не напишешь a<b ? b:a; Почему?

Вообще макросы, шаблоны. функции и классы - возможность абстрагироваться от незначительных деталей. Не в этом случае, ибо тут нужно помнить, что a и b вычисляются либо 1, либо ДВА раза. Если это тривиальные a и b, то несложно их записать дважды, а вот если первый аргумент это что-то типа foo(x), то логично (a=foo(x))<b?b;a; тут скобки нужны по той причине, что приоритет равно почти самый низкий, даже ниже тернарной операции. Тут решены две проблемы:

1. foo(x) может занимать значительное время

2. foo(x) может второй раз выдать другой результат.

drBatty ★★
()
Ответ на: комментарий от KennyMinigun

Зато чуток очевиднее:

вот это и есть через жопу. Я уже писал на эту тему, КАК выводить должно быть привязано к тому, ЧТО выводить, а не к тому, КУДА. Это и есть ОБЪЕКТНО ОРИЕНТИРОВАННОЕ программирование. КУДА - это _другой_ объект, его не должно волновать ЧТО. Для понимания возьми например простую формулу Z=X*Y - тут результат «умножения» зависит исключительно от типов своих операндов, а TYPE_Z::operator=() выполняется уже ПОСЛЕ умножения, для него результат «умножения» это данность. А ты делаешь «очевиднее» как Z=(T=X*Y);

drBatty ★★
()
Ответ на: комментарий от beastie

да, но приоритет у него выше, чем у сравнения.

у кого? есть куча операций, приоритет которых НИЖЕ, чем у сравнения. И по твоему макросу max(a,b) ну никак не скажешь, что туда нельзя пихать что-то, с приоритетом ниже <. Ну например max(a=foo(x), b) выдаст трижды неверный результат, если это такой макрос. А если функция, то всё ОК (потому ВСЕ #define я пишу БОЛЬШИМИ буквами).

drBatty ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.