На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Модераторы: ANDLL, ALXR
Страницы: (5) 1 [2] 3 4 ... Последняя » все  ( Перейти к последнему сообщению )  
> Деление в языках программирования
   
Какое деление вы считаете более логичным (см. первое сообщение)
Гости не могут просматривать результаты голосования.
Гости не могут голосовать 
    В Фортране операция определяется типом операндов. Вот там это несколько напрягало, поскольку не было возможности нормально вещественно поделить два целых. Поскольку тип переменных там по умолчанию зависит от первой буквы имени ошибиться с типом операндов затруднительно.
    Когда я активно программировал на Паскале не напрягало использовать div для деления целых, как не напрягало (даже страховало) отсутствие неявного приведения вещественного к целому (при присваивании и использовании в качестве аргументов).
    В C приходится следить за типами операндов и это немного напрягает, но поскольку работа с числами в этом языке не основное, то на зависимость операции от типа натыкаешься относительно редко. Функции короче, чем в фортране, имена длиннее, за типами следить не сильно накладно.
    В Питоне поступили последовательнее. Там деление и деление с остатком - две разные операции, обе применимые и к вещественным и к целым числам. Более того деление с остатком там более последовательно при получении отрицательного частного.
      Проголосовал за "другое", привык к Перл'овке ;) Там результат деления - скаляр. А вот уже его представление зависит от его значения. Коротенький пример из дебага:

      ExpandedWrap disabled
          DB<1> x 1/2
        0  0.5
         
          DB<2> x 1/3
        0  0.333333333333333
         
          DB<3> x 2/2
        0  1
         
          DB<4> x 4/2
        0  2
         
          DB<5> x 1/81
        0  0.0123456790123457

      Считаю это естественным выражением смысла деления. В строго типизированных языках с этим засада.
        Думаю, и так довольно очевидно, что логичнее сделано в VB/Pascal и т.д., где два разных оператора для целочисленного и с плавающей точкой деления. В C/C++ легко можно создать себе труднообнаруживаемый баг, лишь сменив тип одной переменной, участвующей в выражении. Компилятор, при этом, будет тихо переваривать выражение как валидное, а то, что там в результате изменения типа результат приводится к другому типу, это уже твои проблемы -- не уследил. В VB, используя строго определенный оператор деления, на такую ситуацию попасть невозможно.

        Добавлено
        P.S.
        Промахнулся с пунктом, проголосовал за первый. Кто хочет выбрать первый, голосните за второй плиз, я уже за вас голос отдал :)
          Цитата B.V. @
          Компилятор, при этом, будет тихо переваривать выражение как валидное, а то, что там в результате изменения типа результат приводится к другому типу, это уже твои проблемы -- не уследил.

          Ворнинг по идее должен выдать. По крайней мере MSVS выдает ворнинг аля:
          ExpandedWrap disabled
            warning C4244: '=': conversion from 'int' to 'float', possible loss of data
            Цитата OpenGL @
            А как думаете вы?

            В Си все логично.
              Цитата shm @
              В Си все логично.
              :lool: Особенно первый взгляд на строку: a = a+1; :rolleyes:
                Цитата Славян @
                a = a+1;

                А что с ней не так?
                  Ему, видимо, не нравится, что одиночный знак "равно" означает не равенство, а присваивание.
                  Так он в таком качестве не выступает только в языках Н.Вирта.
                    Цитата amk @
                    Ему, видимо, не нравится, что одиночный знак "равно" означает не равенство, а присваивание.
                    :yes:
                      Операция присваивания используется намного чаще, чем сравнение.
                        Цитата Qraizer @
                        Хотя я могу себе представить Палькальное поведение, где мы имеем две разные операции для вещественного и целочисленного деления, но каждая из них неприменима для операндов неверного типа.

                        И разве это не логичный вариант? / - деление чисел с плавающей точкой, а какой-нибудь div делит целочисленно.

                        Добавлено
                        Цитата shm @
                        Операция присваивания используется намного чаще, чем сравнение.

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

                        Добавлено
                        Цитата amk @
                        Так он в таком качестве не выступает только в языках Н.Вирта.

                        А как же пролог какой-нибудь? В том же haskell = имеет смысл совсем иной, чем в императивных языках.
                          Есть ещё три, хоть и не распространённых, подварианта:
                          1) Ocaml (не знаю, как в других ML'ах): целочисленное деление «/», деление чисел с плавающей точкой «/.» («+», «-», «*» аналогично, без точки — int, с точкой — float). Никакого неявного приведения типов, никаких случайных ошибок. Но писать код может быть менее удобно из-за необходимости явно конвертировать int во float.
                          2) Haskell: тайпкласс Fractional определяет тип функции деления «/» как (a → a → a), т.е. оба операнда должны иметь одинаковый тип, а т.к. субтипирования в Хаскелле нет, то и неявного приведения, например, из Int в Double тоже быть не может и опять никаких случайных ошибок. Писать код, опять же, может быть менее удобно по той же причине, что и в первом пункте.
                          3) Lisp: в целом, деление работает так же, как в Python, но при делении двух целых происходит не целочисленное деление, а создание рациональной дроби. Т.е. «(/ 2 3) ⇒ 2/3», «(/ 4 6) ⇒ 2/3» и т.д.

                          Добавлено
                          Цитата amk @
                          Так он в таком качестве не выступает только в языках Н.Вирта.

                          А ещё *ML, Lisp, SmallTalk, Tcl, Limbo, Ada (впрочем, если под «языками Н.Вирта» подразумевать языки с алголовским синтаксисом, то Ада туда попадает, пожалуй).
                          Сообщение отредактировано: korvin -
                            Цитата D_KEY @
                            И разве это не логичный вариант? / - деление чисел с плавающей точкой, а какой-нибудь div делит целочисленно.
                            В системе типов C — нет. Операция / реализована по-разному для разных типов, но смысл её одинаков безотносительно к типам. Фактически тут классический полиморфизм. Другой вопрос, насколько логична сама система типов в C. Но это будет не голосовалка, это холивар.
                            Плюс, как уже упоминали, создание вдруг "из ниоткуда" значений новых типов, пусть даже в теории и логично, но крайне не практично во многих случаях. Компилятор должен делать то, что ему сказал человек. Если компилятор не уверен, что понял правильно, логично переспросить, именно так поступают на практике люди. В большинстве случаев. Сходный с ТС вопрос: надо ли возвращать complex из sqrt() при отрицательном аргументе?
                              Цитата Qraizer @
                              Операция / реализована по-разному для разных типов, но смысл её одинаков безотносительно к типам. Фактически тут классический полиморфизм.

                              В сочетании с неявным приведением это работает не очень хорошо.

                              Добавлено
                              Да и в принципе мне кажутся более логичным отдельные div и mod для деления по модулю.
                              Сообщение отредактировано: D_KEY -
                                Цитата D_KEY @
                                А как же пролог какой-нибудь?
                                В Прологе вообще нет операции присваивания. Так же, строго говоря, нет операции присваивания в функциональных языках (имеются в видц именно функциональные, а не императивные со средствами функционального программирования). Вообще, в декларативных языках с операцией присваивания плохо. Там её или нет, или она присутствует на птичьих правах.

                                Операция присваивания изменяет значение переменной. Там где "переменная" создаётся с некоторым значением и живёт с ним, пока её не уничтожат присваивания нет.
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0417 ]   [ 18 queries used ]   [ Generated: 18.04.24, 23:11 GMT ]