How to take number up to 64 and output in a 000 000 binary format - little-man-computer

The goal is to accept a number up to 64 and output it in binary in a 000 000 format, so encoded in two decimal values. I know that LMC wont allow an output number like 010, so a format like 11 100 is also acceptable.
Here is my code so far:
INP
STO INPUT
SUB SUB64
BRP END
LDA INPUT
SUB SUB32
BRP SET_32
RET_32 LDA INPUT
SUB SUB16
BRP SET_16
RET_16 LDA INPUT
SUB SUB8
BRP SET_8
RET_8 LDA INPUT
SUB SUB4
BRP SET_4
RET_4 LDA INPUT
SUB SUB2
BRP SET_2
RET_2 LDA INPUT
SUB SUB1
BRP SET_1
RET_1 OUT OUTPUT_2
OUT OUTPUT_1
END HLT
SET_1 STO INPUT
LDA OUTPUT_1
ADD ADD1
STO OUTPUT_1
BRA RET_1
SET_2 STO INPUT
LDA OUTPUT_1
BRA RET_2
SET_4 STO INPUT
LDA OUTPUT_1
ADD ADD100
STO OUTPUT_1
BRA RET_4
SET_8 STO INPUT
LDA OUTPUT_2
ADD ADD1
STO OUTPUT_2
BRA RET_8
SET_16 STO INPUT
LDA OUTPUT_2
ADD ADD10
STO OUTPUT_2
BRA RET_16
SET_32 STO INPUT
LDA OUTPUT_2
ADD ADD100
STO OUTPUT_2
BRA RET_32
OUTPUT_1 DAT 000
OUTPUT_2 DAT 000
INPUT DAT 000
SUB64 DAT 64
SUB32 DAT 32
SUB16 DAT 16
SUB8 DAT 8
SUB4 DAT 4
SUB2 DAT 2
SUB1 DAT 1
ADD1 DAT 1
ADD10 DAT 10
ADD100 DAT 100
Running this with input 63 will output 101 101, so it's outputting it in the right format, but it is not working consistently: for input 62, this outputs two -1's
What should I do to make this work?

There are two issues in your code (the updated version at the end of your question):
OUT does not take an argument. OUT will output whatever is in the accumulator. So change:
OUT OUTPUT_2
OUT OUTPUT_1
To:
LDA OUTPUT_2
OUT
LDA OUTPUT_1
OUT
You forgot to add 10 in the case of SET_2. The following two instructions need to be added there:
ADD ADD10
STO OUTPUT_1
Here is the corrected code:
#input:63
INP
STO INPUT
SUB SUB64
BRP END
LDA INPUT
SUB SUB32
BRP SET_32
RET_32 LDA INPUT
SUB SUB16
BRP SET_16
RET_16 LDA INPUT
SUB SUB8
BRP SET_8
RET_8 LDA INPUT
SUB SUB4
BRP SET_4
RET_4 LDA INPUT
SUB SUB2
BRP SET_2
RET_2 LDA INPUT
SUB SUB1
BRP SET_1
RET_1 LDA OUTPUT_2
OUT
LDA OUTPUT_1
OUT
END HLT
SET_1 STO INPUT
LDA OUTPUT_1
ADD ADD1
STO OUTPUT_1
BRA RET_1
SET_2 STO INPUT
LDA OUTPUT_1
ADD ADD10
STO OUTPUT_1
BRA RET_2
SET_4 STO INPUT
LDA OUTPUT_1
ADD ADD100
STO OUTPUT_1
BRA RET_4
SET_8 STO INPUT
LDA OUTPUT_2
ADD ADD1
STO OUTPUT_2
BRA RET_8
SET_16 STO INPUT
LDA OUTPUT_2
ADD ADD10
STO OUTPUT_2
BRA RET_16
SET_32 STO INPUT
LDA OUTPUT_2
ADD ADD100
STO OUTPUT_2
BRA RET_32
OUTPUT_1 DAT 000
OUTPUT_2 DAT 000
INPUT DAT 000
SUB64 DAT 64
SUB32 DAT 32
SUB16 DAT 16
SUB8 DAT 8
SUB4 DAT 4
SUB2 DAT 2
SUB1 DAT 1
ADD1 DAT 1
ADD10 DAT 10
ADD100 DAT 100
<script src="https://cdn.jsdelivr.net/gh/trincot/lmc#v0.7/lmc.js"></script>
According to your specification, this outputs two decimal numbers, where the digits should be interpreted as binary. As you already noted, this can be confusing. For instance, with input 9, the output is 1 1 and not 001 001.
If you want to have every binary digit visualised, consider outputting 6 values instead of 2, and let each output be either 0 or 1. In that case the output for 9 would be 0 0 1 0 0 1.
See this answer to see how you can achieve that.

You can print the most significant bit, then multiply by 2 (left-shift 1) until you reach the bit length of the number you're trying to print. For example:
n = 01100100 # 0
SHL(n, 1)
n = 11001000 # 1
SHL(n, 1)
n = 10010000 # 1
SHL(n, 1)
n = 00100000 # 0
SHL(n, 1)
n = 01000000 # 0
SHL(n, 1)
n = 10000000 # 1
SHL(n, 1)
n = 00000000 # 0
SHL(n, 1)
n = 00000000 # 0 (number is 8-bits so we don't stop until we print 8 digits.)
----------------------
Result: '01100100'

Related

Program to sum input numbers is not working

I am trying to make a program that first takes n inputs from the user, and then calculates the sum of those numbers. Then I want the program to print if the sum is an even or an odd number.
For example if the user types in 3, he/she will have to type in 3 numbers (for example 3, 2, 5): then the program will calculate the sum of those (3 + 2 + 5) and print out if the answer (10) is an odd or an even number.
I thought I coded it right, but it doesn't run in the LMC simulator, can someone please help me finding the error?
My code:
INP
STA b
ab INP
STA a
LDA total
ADD a
STA total
STA count
LDA b
SUB one
STA b
BRZ number
BRP loop
bc LDA count
SUB two
STA count
BRZ evennumber
BRP number
LDA total
OUT
LDA space
OTC
OTC
LDA o
OTC
LDA d
OTC
OTC
LDA e
OTC
HLT
cd LDA total
OUT
LDA space
OTC
OTC
LDA p
OTC
LDA A
OTC
LDA r
OTC
HLT
a DAT 0
b DAT 0
total DAT 0
one DAT 1
two DAT 2
count DAT 0
o DAT 111
space DAT 32
d DAT 100
e DAT 101
p DAT 112
A DAT 97
r DAT 114
The main problem in your code is that the labels mismatch.
On the one hand you have defined the following labels:
ab
bc
cd
...but you have referenced the following labels:
loop
number
evennumber
As a consequence your code is not valid ... it will not parse.
The second set of labels make more sense, while "ab", "bc", "cd" are meaningless: they don't help the viewer of your code to understand what they are about. So align your code with the second set.
Also, it is not defined whether LMC is case sensitive, so using a variable name a and another A is not certain to be supported. Instead, give meaningful names. The first a is in fact the number you input and need to add to the sum, so maybe call it summand instead of a. The other A could then be called a, as it really represents the letter "a". b is also meaningless. It represents the number of inputs that are expected, so maybe call it inputs.
Taking that together, your code would look like this:
#input: 2 4 5
INP
STA inputs
loop INP
STA summand
LDA total
ADD summand
STA total
STA count
LDA inputs
SUB one
STA inputs
BRZ number
BRP loop
number LDA count
SUB two
STA count
BRZ evennumber
BRP number
LDA total
OUT
LDA space
OTC
OTC
LDA o
OTC
LDA d
OTC
OTC
LDA e
OTC
HLT
evennumber LDA total
OUT
LDA space
OTC
OTC
LDA p
OTC
LDA a
OTC
LDA r
OTC
HLT
summand DAT 0
inputs DAT 0
total DAT 0
one DAT 1
two DAT 2
count DAT 0
o DAT 111
space DAT 32
d DAT 100
e DAT 101
p DAT 112
a DAT 97
r DAT 114
<script src="https://cdn.jsdelivr.net/gh/trincot/lmc#v0.72/lmc.js"></script>

LMC: base conversion from decimal to base 9 included

I am trying to create an LMC assemble code that will allow a user to put two inputs: a decimal number and a base that the number should be converted to. The code should be able to convert any decimal number to any base between 2 and 9 included.
I am aware that the division is not available on LMC: I can use subtractions. Lets say, from 12 decimal to base 3, I am able to get 12-3-3-3-3= 4, but how can I make the code understand that the rest of the division 12/3= 4 and rest of the division is 0 and 4-3=1 but 4/3=1,... so the rest of the division is 1-3=-2 and 1/3 is 0,33... so the rest is 1. Now reading it in opposite sense, 12 decimal to base 2 is 110.
But again, even the 1-3= -2: how can I make it understand that the rest is 1?
Also, how can I make the code understand it's within which base? Do I create a long code first for detecting the base? And let's say it's going to BRA depending which base it is, then I'm not even sure if it's the same algorithm for all the bases...
I am a bit confused here, but even if someone can help me understand how to make the code for getting the remainder of the division, that's gonna help me a lot.
I'll assume that the output should be a series of single-digit numbers representing the given decimal number in the given base notation.
You could use a data-based approach: store all relevant powers of 2, 3, 4, ... and 9 in memory (mailboxes). We only need powers that are not greater than 999, so this list is limited:
Base 2: 1 2 4 8 16 32 64 128 256 512
Base 3: 1 3 9 27 81 243 729
Base 4: 1 4 16 64 256
Base 5: 1 5 25 125 625
Base 6: 1 6 36 216
Base 7: 1 7 49 343
Base 8: 1 8 64 512
Base 9: 1 9 81 729
This also has the advantage that you don't have to perform that many subtractions. Imagine the difference when the input is 999 and base 2. If you have the powers of 2 already available (up to 512), you'll only do about 9 subtractions, while if you try to do it with only 2, you'll do hundreds of subtractions...
So, given these powers, use a "pointer" in that list (through self modifying code) that will first find the range of powers that belong to the given base,
and then will take it from there to perform repeated subtractions of a power (greatest first) from the original number to determine each output digit.
With some care you can avoid that zeroes are output as long as no one has been output.
Here is how that could be coded:
#input: 12 2
INP // number
STA DECIMAL
INP // base
SUB ONE
STA BASE
LOOPBASE LDA BASE // count down to find powers of base
SUB ONE
STA BASE
BRZ DIVIDE
LOOPPOW LDA CODE1 // take next power
ADD ONE
STA CODE1 // self-modifying
LDA ONE // is it 1?
CODE1 SUB POWER
BRZ LOOPBASE // yes...
BRA LOOPPOW // no...
DIVIDE LDA CODE1
ADD ONE
STA CODE2
BRA ENTRY
LOOP STA DECIMAL
LDA DIGIT
ADD ONE
STA DIGIT
ENTRY LDA DECIMAL
CODE2 SUB POWER
BRP LOOP
LDA FIRST // do not output prepadded 0
BRZ OUTPUT // not the first digit
LDA DIGIT
BRZ SKIP
OUTPUT LDA DIGIT
OUT
SUB DIGIT
STA FIRST // no longer first digit
SKIP STA DIGIT
LDA CODE2
ADD ONE
STA CODE2 // self-modifying
STA CODE3 // self-modifying
LDA ONE // is power 1?
CODE3 SUB POWER
BRP FINISH // yes
BRA ENTRY
FINISH LDA DECIMAL
OUT
HLT
DECIMAL DAT
BASE DAT
DIGIT DAT
FIRST DAT 1
POWER DAT
DAT 512 // powers of 2
DAT 256
DAT 128
DAT 64
DAT 32
DAT 16
DAT 8
DAT 4
TWO DAT 2
ONE DAT 1
DAT 729 // powers of 3
DAT 243
DAT 81
DAT 27
DAT 9
DAT 3
DAT 1
DAT 256 // powers of 4
DAT 64
DAT 16
DAT 4
DAT 1
DAT 625 // powers of 5
DAT 125
DAT 25
DAT 5
DAT 1
DAT 216 // powers of 6
DAT 36
DAT 6
DAT 1
DAT 343 // powers of 7
DAT 49
DAT 7
DAT 1
DAT 512 // powers of 8
DAT 64
DAT 8
DAT 1
DAT 729 // powers of 9
DAT 81
DAT 9
DAT 1
<script src="https://cdn.jsdelivr.net/gh/trincot/lmc#v0.7/lmc.js"></script>
This uses almost all available mailboxes. Probably some optimisation in space use is still possible.

Algorithm for finding primitive roots from number theory

i would like to implement program for finding primitive number, for given prime number, for this one, i wrote following three program
function primitive_roots=primitive_root(p)
if ~isprime(p)
error(' p must be prime number ');
end
primitive_roots=[];
n=phi(p);
k=p-1;
for ii=2:n
if power_mod(ii,k,p)==1
primitive_roots=[primitive_roots,ii];
end
end
end
there is also power_mod function
function modresult=power_mod(a,b,c)
% this program will calculate a^b mod c
i=0;
result=1;
while i<b
result=mod(result*a,c);
i=i+1;
end
modresult=result;
end
and euler totient function
function phin=phi(n)
% this function will calculates how many coprime number exist for given n, coprime number must be
%less then n
if isprime(n) % if number is prime
phin=(n-1);
end
factors=unique(factor(n));% will printt unique prime divisors of given n
k=1; % counter
for ii=1:length(factors)
k=k*(1-1/factors(ii));
end
phin=k*n;
end
but first programs give me incorrect result, for instance
>> primitive_roots=primitive_root(19)
primitive_roots =
Columns 1 through 14
2 3 4 5 6 7 8 9 10 11 12 13 14 15
Columns 15 through 17
16 17 18
>>
while wolfram alhpa gives me different result
https://www.wolframalpha.com/widgets/view.jsp?id=ef51422db7db201ebc03c8800f41ba99
please help me
i have solved this program, for this one i introduced additional function which will calculate all possible powers and then i am checking for smallest ones
function all_powers=powers_list(a,p)
all_powers=[];
for ii=1:p-1
if power_mod(a,ii,p)==1 % finding all powers
all_powers=[all_powers,ii];
end
end
end
function primitive_roots=primitive_root(p)
if ~isprime(p)
error(' p must be prime number ');
end
primitive_roots=[];
n=phi(p);
k=p-1;
for ii=2:p-1
if power_mod(ii,k,p)==1
all_powers=powers_list(ii,p);
if (min(all_powers)==(p-1))
primitive_roots=[primitive_roots,ii];
end
end
end
>> primitive_roots=primitive_root(5)
primitive_roots =
2 3
>> primitive_roots=primitive_root(7)
primitive_roots =
3 5
>> primitive_roots=primitive_root(19)
primitive_roots =
2 3 10 13 14 15
>> primitive_roots=primitive_root(23)
primitive_roots =
5 7 10 11 14 15 17 19 20 21
>>

How can i replace some elements of a matrix by other numbers in MATLAB?

I have a matrix consists of 1000 binary elements like below in Matlab:
M =
11001100101100001011010001001100101000101110010110001‌​10000101010110010111‌​0111001...
How i can split every 3 elements and replace them By another elements. for example 000 By 000000, 110 By 000001, 001 By 00001, 100 By 0001, 101 By 001, 010 By 01, 011 By 1.
I used this method but it doesn't work. What is wrong with it?
Lookup_In = [ 000 110 001 100 101 010 011 ] ;
Lookup_Out = {'000000','000001','00001','0001','101','01','1' } ;
StrOut = repmat({'Unknown'},size(M)) ;
[tf, idx] =ismember(M, Lookup_In) ;
StrOut(tf) = Lookup_Out(idx(tf))
M here is randomly generated with 1000 binary elements:
rng(1);
M = randi([0 1], 1,1000);
fprintf('%d\n',M)
First, I zeropadded M to reach a length multiple of 3. Second, I reshaped the array in a matrix with 3 elements of each row and applied Lookup_Out.
c = mod(numel(M),3);
M = [M,zeros(1,3-c)]; %zeropadding to multiple of 3
M = reshape(M,[3,numel(M)/3])';
Lookup_In = [ 000 110 001 100 101 010 011 ] ;
Lookup_Out = {'000000','000001','00001','0001','101','01','1' } ;
StrOut = repmat({''},[1,size(M,1)]);
for r=1:size(M,1)
StrOut{r} = Lookup_Out{str2double(sprintf('%d',M(r,:))) == Lookup_In};
end

LMC to find prime numbers by user input

00: 599
01: 298
02: 738
03: 598
04: 297
05: 395
06: 730
07: 825
08: 597
09: 295
10: 717
11: 597
12: 196
13: 397
14: 592
15: 393
16: 600
17: 598
18: 902
19: 598
20: 196
21: 398
22: 594
23: 397
24: 600
25: 593
26: 196
27: 393
28: 595
29: 604
30: 593
31: 717
32: 598
33: 196
34: 398
35: 594
36: 397
37: 600
38: 000
91: 005
92: 000 // DAT 000
93: 000 // Counter
94: 002 // DAT 002
96: 001 // DAT 001 - plus 1
97: 002 // DAT 002 - dividor
98: 002 // DAT 001 - incrementor
99: 050 // DAT 10 - max
Hi guys,
I have a code to find the prime numbers between 1-100, but I'm struggling to recreate this into a program that finds only those between user input.
I had a plan to subtract one number from another, and then to divide that number by 2, 3, 4 and 5.
Do you guys have any advice how to go about this? I apologize for the lack of comments.
Disclaimer: I don't know what your original code does, as I don't read numeric codes that well. The following is from primes.lmc, which I wrote myself.
Code (heavily commented):
# Prime number finder. Prints all prime numbers between the numbers the user inputs (min, then max).
# Min
INP
SUB ONE
STA NUM
# Max
INP
STA MAX
# Main checking loop. Check each number from NUM to MAX.
TLOOP LDA NUM
# Have we done all MAX numbers?
SUB MAX
BRZ HALT
# Increment to next number to check.
LDA NUM
ADD ONE
STA NUM
# Reset divisor.
LDA ONE
STA DIV
# Check NUM for primeness by dividing all numbers from 2 to NUM - 1 into it.
DLOOP LDA DIV
# Increment to next divisor.
ADD ONE
STA DIV
# Have we checked up to the number itself?
LDA DIV
SUB NUM
BRZ PRIME
# Setup for divide function.
LDA NUM
# Modulus function: accumulator % DIV.
MODULUS SUB DIV
BRP MODULUS
ADD DIV
# Remainder is now in the accumulator. If its zero, NUM is not prime.
BRZ NPRIME
BRA DLOOP
# If its prime, print it.
PRIME LDA NUM
OUT
# Go back to the top.
NPRIME BRA TLOOP
# End of program.
HALT HLT
NUM DAT 1
DIV DAT 1
ONE DAT 1
MAX DAT
First user input is the minimum, second is the maximum (inclusive).
Running (on specter, from 13 to 23):