這裏有一個版本,它允許你指定一個基礎(2-10):
在shell:
167> c(my).
{ok,my}
168> Base10 = 10.
10
169> Base2 = 2.
2
170> my:list_mult([1,1], [1,1,1], Base10).
[1,2,2,1]
171> 11 * 111.
1221
172> my:list_mult([1,1], [1,1,1], Base2).
[1,0,1,0,1]
173> io:format("~.2B~n", [2#11 * 2#111]).
10101
ok
-module(my).
%%-compile(export_all).
-export([list_mult/3]).
-include_lib("eunit/include/eunit.hrl").
list_mult(List1, List2, Base) ->
Number = digits_to_int(List1, Base) * digits_to_int(List2, Base),
list_of_digits(Number, Base).
list_mult_test() ->
Base10 = 10,
?assertEqual(
list_of_digits(123 * 12, Base10),
list_mult([1,2,3], [1,2], Base10)
),
?assertEqual(
list_of_digits(2 * 5, Base10),
list_mult([2], [5], Base10)
),
?assertEqual(
list_of_digits(0 * 0, Base10),
list_mult([], [], Base10)
),
?assertEqual(
list_of_digits(0 * 23, Base10),
list_mult([], [2,3], Base10)
),
?assertEqual(
list_of_digits(30 * 4, Base10),
list_mult([0,3,0], [0,4], Base10)
),
?assertEqual(
list_of_digits(1 * 3, Base10),
list_mult([0,0,1], [0,3], Base10)
),
Base2 = 2,
?assertEqual(
list_of_digits(2#11 * 2#1000, Base2),
list_mult([1,1], [1,0,0,0], Base2)
),
?assertEqual(
list_of_digits(2#1001 * 2#10, Base2),
list_mult([1,0,0,1], [1,0], Base2)
),
%%Errors:
?assertThrow(
"illegal_number: Some elements are >= to Base",
list_mult([1,3], [1,0,0,0,0], Base2)
),
?assertThrow(
"illegal_number: Some elements are >= to Base",
list_mult([a, 3], [f,1], Base10) %%hex notation
).
%--------------
digits_to_int_test() ->
Base10 = 10,
?assertEqual(
123,
digits_to_int([1,2,3], Base10)
),
?assertEqual(
10,
digits_to_int([1,0], Base10)
),
?assertEqual(
3,
digits_to_int([3], Base10)
),
?assertEqual(
0,
digits_to_int([0], Base10)
),
?assertEqual(
0,
digits_to_int([], Base10)
),
Base2 = 2,
?assertEqual(
2#11,
digits_to_int([1,1], Base2)
),
?assertEqual(
2#1101,
digits_to_int([1,1,0,1], Base2)
),
?assertEqual(
2#11110000,
digits_to_int([1,1,1,1, 0,0,0,0], Base2)
),
?assertEqual(
2#1,
digits_to_int([1], Base2)
),
?assertEqual(
0,
digits_to_int([0], Base2)
),
?assertEqual(
0,
digits_to_int([], Base2)
),
%%Errors:
?assertThrow(
"illegal_number: Some elements are >= to Base",
digits_to_int([1,2,3], Base2)
),
?assertThrow(
"illegal_number: Some elements are >= to Base",
list_mult([a, 3], [f,1], Base10) %%hex notation
).
digits_to_int(List, Base) ->
HighestPower = length(List) - 1,
digits_to_int(List, Base, HighestPower, 0).
digits_to_int([], _, _, Sum) ->
Sum;
digits_to_int([X|Xs], Base, Power, Sum) when X<Base ->
Term = round(math:pow(Base, Power) * X), %%round() converts float to integer.
digits_to_int(Xs, Base, Power-1, Sum+Term);
digits_to_int(_, _, _, _) ->
throw("illegal_number: Some elements are >= to Base").
%--------------
list_of_digits_test() ->
Base10 = 10,
?assertEqual(
[1,1],
list_of_digits(11, Base10)
),
?assertEqual(
[1,0,0],
list_of_digits(100, Base10)
),
?assertEqual(
[1],
list_of_digits(1, Base10)
),
?assertEqual(
[],
list_of_digits(0, Base10)
),
Base2 = 2,
?assertEqual(
[1,0,1,1],
list_of_digits(2#1011, Base2)
),
?assertEqual(
[1,1,1],
list_of_digits(2#111, Base2)
),
?assertEqual(
[1],
list_of_digits(1, Base2)
).
list_of_digits(0, _Base) ->
[];
list_of_digits(Number, Base) -> %% 193
HighestPower = get_highest_power(Number, Base),
list_of_digits(Number, Base, HighestPower, []).
list_of_digits(Number, _, 0, Digits) ->
lists:reverse([Number|Digits]);
list_of_digits(Number, Base, Power, Digits) ->
X = round(math:pow(Base, Power)),
Digit = Number div X,
Remainder = Number rem X,
list_of_digits(Remainder, Base, Power-1, [Digit|Digits]).
%---------------
get_highest_power_test() ->
Base10 = 10,
?assertEqual(
2,
get_highest_power(199, Base10)
),
?assertEqual(
3,
get_highest_power(1999, Base10)
),
?assertEqual(
3,
get_highest_power(1000, Base10)
),
?assertEqual(
1,
get_highest_power(19, Base10)
),
?assertEqual(
0,
get_highest_power(5, Base10)
).
get_highest_power(Number, Base) ->
Power = 0,
KeepGoing = (Number div round(math:pow(Base,Power))) > 0,
get_highest_power(Number, Base, Power, KeepGoing).
get_highest_power(Number, Base, Power, KeepGoing) when KeepGoing =:= true ->
NewPower = Power+1,
StillKeepGoing = (Number div round(math:pow(Base, NewPower))) > 0,
get_highest_power(Number, Base, NewPower, StillKeepGoing);
get_highest_power(_, _, Power, KeepGoing) when KeepGoing =:= false ->
max(0, Power - 1).
你能告訴我們你到目前爲止已經試過了,你得到了什麼結果? –
@SteveVinoski我已發佈我所做的... – koko
請注意'[X * Y || X < - [H],Y <-B]'相當於[H * Y || Y <-B]'因爲'H'是列表中的一個數字 - 不是一個列表本身。 – 7stud