Erlang浮点转位语法

1cosmwyk  于 2022-12-08  发布在  Erlang
关注(0)|答案(3)|浏览(161)

我是Erlang的新手,有人能解释一下,这个代码片段中发生了什么吗?

<<2.03:64/float>>.

<<64,0,61,112,163,215,10,61>>

<<2.03:32/float>>.

<<64,1,235,133>>

我正在关注编程Erlang:Joe Armstrong的并发世界的软件和二进制文件和位语法第7章。
如果答案已经存在,请标记为重复。谢谢。

vsnjm48y

vsnjm48y1#

Same results from C:

#include <stdio.h>
int main (int argc, char *argv[]) {
    float f = 2.03F;
    unsigned char *c;
    c = (unsigned char *) &f;
    for (int i = 0; i < 4; ++i)
        printf("%d ", c[i]);
    printf("\n");

    double d = 2.03;
    c = (unsigned char *) &d;
    for (int i = 0; i < 8; ++i)
        printf("%d ", c[i]);
    printf("\n");
}

Output:

133 235 1 64 
61 10 215 163 112 61 0 64

or Perl:

$ perl -wE 'say join " ", map ord, split //, pack "f", 2.03' 
133 235 1 64
$ perl -wE 'say join " ", map ord, split //, pack "d", 2.03' 
61 10 215 163 112 61 0 64

That's how floating point numbers are represented internally. See Floating-point aritmetic .
A nice demo to experiment with the values here .

mcvgt66p

mcvgt66p2#

<<2.03/float>>.
<<64,0,61,112,163,215,10,61>>

在Erlang中,float二进制的默认大小是64,因此输出存储为8 X 8 = 64字节。当float的默认大小为32时,它存储为4 X 8 = 32字节。下面的代码显示了如何从字节中提取位。

[ K || <<K:1>> <= <<2.03/float>>].

[0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,1,0,1,1,1,0,0,0,0,1,0,1,0,0,0,1,1,1,1,0,1,0,1,1,1,0,0,0,0,1,0,1,0,0,0,1,1,1,1,0,1]

上述输出中的前8位是“0,1,0,0,0,0,0,0”,当转换为整数时给出以下输出。

erlang:list_to_integer("01000000",2).
   64

类似地,接下来的8位给出0,第三组8位给出61,等等。

ajsxfq5m

ajsxfq5m3#

  1. Floats are represented by a secret code. Erlang interprets that secret code in order to output:
<<64,0,61,112,163,215,10,61>>
  1. When you chop off the first 32 bits of the secret code, it means something totally different, and Erlang interprets the remaining 32 bits to output:
<<64,1,235,133>>

which is why you don't just get:

<<163,215,10,61>>

I am new to erlang
Then the bit syntax for floating point numbers is the least of your worries. If you understand it for integers, then move on.

相关问题