如何解决Erlang badarg的问题?

8xiog9wr  于 8个月前  发布在  Erlang
关注(0)|答案(2)|浏览(117)

我在Eclipse中运行了下面的代码。编译代码,并在Eclipse工作区的scr文件夹中创建.txt文件,并将数据的头传递给第一个io:format,但second io:format抛出错误参数,我不知道如何解决它。

%% @author PC
%% @doc @todo Add description to pingping.

-module(pingping).
-export([run/2, run/3]).
-include("conf.hrl").

run(DataSize, R) ->
    OutFileLocation = "out_cerl_pingping.txt",
    case file:open(OutFileLocation, [append]) of
        {error, Why} ->
            ?ERR_REPORT("L'archivio non esiste!", Why);
        {ok, OutFile} ->
            run(DataSize, R, OutFile)
    end.

run(DataSize, R, OutFile) ->
    Data = generate_data(DataSize),
    Self = self(),
    SpawnStart = time_microseg(),
    P1 = spawn(fun() -> pingping(Data, Self, R) end),
    P2 = spawn(fun() -> pingping(Data, Self, R) end),
    SpawnEnd = time_microseg(),
    TimeStart = time_microseg(),
    P1 ! {init, self(), P2},
    P2 ! {init, self(), P1},
    finalize(P1),
    finalize(P2),
    TimeEnd = time_microseg(),
    TotalTime = TimeEnd - TimeStart,
    SpawnTime = SpawnEnd - SpawnStart,
    printResult(Data, R, TotalTime, SpawnTime, OutFile).

pingping(_, Parent, 0) ->
    Parent ! {finish, self()};
pingping(Data, Parent, R) ->
    receive
        {init, Parent, Peer} ->
            Peer ! {self(), Data},
            pingping(Data, Parent, R-1);
        {Peer, _} ->
            Peer ! {self(), Data},
            pingping(Data, Parent, R-1)
    end.

finalize(Pid) ->
    receive
        {finish, Pid} -> ok
    end.

printResult(Data, R, Time_exec, Time_spawn, OutFile) ->
    FormatH = "~-9s\t ~-13s\t ~-22s\t ~-11s\t ~-10s~n",
    Header = ["#bytes", "#repetitions", "exec_time[microsec]", "MBytes/sec", "spawn_time"],
    io:format(OutFile, FormatH, Header),
    MBps = bandwidth_calc(Data, Time_exec),
    FormatD = "~-9w\t ~-13w\t ~-22f\t ~-11f\t ~-3f~n",
    io:format(OutFile,FormatD, [size(Data), R, Time_exec, MBps, Time_spawn ]).

bandwidth_calc(Data, Time) ->
    Megabytes = (size(Data) / math:pow(2, 20)),
    Seconds = (Time * 1.0e-6),
    Megabytes / Seconds.

generate_data(Size) -> generate_data(Size, []).
generate_data(0, Bytes) ->
    list_to_binary(Bytes);
generate_data(Size, Bytes) ->
    generate_data(Size - 1, [1 | Bytes]).

time_microseg() ->
    {MS, S, US} = now(),
    (MS * trunc(1.0e+12)) + (S * trunc(1.0e+6)) + US.

%-define(OUT_FILE, "erl_out.txt").

-define(ERR_REPORT(Msg, Reason), io:format("%%%%%%%%%%%%%% ERROR %%%%%%%%%%%%%%\n" ++
                     "Msg: ~s\n" ++
                     "Reason: ~s\n\n", [Msg, Reason])).
eagi6jfj

eagi6jfj1#

您的代码无法编译,因为conf.hrl包含文件没有显示,所以我猜它提供了底部提供的ERR_REPORT宏。您没有包含如何运行代码的说明,所以我猜测并调用了pingping:run(3, 3).,这导致了Erlang/OTP 26.1下的错误:

** exception error: bad argument
     in function  io:format/3
        called as io:format(<0.95.0>,"~-9w\t ~-13w\t ~-22f\t ~-11f\t ~-3f~n",
                            [3,3,23,0.12439230213994565,6])
        *** argument 3: element 3 must be of type float
                        element 5 must be of type float

错误消息给了我们答案:你想把整数打印成浮点数。更改此行:

FormatD = "~-9w\t ~-13w\t ~-22f\t ~-11f\t ~-3f~n",

为了纠正要素3和要素5的格式,

FormatD = "~-9w\t ~-13w\t ~-22w\t ~-11f\t ~-3w~n",

导致pingping:run(3, 3)返回ok和包含以下内容的out_cerl_pingping.txt文件:

#bytes       #repetitions    exec_time[microsec]     MBytes/sec      spawn_time
3            3               15                      0.190735        5
bz4sfanl

bz4sfanl2#

调试的一种方法是将所有格式说明符设置为~p,因为它将接受所有Erlang术语,因此至少不会再有badarg错误,同时我们可以看到打印的实际值。

FormatD = "~p\t ~p\t ~p\t ~p\t ~p~n",

从那里你可以开始改变5个参数中的每一个,以找出哪些参数的数据类型不匹配。
最终答案已经由@steve提供

相关问题