целочисленное деление

По определению целочисленное деление возвращает частное.

Почему 4613.9145 div 100. выдает ошибку ("неверный аргумент")?


person Bertaud    schedule 20.01.2011    source источник


Ответы (4)


Для div аргументы должны быть целыми числами. / принимает в качестве аргументов произвольные числа, особенно числа с плавающей запятой. Итак, для вашего примера будет работать следующее:

1> 4613.9145 / 100.  
46.139145

Чтобы сравнить разницу, попробуйте:

2> 10 / 10.
1.0

3> 10 div 10.
1

Документация: http://www.erlang.org/doc/reference_manual/expressions.html


Обновление: целочисленное деление, иногда обозначаемое \, может быть определено как:

a \ b = floor(a / b)

Итак, вам понадобится функция пола, которой нет в стандартной библиотеке.

% intdiv.erl
-module(intdiv).
-export([floor/1, idiv/2]).

floor(X) when X < 0 ->
    T = trunc(X),
    case X - T == 0 of
        true -> T;
        false -> T - 1
    end;

floor(X) -> 
    trunc(X) .

idiv(A, B) ->
    floor(A / B) .

Применение:

$ erl
...
Eshell V5.7.5  (abort with ^G)
> c(intdiv).
{ok,intdiv}
> intdiv:idiv(4613.9145, 100).
46
person miku    schedule 20.01.2011
comment
Не согласен: результат 46, а не 46,139145. div = целочисленное деление, / = деление с плавающей запятой - person Bertaud; 20.01.2011
comment
что бы вы ни предложили, это нелогично. trunc(N/100) дает результат. Функция div, похоже, не соблюдает определение целочисленного деления. - person Bertaud; 20.01.2011
comment
@Bertaud: Хорошо, извини, я не хотел ничего путать. Но затем попробуйте перефразировать свой вопрос, чтобы ответы были более целенаправленными. Вам нужна целая часть деления float / int, округленная часть, пол, потолок? Вы получаете ошибку неправильного аргумента, потому что аргументы операций должны быть определенного типа, а в вашем примере это не выполняется. - person miku; 20.01.2011
comment
@Bertaud: Ваш вопрос интересен, возможно, вы подозреваете здесь несоответствие. Попытайтесь выразить это в своем вопросе, сделайте его более интересным, заставьте больше людей посмотреть на него и, возможно, ответ лучше, чем мой. - person miku; 20.01.2011
comment
Я просто хочу сделать целочисленное деление двух чисел! А целочисленное деление определено в математике: вернуть частное результата. Что я мог добавить? Может быть, у erlang есть другое определение? - person Bertaud; 20.01.2011
comment
@Bertaud: Обновил мой пост, посмотрите, понравится ли он вам. - person miku; 20.01.2011
comment
Вопроса не было: напишите мне модуль имитирующий целочисленное деление!!! Тем не менее, спасибо за вашу работу - person Bertaud; 20.01.2011

Целочисленное деление в Erlang, div, определено таким образом, что принимает два целых числа в качестве входных данных и возвращает целое число. Ссылка, которую вы дали в предыдущем комментарии, http://mathworld.wolfram.com/IntegerDivision.html, в своих примерах использует только целые числа, поэтому в данном обсуждении он не очень полезен. Использование trunc и round позволит вам использовать любые аргументы по вашему желанию.

person rvirding    schedule 21.01.2011

Я не совсем понимаю, что вы подразумеваете под "определением". Разработчики языка могут определять операторы по своему усмотрению. В Erlang они определили div для приема только целочисленных аргументов.

Если вам интересно узнать о проектных решениях создателей Erlang, вы можете написать им по электронной почте. Кроме того, если вы достаточно любопытны, чтобы просмотреть (замечательно короткую) грамматику, вы можете найти ее здесь. Удачи!

person Aliud Alius    schedule 20.01.2011
comment
да и нет. Прочтите еще раз mathworld.wolfram.com/IntegerDivision.html . Конечно, вы можете определить выражение (1 == 1) как ложное, но этим вы всех беспокоите. - person Bertaud; 21.01.2011
comment
Типы a и b в этой ссылке не определены. Я думаю, что в примере, в котором используются целые числа и выражается промежуточный результат в виде дроби, явно подразумевается, что a и b являются целыми числами. - person cthulahoops; 21.01.2011

Не уверен, что ты ищешь, @Bertaud. Независимо от того, как это определено в другом месте, div в Erlang работает только с целыми числами. Вы можете преобразовать аргументы в целые числа перед вызовом div:

trunc(4613.9145) div 100.

или вы можете использовать / вместо div и впоследствии преобразовать частное в целое число:

trunc(4613.9145 / 100).

И trunc может быть или не быть тем, что вы хотите - вы можете хотеть round, пол или потолок (которые не определены в стандартной библиотеке Erlang, но их несложно определить самостоятельно, как это сделал miku с floor выше). Это одна из причин, по которой Erlang ничего не принимает и не выполняет преобразование за вас. Но в любом случае, если вы хотите целочисленное частное двух нецелых чисел в Erlang, вы должны где-то иметь какой-то шаг явного преобразования.

person Mark Reed    schedule 11.04.2013