将二进制转换为十进制谓词
Convert Binary to decimal predicate
convertBinToDec(B,D):- atom_number(S,B),
atom_length(S,L),
sub_atom(S, 0, 1, After,S1),
atom_number(S1,N),
L1 is L-1,
sub_atom(S, 1,L1, After ,S2),
atom_number(S2,B2),
convertBinToDec(B2,D1),
D is D1+((2*N)**L1).
convertBinToDec(0,0).
convertBinToDec(1,1).
谓词采用 B,它是整数形式的二进制数,应该 return D 其对应的十进制形式,抱歉,我对声明性编程语言还是陌生的,但我不知道为什么我上面的代码总是给假,我觉得基本情况有问题也不允许使用序言库
您已使用After
两次。子句中变量的任何使用都可以实例化为一个单一的值。 After
不能在对过程 sub_atom
的两次调用中采用两个不同的值。这会奏效,请尝试找出原因?
convertBinToDec(B,D):- atom_number(S,B),
atom_length(S,L),
sub_atom(S, 0, 1, After,S1),
atom_number(S1,N),
sub_atom(S, 1, After, 0, S2),
atom_number(S2, B2),
convertBinToDec(B2,D1),
D is D1+((2*N)**(L-1)).
convertBinToDec(0,0).
convertBinToDec(1,1).
这是高度程序化的思维。
一个更惯用的序言解决方案是
conv([], 0).
conv([0|Xs], N) :-
conv(Xs, N).
conv([1|Xs], N) :-
conv(Xs, N1),
length(Xs, L),
N is 2**L + N1.
% To convert atoms to binary list
code_to_binary(48, 0).
code_to_binary(49, 1).
convAtom(B, D) :-
atom_codes(B, C),
maplist(code_to_binary, C, Bin),
conv(Bin, D).
conv/2
完成大部分计算。分区数据表示和问题的核心逻辑总是一个好主意。
示例:
?- conv([1, 0, 0, 1], X).
X = 9.
?- conv([0, 0, 1, 0 , 0, 0, 1], X).
X = 17
?- convAtom('1010', X).
X = 10.
?- convAtom('0010001', X).
X = 17.
鉴于 Prolog 支持使用 0b
前缀表示二进制数,例如0b10011101
,可以使用标准的number_codes/2
谓词进行转换:
convert_binary_to_decimal(Binary, Decimal) :-
number_codes(Binary, Codes),
number_codes(Decimal, [0'0, 0'b| Codes]).
调用示例:
| ?- convert_binary_to_decimal(10011101, Decimal).
Decimal = 157
yes
验证结果:
| ?- Decimal is 0b10011101.
Decimal = 157
yes
convertBinToDec(B,D):- atom_number(S,B),
atom_length(S,L),
sub_atom(S, 0, 1, After,S1),
atom_number(S1,N),
L1 is L-1,
sub_atom(S, 1,L1, After ,S2),
atom_number(S2,B2),
convertBinToDec(B2,D1),
D is D1+((2*N)**L1).
convertBinToDec(0,0).
convertBinToDec(1,1).
谓词采用 B,它是整数形式的二进制数,应该 return D 其对应的十进制形式,抱歉,我对声明性编程语言还是陌生的,但我不知道为什么我上面的代码总是给假,我觉得基本情况有问题也不允许使用序言库
您已使用After
两次。子句中变量的任何使用都可以实例化为一个单一的值。 After
不能在对过程 sub_atom
的两次调用中采用两个不同的值。这会奏效,请尝试找出原因?
convertBinToDec(B,D):- atom_number(S,B),
atom_length(S,L),
sub_atom(S, 0, 1, After,S1),
atom_number(S1,N),
sub_atom(S, 1, After, 0, S2),
atom_number(S2, B2),
convertBinToDec(B2,D1),
D is D1+((2*N)**(L-1)).
convertBinToDec(0,0).
convertBinToDec(1,1).
这是高度程序化的思维。
一个更惯用的序言解决方案是
conv([], 0).
conv([0|Xs], N) :-
conv(Xs, N).
conv([1|Xs], N) :-
conv(Xs, N1),
length(Xs, L),
N is 2**L + N1.
% To convert atoms to binary list
code_to_binary(48, 0).
code_to_binary(49, 1).
convAtom(B, D) :-
atom_codes(B, C),
maplist(code_to_binary, C, Bin),
conv(Bin, D).
conv/2
完成大部分计算。分区数据表示和问题的核心逻辑总是一个好主意。
示例:
?- conv([1, 0, 0, 1], X).
X = 9.
?- conv([0, 0, 1, 0 , 0, 0, 1], X).
X = 17
?- convAtom('1010', X).
X = 10.
?- convAtom('0010001', X).
X = 17.
鉴于 Prolog 支持使用 0b
前缀表示二进制数,例如0b10011101
,可以使用标准的number_codes/2
谓词进行转换:
convert_binary_to_decimal(Binary, Decimal) :-
number_codes(Binary, Codes),
number_codes(Decimal, [0'0, 0'b| Codes]).
调用示例:
| ?- convert_binary_to_decimal(10011101, Decimal).
Decimal = 157
yes
验证结果:
| ?- Decimal is 0b10011101.
Decimal = 157
yes