实例阐述浮点数解包运算过程

本文来自 瑞仙的Erlang开发博客,转载请注明出处。

原文链接:http://blog.csdn.net/zhongruixian/article/details/21294855

浮点数在计算机中存储或传输时,常会遇到读出来的浮点数有N(N>10)位小数的问题,这里以Erlang实例阐述产生这种现象的原因。

浮点数的实现及其表现,详见:http://blog.csdn.net/zhongruixian/article/details/21292593

Erlang源码:

f(N) ->
    Bin = <<N:32/float>>,
    <<S:1, E:8, M:23>> = Bin,
    io:format("~n"),
    io:format("*---*----------*-------------------------*~n"),
    io:format("* s * eeeeeeee * mmmmmmmmmmmmmmmmmmmmmmm *~n"),
    io:format("*---*----------*-------------------------*~n"),
    io:format("* ~1.2.0B * ~8.2.0B * ~23.2.0B * ~n", [S, E, M]),
    io:format("*---*----------*-------------------------*~n"),
    io:format("~n"),
    E1 = E - 127,
    M1 = calc_m(lists:flatten(io_lib:format("~23.2.0B", [M]))),
    io:format("~n"),
    io:format("S = s = ~w~n", [S]),
    io:format("E = eeeeeeee - 127 = ~w - 127 = ~w~n", [E, E1]),
    io:format("M = ~w~n", [M1]),
    %% 计算公式:V=(-1)^S*2^E*M
    V = math:pow(-1, S) * math:pow(2, E1) * M1,
    io:format("V = (-1)^S*2^E*M = (-1)^~w*2^~w*~w = ~w~n", [S, E1, M1, V]),
    io:format("~n"),
    io:format("~ts ~w ~ts~w~n", [iolist_to_binary("浮点数"), N, iolist_to_binary("以[单精度]存储后根据公式(V=(-1)^S*2^E*M)运算出来的值为:"), V]),
    <<N1:32/float>> = Bin,
    io:format("~ts ~w ~ts~w~n", [iolist_to_binary("浮点数"), N, iolist_to_binary("以[单精度]存储后                    Erlang解包出来的值为:"), N1]),
    io:format("~n"),
    f2(N).

f2(N) ->
    io:format("~ts~n", [iolist_to_binary("双精度:")]),
    Bin = <<N:64/float>>,
    <<S:1, E:11, M:52>> = Bin,
    io:format("~ns,eeeeeeeeeee,mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm~n"),
    io:format("~1.2.0B,", [S]),
    io:format("~11.2.0B,", [E]),
    io:format("~52.2.0B,", [M]),
    io:format("~n"),
    <<N1:64/float>> = Bin,
    io:format("~ts ~w ~ts~w", [iolist_to_binary("浮点数"), N, iolist_to_binary("以[双精度]存储后再读取出来的值为:"), N1]),
    io:format("~n"),
    ok.

calc_m(M) ->
    calc_m(M, -1, 0).

calc_m([], _E, Rt) ->
    Rt1 = Rt + 1,
    io:format("        M = ~w~n", [Rt]),
    io:format("    1 + M = ~w~n", [Rt1]),
    Rt1;
calc_m([M | T], E, Rt) ->
    M1 = case M of
        49 -> 1;
        48 -> 0
    end,
    V = M1 * math:pow(2, E),
    io:format("~w * 2^~3w = ~w~n", [M1, E, V]),
    calc_m(T, E - 1, Rt + V).

运行实例:


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值