MIPS - IEEE binary64 (double) and signed integer multiplication - double

I have a problem with MIPS project. The task is to multiply binary64(double) number by a signed integer without using floating-point Unit. It is almost working well, but for some numbers an error occurs(ex. float-123456789123456, int - 1). By error I mean that after 7th digit my result seems to differ from the proper one. I suspect there can be a problem with transfer of some bit during the procedure(maybe in process of adding $high of mantissa2 and $low of mantissa2). I tried to correct it, but so far I have no idea how to do it. Please verify my code and correct it if possible.
.data
text1: .asciiz "Enter double: "
text2: .asciiz "Enter integer: "
text3: .asciiz "Result: "
quest: .asciiz "\nIf you want to multiply enter 1, otherwise enter 0: "
num1a: .word 0 #multiplicand and result(sign exponent and first part of mantissa)
num1b: .word 0 #second part of the multiplicand and result(remaining part of mantissa)
num2: .word 0 #integer
.text
.globl input
input:
#print "Enter double: "
la $a0, text1
li $v0, 4
syscall
# saving input double into num1
li $v0, 7
syscall
swc1 $f0, num1b
swc1 $f1, num1a
#print "Enter integer: "
la $a0, text2
li $v0, 4
syscall
# saving input int into num2
li $v0, 5
syscall
sw $v0, num2
# loading data to registers
lw $t0, num1a
lw $t1, num1b
lw $t2, num2
#########################################################sign
sign:
move $t3, $t0
andi $t3, $t3, 0x80000000 #preserve sign, zero the rest
bgez $t2, extract #if less than zero we change the final sign and negate the value of integer
xori $t3, $t3, 0x80000000 #multiply signs (if integer is negative, then the sign is equal to $s0)
neg $t2, $t2 #absolute value of int
extract:
################################################checking for zero
or $t5, $t0, $t1 #if both part of double are equal to zero we skip all the calculation
beqz $t5, result_zero
beqz $t2, result_zero
###############################sign, exponent and mantissa
move $t7, $t0
andi $t7, $t7, 0x7FF00000 #extracting exponent to $t7
move $t8, $t0
andi $t8, $t8, 0x000FFFFF #extracting first part of mantissa
ori $t8, $t8, 0x00100000 #adding prefix one to mantissa
#remaining mantissa stays in register $t1
#########################################################
multiply:
########################multiplying mantissa part 1
multu $t8, $t2 #multiply mantissa1 by integer
mflo $t8 #low part of multiplication to $t8
mfhi $s1 #high part of multiplication to $s1
########################multiplying mantissa part 2
multu $t1, $t2 #mantissa part 2 multiplication
mflo $t1 #low part to $t1
mfhi $t0 #with overflow going to $t0
########################partial accumulation
addu $t8, $t8, $t0 #adding the high part of mantissa2 to result of low part of mantissa1
bgeu $t8, $t0, skip_add #if the result is less than any element we add 1 to mantissa1 high
addiu $s1, $s1, 1
######
skip_add:
bnez $s1, shift
bltu $t8, 0x00200000, result
shift: #else we shift 3 parts of mantissa and increment the the exponent
###extracting least significant bit of high mantissa1
sll $s2, $s1, 31 #copying least significant beat of $s1 to most significant bit in $s2
sll $t9, $t8, 31 #copying least significant beat of $s8 to most significant bit in $t9
######
srl $s1, $s1, 1 #shifting right mantisa part1 high
srl $t8, $t8, 1 #shifting right mantisa part1 low
or $t8, $t8, $s2 #copying least significant bit from mantissa1- high to most significant bit of mantissa1 low
srl $t1, $t1, 1 #shifting right mantisa part2
or $t1, $t1, $t9 #copying least significant bit from mantissa1 to most significant bit of mantissa2
######
addiu $t7, $t7, 0x00100000 #increment exponent by one
######
bnez $s1, shift #if mantissa1 high is greater than zero we continue
bgeu $t8, 0x00200000, shift #if mantissa1 low exceeds final mantissa space
result:
andi $t8, $t8, 0x000FFFFF #preserve mantissa, zero the rest(cut the prefix - one)
move $t0, $t3 #copy propoer sign
or $t0, $t0, $t7 #add exponent
or $t0, $t0, $t8 #add mantissa part1
b output
result_zero:
li $t0, 0
li $t1, 0
output:
sw $t0, num1a
sw $t1, num1b
#print "Result: "
la $a0, text3
li $v0, 4
syscall
lwc1 $f12, num1b
lwc1 $f13, num1a
#print double - the result
li $v0, 3
syscall
question:
la $a0, quest #Do you want to enter new numbers or finish?
li $v0, 4
syscall
li $v0, 5 #reads the answer (integer)
syscall
beq $v0, 1, input #if input =1, continue, if 0 finish, otherwise ask again
beqz $v0, fin
b question
fin:
li $v0, 10 #exit
syscall
I think the problem might be in this section(multiply):
addu $t8, $t8, $t0 #adding the high part of mantissa2 to result of low part of mantissa1
bgeu $t8, $t0, skip_add #if the result is less than any element we add 1 to mantissa1 high
#addiu $s1, $s1, 1
######
skip_add:
bnez $s1, shift
bltu $t8, 0x00200000, result
The process of adding may cause a carry out. I tried to handle it with instruction held in comment (addiu).It means that if the result of adding two unsigned numbers is less than one of them we obtain a cary out and have to add 1 to register $s1 which holds the most significant part of mantissa.It didn't help.

In my opinion this is the correct code:
.data
text1: .asciiz "Enter double: "
text2: .asciiz "Enter integer: "
text3: .asciiz "Result: "
quest: .asciiz "\nIf you want to multiply enter 1, otherwise enter 0: "
num1a: .word 0 #multiplicand and result(sign exponent and first part of mantissa)
num1b: .word 0 #second part of the multiplicand and result(remaining part of mantissa)
num2: .word 0 #integer
.text
.globl input
input:
#print "Enter double: "
la $a0, text1
li $v0, 4
syscall
# saving input double into num1
li $v0, 7
syscall
swc1 $f0, num1b
swc1 $f1, num1a
#print "Enter integer: "
la $a0, text2
li $v0, 4
syscall
# saving input int into num2
li $v0, 5
syscall
sw $v0, num2
# loading data to registers
lw $t0, num1a
lw $t1, num1b
lw $t2, num2
#########################################################sign
sign:
move $t3, $t0
andi $t3, $t3, 0x80000000 #preserve sign, zero the rest
bgez $t2, extract #if less than zero we change the final sign and negate the value of integer
xori $t3, $t3, 0x80000000 #multiply signs (if integer is negative, then the sign is equal to $s0)
neg $t2, $t2 #absolute value of int
extract:
################################################checking for zero
or $t5, $t0, $t1 #if both part of double are equal to zero we skip all the calculation
beqz $t5, result_zero
beqz $t2, result_zero
###############################sign, exponent and mantissa
move $t7, $t0
andi $t7, $t7, 0x7FF00000 #extracting exponent to $t7
move $t8, $t0
andi $t8, $t8, 0x000FFFFF #extracting first part of mantissa
ori $t8, $t8, 0x00100000 #adding prefix one to mantissa
#remaining mantissa stays in register $t1
#########################################################
multiply:
########################multiplying mantissa part 1
multu $t8, $t2 #multiply mantissa1 by integer
mflo $t8 #low part of multiplication to $t8
mfhi $s1 #high part of multiplication to $s1
########################multiplying mantissa part 2
multu $t1, $t2 #mantissa part 2 multiplication
mflo $t1 #low part to $t1
mfhi $t0 #with overflow going to $t0
########################partial accumulation
addu $t8, $t8, $t0 #adding the high part of mantissa2 to result of low part of mantissa1
bgeu $t8, $t0, skip_add #if the result is less than any element we add 1 to mantissa1 high
addiu $s1, $s1, 1
######
skip_add:
bnez $s1, shift
bltu $t8, 0x00200000, result
shift: #else we shift 3 parts of mantissa and increment the the exponent
###extracting least significant bit of high mantissa1
sll $s2, $s1, 31 #copying least significant beat of $s1 to most significant bit in $s2
sll $t9, $t8, 31 #copying least significant beat of $s8 to most significant bit in $t9
######
srl $s1, $s1, 1 #shifting right mantisa part1 high
srl $t8, $t8, 1 #shifting right mantisa part1 low
or $t8, $t8, $s2 #copying least significant bit from mantissa1- high to most significant bit of mantissa1 low
srl $t1, $t1, 1 #shifting right mantisa part2
or $t1, $t1, $t9 #copying least significant bit from mantissa1 to most significant bit of mantissa2
######
addiu $t7, $t7, 0x00100000 #increment exponent by one
######
bnez $s1, shift #if mantissa1 high is greater than zero we continue
bgeu $t8, 0x00200000, shift #if mantissa1 low exceeds final mantissa space
result:
andi $t8, $t8, 0x000FFFFF #preserve mantissa, zero the rest(cut the prefix - one)
move $t0, $t3 #copy propoer sign
or $t0, $t0, $t7 #add exponent
or $t0, $t0, $t8 #add mantissa part1
b output
result_zero:
li $t0, 0
li $t1, 0
output:
sw $t0, num1a
sw $t1, num1b
#print "Result: "
la $a0, text3
li $v0, 4
syscall
lwc1 $f12, num1b
lwc1 $f13, num1a
#print double - the result
li $v0, 3
syscall
question:
la $a0, quest #Do you want to enter new numbers or finish?
li $v0, 4
syscall
li $v0, 5 #reads the answer (integer)
syscall
beq $v0, 1, input #if input =1, continue, if 0 finish, otherwise ask again
beqz $v0, fin
b question
fin:
li $v0, 10 #exit
syscall

Related

MIPS Assembly convert integer to ascii string using memory

Hi i have a problem with my subroutine code. here is my code. It's giving a
Runtime exception at 0x00400074: address out of range 0x000000c8 error.
The line is: sb $t2, 0($t4) - It's the second store byte.
intToa: addi $sp, $sp, -12
sw $ra ,8($sp)
sw $a0, 4($sp)
sw $a1, 0($sp)
move $t0, $a0
move $t4, $a1
bne $t0, $zero, while
li $t2, 48
sb $t2, 0($t4)
addi $t4, $t4, 1
b end
while: beq $t0, $zero, end
li $t6, 10
div $t0, $t6 # divide $t0 by 10
mfhi $t1 # $t3 = $t0%10 (last digit of $t0)
mflo $t0 # $t0 = $t0/10 (first digit of $t0)
addi $t2, $t1, 48 # store character '0' to $t1 in
sb $t2, 0($t4) # out destinationg string
addi $t4, $t4, 1 # increment our string pointer
j while # continue looping
end:
sb $zero, 0($t4) # null terminate our string
move $a1, $a0
jal reverse
lw $ra, 12($sp)
addiu $sp, $sp, 12 # put stack back in place
jr $ra

Modifying perl script to not print duplicates and extract sequences of a certain length

I want to first apologize for the biological nature of this post. I thought I should post some background first. I have a set of gene files that contain anywhere from one to five DNA sequences from different species. I used a bash shell script to perform blastn with each gene file as a query and a file of all transcriptome sequences (all_transcriptome_seq.fasta) from the five species as the subject. I now want to process these output files (and there are many) so that I can get all subject sequences that hit into one file per gene, with duplicate sequences removed (except to keep one), and ensure I'm getting the length of the sequences that actually hit the query.
Here is what the blastn output looks like for one gene file (columns: qseqid qlen sseqid slen qframe qstart qend sframe sstart send evalue bitscore pident nident length)
Acur_01000750.1_OFAS014956-RA-EXON04 248 Apil_comp17195_c0_seq1 1184 1 1 248 1 824 1072 2e-73 259 85.60 214 250
Acur_01000750.1_OFAS014956-RA-EXON04 248 Atri_comp5613_c0_seq1 1067 1 2 248 1 344 96 8e-97 337 91.16 227 249
Acur_01000750.1_OFAS014956-RA-EXON04 248 Acur_01000750.1 992 1 1 248 1 655 902 1e-133 459 100.00 248 248
Acur_01000750.1_OFAS014956-RA-EXON04 248 Btri_comp17734_c0_seq1 1001 1 1 248 1 656 905 5e-69 244 84.40 211 250
Btri_comp17734_c0_seq1_OFAS014956-RA-EXON04 250 Atri_comp5613_c0_seq1 1067 1 2 250 1 344 96 1e-60 217 82.33 205 249
Btri_comp17734_c0_seq1_OFAS014956-RA-EXON04 250 Acur_01000750.1 992 1 1 250 1 655 902 5e-69 244 84.40 211 250
Btri_comp17734_c0_seq1_OFAS014956-RA-EXON04 250 Btri_comp17734_c0_seq1 1001 1 1 250 1 656 905 1e-134 462 100.00 250 250
I've been working on a perl script that would, in short, take the sseqid column to pull out the corresponding sequences from the all_transcriptome_seq.fasta file, place these into a new file, and trim the transcripts to the sstart and send positions. Here is the script, so far:
#!/usr/bin/env perl
use warnings;
use strict;
use Data::Dumper;
############################################################################
# blastn_post-processing.pl v. 1.0 by Michael F., XXXXXX
############################################################################
my($progname) = $0;
############################################################################
# Initialize variables
############################################################################
my($jter);
my($com);
my($t1);
if ( #ARGV != 2 ) {
print "Usage:\n \$ $progname <infile> <transcriptomes>\n";
print " infile = tab-delimited blastn text file\n";
print " transcriptomes = fasta file of all transcriptomes\n";
print "exiting...\n";
exit;
}
my($infile)=$ARGV[0];
my($transcriptomes)=$ARGV[1];
############################################################################
# Read the input file
############################################################################
print "Reading the input file... ";
open (my $INF, $infile) or die "Unable to open file";
my #data = <$INF>;
print #data;
close($INF) or die "Could not close file $infile.\n";
my($nlines) = $#data + 1;
my($inlines) = $nlines - 1;
print "$nlines blastn hits read\n\n";
############################################################################
# Extract hits and place sequences into new file
############################################################################
my #temparray;
my #templine;
my($seqfname);
open ($INF, $infile) or die "Could not open file $infile for input.\n";
#temparray = <$INF>;
close($INF) or die "Could not close file $infile.\n";
$t1 = $#temparray + 1;
print "$infile\t$t1\n";
$seqfname = "$infile" . ".fasta";
if ( -e $seqfname ) {
print " --> $seqfname exists. overwriting\n";
unlink($seqfname);
}
# iterate through the individual hits
for ($jter=0; $jter<$t1; $jter++) {
(#templine) = split(/\s+/, $temparray[$jter]);
$com = "./extract_from_genome2 $transcriptomes $templine[2] $templine[8] $templine[9] $templine[2]";
# print "$com\n";
system("$com");
system("cat temp.3 >> $seqfname");
} # end for ($jter=0; $jter<$t1...
# Arguments for "extract_from_genome2"
# // argv[1] = name of genome file
# // argv[2] = gi number for contig
# // argv[3] = start of subsequence
# // argv[4] = end of subsequence
# // argv[5] = name of output sequence
Using this script, here is the output I'm getting:
>Apil_comp17195_c0_seq1
GATTCTTGCATCTGCAGTAAGACCAGAAATGCTCATTCCTATATGGCTATCTAATGGTATTATTTTTTTCTGATGTGCTGATAATTCAGACGAAGCTCTTTTAAGAGCCACAAGAACTGCATACTGCTTGTTTTTTACTCCAACAGTAGCAGCTCCCAGTTTTACAGCTTCCATTGCATATTCGACTTGGTGCAGGCGTCCCTGGGGACTCCAGACGGTAACGTCAGAATCATACTGGTTACGGAACA
>Atri_comp5613_c0_seq1
GAGAATTCTAGCATCAGCAGTGAGGCCTGAAATACTCATGCCTATGTGACTATCTAGAGGTATTATTTTTTTTTGATGAGCTGACAGTTCAGAAGAAGCTCTTTTGAGAGCTACAAGAACTGCATACTGTTTATTTTTTACTCCAACTGTTGCTGCTCCAAGCTTTACAGCCTCCATTGCATATTCCACTTGGTGTAAACGCCCCTGAGGACTCCATACCGTAACATCAGAATCATACTGATTACGGA
>Acur_01000750.1
GAATTCTAGCGTCAGCAGTGAGTCCTGAAATACTCATCCCTATGTGGCTATCTAGAGGTATTATTTTTTCTGATGGGCCGACAGTTCAGAGGATGCTCTTTTAAGAGCCACAAGAACTGCATACTCTTTATTTTTACTCCAACAGTAGCAGCTCCAAGCTTCACAGCCTCCATTGCATATTCCACCTGGTGTAAACGTCCCTGAGGGCTCCATACCGTAACATCAGAATCATACTGGTTACGGAACA
>Btri_comp17734_c0_seq1
GAATCCTTGCATCTGCAGTAAGTCCAGAAATGCTCATTCCAATATGGCTATCTAATGGTATTATTTTTTTCTGGTGAGCAGACAATTCAGATGATGCTCTTTTAAGAGCTACCAGTACTGCAAAATCATTGTTCTTCACTCCAACAGTTGCAGCACCTAATTTGACTGCCTCCATTGCATACTCCACTTGGTGCAATCTTCCCTGAGGGCTCCATACCGTAACATCAGAATCATACTGGTTACGGAACA
>Atri_comp5613_c0_seq1
GAGAATTCTAGCATCAGCAGTGAGGCCTGAAATACTCATGCCTATGTGACTATCTAGAGGTATTATTTTTTTTTGATGAGCTGACAGTTCAGAAGAAGCTCTTTTGAGAGCTACAAGAACTGCATACTGTTTATTTTTTACTCCAACTGTTGCTGCTCCAAGCTTTACAGCCTCCATTGCATATTCCACTTGGTGTAAACGCCCCTGAGGACTCCATACCGTAACATCAGAATCATACTGATTACGGA
>Acur_01000750.1
GAATTCTAGCGTCAGCAGTGAGTCCTGAAATACTCATCCCTATGTGGCTATCTAGAGGTATTATTTTTTCTGATGGGCCGACAGTTCAGAGGATGCTCTTTTAAGAGCCACAAGAACTGCATACTCTTTATTTTTACTCCAACAGTAGCAGCTCCAAGCTTCACAGCCTCCATTGCATATTCCACCTGGTGTAAACGTCCCTGAGGGCTCCATACCGTAACATCAGAATCATACTGGTTACGGAACA
>Btri_comp17734_c0_seq1
GAATCCTTGCATCTGCAGTAAGTCCAGAAATGCTCATTCCAATATGGCTATCTAATGGTATTATTTTTTTCTGGTGAGCAGACAATTCAGATGATGCTCTTTTAAGAGCTACCAGTACTGCAAAATCATTGTTCTTCACTCCAACAGTTGCAGCACCTAATTTGACTGCCTCCATTGCATACTCCACTTGGTGCAATCTTCCCTGAGGGCTCCATACCGTAACATCAGAATCATACTGGTTACGGAACA
As you can see, it's pretty close to what I'm wanting. Here are the two issues I have and cannot seem to figure out how to resolve with my script. The first is that a sequence may occur more than once in the sseqid column, and with the script in its current form, it will print out duplicates of these sequences. I only need one. How can I modify my script to not duplicate sequences (i.e., how do I only retain one but remove the other duplicates)? Expected output:
>Apil_comp17195_c0_seq1
GATTCTTGCATCTGCAGTAAGACCAGAAATGCTCATTCCTATATGGCTATCTAATGGTATTATTTTTTTCTGATGTGCTGATAATTCAGACGAAGCTCTTTTAAGAGCCACAAGAACTGCATACTGCTTGTTTTTTACTCCAACAGTAGCAGCTCCCAGTTTTACAGCTTCCATTGCATATTCGACTTGGTGCAGGCGTCCCTGGGGACTCCAGACGGTAACGTCAGAATCATACTGGTTACGGAACA
>Atri_comp5613_c0_seq1
GAGAATTCTAGCATCAGCAGTGAGGCCTGAAATACTCATGCCTATGTGACTATCTAGAGGTATTATTTTTTTTTGATGAGCTGACAGTTCAGAAGAAGCTCTTTTGAGAGCTACAAGAACTGCATACTGTTTATTTTTTACTCCAACTGTTGCTGCTCCAAGCTTTACAGCCTCCATTGCATATTCCACTTGGTGTAAACGCCCCTGAGGACTCCATACCGTAACATCAGAATCATACTGATTACGGA
>Acur_01000750.1
GAATTCTAGCGTCAGCAGTGAGTCCTGAAATACTCATCCCTATGTGGCTATCTAGAGGTATTATTTTTTCTGATGGGCCGACAGTTCAGAGGATGCTCTTTTAAGAGCCACAAGAACTGCATACTCTTTATTTTTACTCCAACAGTAGCAGCTCCAAGCTTCACAGCCTCCATTGCATATTCCACCTGGTGTAAACGTCCCTGAGGGCTCCATACCGTAACATCAGAATCATACTGGTTACGGAACA
>Btri_comp17734_c0_seq1
GAATCCTTGCATCTGCAGTAAGTCCAGAAATGCTCATTCCAATATGGCTATCTAATGGTATTATTTTTTTCTGGTGAGCAGACAATTCAGATGATGCTCTTTTAAGAGCTACCAGTACTGCAAAATCATTGTTCTTCACTCCAACAGTTGCAGCACCTAATTTGACTGCCTCCATTGCATACTCCACTTGGTGCAATCTTCCCTGAGGGCTCCATACCGTAACATCAGAATCATACTGGTTACGGAACA
The second is the script is not quite extracting the right base pairs. It's super close, off by one or two, but its not exact.
For example, take the first subject hit Apil_comp17195_c0_seq1. The sstart and send values are 824 and 1072, respectively. When I go to the all_transcriptome_seq.fasta, I get
AAGATTCTTGCATCTGCAGTAAGACCAGAAATGCTCATTCCTATATGGCTATCTAATGGTATTATTTTTTTCTGATGTGCTGATAATTCAGACGAAGCTCTTTTAAGAGCCACAAGAACTGCATACTGCTTGTTTTTTACTCCAACAGTAGCAGCTCCCAGTTTTACAGCTTCCATTGCATATTCGACTTGGTGCAGGCGTCCCTGGGGACTCCAGACGGTAACGTCAGAATCATACTGGTTACGGAAC
at that base pair range, not
GATTCTTGCATCTGCAGTAAGACCAGAAATGCTCATTCCTATATGGCTATCTAATGGTATTATTTTTTTCTGATGTGCTGATAATTCAGACGAAGCTCTTTTAAGAGCCACAAGAACTGCATACTGCTTGTTTTTTACTCCAACAGTAGCAGCTCCCAGTTTTACAGCTTCCATTGCATATTCGACTTGGTGCAGGCGTCCCTGGGGACTCCAGACGGTAACGTCAGAATCATACTGGTTACGGAACA
as outputted by my script, which is what I'm expecting. You will also notice that the sequence outputted by my script is slightly shorter than it should be. Does anyone know how I can fix these issues in my script?
Thanks, and sorry for the lengthy post!
Edit 1: a solution was offered that work for some of the infiles. However, some were causing the script to output fewer sequences than expected. Here is one such infile with 9 hits, from which I was expecting only 4 sequences.
Note: this issue has been largely resolved based on the solution provided below the answer section
Apil_comp16418_c0_seq1_OFAS000119-RA-EXON01 1587 Apil_comp16418_c0_seq1 2079 1 1 1587 1 416 2002 0.0 2931 100.00 1587 1587
Apil_comp16418_c0_seq1_OFAS000119-RA-EXON01 1587 Atri_comp13712_c0_seq1 1938 1 1 1587 1 1651 75 0.0 1221 80.73 1286 1593
Apil_comp16418_c0_seq1_OFAS000119-RA-EXON01 1587 Ctom_01003023.1 2162 1 1 1406 1 1403 1 0.0 1430 85.07 1197 1407
Atri_comp13712_c0_seq1_OFAS000119-RA-EXON01 1441 Apil_comp16418_c0_seq1 2079 1 1 1437 1 1866 430 0.0 1170 81.43 1175 1443
Atri_comp13712_c0_seq1_OFAS000119-RA-EXON01 1441 Atri_comp13712_c0_seq1 1938 1 1 1441 1 201 1641 0.0 2662 100.00 1441 1441
Atri_comp13712_c0_seq1_OFAS000119-RA-EXON01 1441 Acur_01000228.1 2415 1 1 1440 1 2231 797 0.0 1906 90.62 1305 1440
Ctom_01003023.1_OFAS000119-RA-EXON01 1289 Apil_comp16418_c0_seq1 2079 1 3 1284 1 1714 430 0.0 1351 85.69 1102 1286
Ctom_01003023.1_OFAS000119-RA-EXON01 1289 Acur_01000228.1 2415 1 1 1287 1 2084 797 0.0 1219 83.81 1082 1291
Ctom_01003023.1_OFAS000119-RA-EXON01 1289 Ctom_01003023.1 2162 1 1 1289 1 106 1394 0.0 2381 100.00 1289 1289
Edit 2: There is still an occasional output lacking fewer sequences than expected, although not as many after incorporating modifications to my script from Edit 1 suggestion (i.e., accounting for reverse direction). I cannot figure out why the script would be outputting fewer sequences in these other cases. Below the infile in question. The output is lacking Btri_comp15171_c0_seq1:
Apil_comp19456_c0_seq1_OFAS000248-RA-EXON07 2464 Apil_comp19456_c0_seq1 3549 1 1 2464 1 761 3224 0.0 4551 100.00 2464 2464
Apil_comp19456_c0_seq1_OFAS000248-RA-EXON07 2464 Btri_comp15171_c0_seq1 3766 1 1 2456 1 3046 591 0.0 1877 80.53 1985 2465
Btri_comp15171_c0_seq1_OFAS000248-RA-EXON07 2457 Apil_comp19456_c0_seq1 3549 1 1 2457 1 3214 758 0.0 1879 80.54 1986 2466
Btri_comp15171_c0_seq1_OFAS000248-RA-EXON07 2457 Atri_comp28646_c0_seq1 1403 1 1256 2454 1 1401 203 0.0 990 81.60 980 1201
Btri_comp15171_c0_seq1_OFAS000248-RA-EXON07 2457 Btri_comp15171_c0_seq1 3766 1 1 2457 1 593 3049 0.0 4538 100.00 2457 2457
You can use hash to remove duplicates
The bellow code remove duplicates depending on their subject length (keep larger subject length rows).
Just update your # iterate through the individual hits part with
# iterate through the individual hits
my %filterhash;
my $subject_length;
for ($jter=0; $jter<$t1; $jter++) {
(#templine) = split(/\s+/, $temparray[$jter]);
$subject_length = $templine[9] -$templine[8];
if(exists $filterhash{$templine[2]} ){
if($filterhash{$templine[2]} < $subject_length){
$filterhash{$templine[2]}= $subject_length;
}
}
else{
$filterhash{$templine[2]}= $subject_length;
}
}
my %printhash;
for ($jter=0; $jter<$t1; $jter++) {
(#templine) = split(/\s+/, $temparray[$jter]);
$subject_length = $templine[9] -$templine[8];
if(not exists $printhash{$templine[2]})
{
$printhash{$templine[2]}=1;
if(exists $filterhash{$templine[2]} and $filterhash{$templine[2]} == $subject_length ){
$com = "./extract_from_genome2 $transcriptomes $templine[2] $templine[8] $templine[9] $templine[2]";
# print "$com\n";
system("$com");
system("cat temp.3 >> $seqfname");
}
}
else{
if(exists $filterhash{$templine[2]} and $filterhash{$templine[2]} == $subject_length ){
$com = "./extract_from_genome2 $transcriptomes $templine[2] $templine[8] $templine[9] $templine[2]";
#print "$com\n";
system("$com");
system("cat temp.3 >> $seqfname");
}
}
} # end for ($jter=0; $jter<$t1...
Hope this will help you.
Edit part update
for negative stand you need to replace
$subject_length = $templine[9] -$templine[8];
with
if($templine[8] > $templine[9]){
$subject_length = $templine[8] -$templine[9];
}else{
$subject_length = $templine[9] -$templine[8];
}
You also need to update your extract_from_genome2 code for negative strand sequences.

Mips Assembly. Connect, read, and write

My objective is to open a socket, connect to that socket on a port, and then whenever that socket sends data to me, I want to write it to stdout.
My code works fine, but for some reason the string that is writing doesn't null terminate? I'm not so sure what the issue is and I have yet to find anything online about it.
#socket(2,1,0)
li $t7, -6
nor $t7, $t7, $zero
addi $a0, $t7, -3
addi $a1, $t7, -3
slti $a2, $zero, -1
li $v0, 4183
syscall 0x40404
sw $v0, -4($sp)
#connect(3, &addr, 16)
lw $a0, -4($sp)
li $t7, -3
nor $t7, $t7, $zero
sw $t7,-32($sp)
lui $t6,0x7a69
ori $t6,$t6,0x7a69
sw $t6, -28($sp)
lui $t5, 0x7F00
ori $t5, $t5, 0x1
sw $t5, -26($sp)
addiu $a1, $sp, -30
li $t4, -17
nor $a2, $t4, $zero
li $v0, 4170
syscall 0x40404
#read(3, addr, 50)
nex:
lw $a0, -4($sp)
addiu $a1, $sp,-64
li $a2, 50
addi $a2, $a2, -1
li $v0, 4003
syscall 0x40404
beqz $a3, next
move $a2,$v0
negu $a2,$v0
next:
blez $a2,nextt
#write(1, addr, 50)
li $a0, 1
li $v0, 4004
syscall 0x40404
j nex
nextt:
Here is the strace of me writing a\n to the socket, and it writing a\n\0\0\0\0\0\0\0\0 to stdout.
socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 3
connect(3, {sa_family=AF_INET, sin_port=htons(31337), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
read(3, "a\n", 49) = 2
write(1, "a\n\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 49a
zi3▒ݤ) = 49
As you can see, it prints out some weird characters at the end. Thanks for any help!
Notice in your strace output that your read syscall returns a value of 2 [in $v0].
Also notice that your write syscall has a length much greater than 2.
After your read syscall you have:
move $a2,$v0 # this reg has 2
negu $a2,$v0 # BUG: this changes it to -2 (0xFFFFFFFE)
The length for the write was interpreted as an unsigned number [and a very large one]
Change this to just [i.e. remove the negu]:
move $a2,$v0

MIPS float printing

I wrote this code in MIPS to calculate the sum of N-numbers with double float precision.
But when I print the result it prints 0.00000 althought I see that in memory it's the correct result.
Anyone can help me with this?
#architecture ex.2
.data
first: .asciiz "Give the number of the summation"
m1: .asciiz "Give the"
m2: .asciiz "th number."
nl: .asciiz "\n"
final: .asciiz "The sum is"
.text
main:
li $v0, 4
la $a0, first
syscall
li $v0,5
syscall
move $t1,$v0
li $v0, 4
la $a0, nl
syscall
li $t2,0
li $t0,1
mtc1.d $t2, $f2
cvt.d.w $f2, $f2
Sumin:
li $t3,0
li $v0, 4
la $a0, m1
syscall
li $v0,1
move $a0,$t0
syscall
li $v0, 4
la $a0, m2
syscall
li $v0, 4
la $a0, nl
syscall
li $v0,5
syscall
move $t3,$v0
mtc1.d $t3, $f14
cvt.d.w $f14, $f14
add.d $f2,$f2,$f14
addi $t0,$t0,1
ble $t0,$t1,Sumin
Sumexit:
li $v0, 4
la $a0, final
syscall
li $v0, 4
la $a0, nl
syscall
li $v0,2
mov.d $f12,$f2
syscall
END:jr $ra
I'd just suggest printing the double in $f12, not just the float
li $v0, 3
mov.d $f12, $f2
syscall

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):