exchange bits of an integer number in fortran - binary

suppose you have the number 2 whose binary representation is 0010
How can you exchange bits located at positions 0 and 2, and bit at 1 and 3?
so that the outcome is 1000 which is the number 8?
If I try using mvbits to exchange bits 0 and 2:
integer :: s1
s1= 2
call mvbits(s1,1,1,s1,3)
the result is the number 10
Is there an intrinsic function for such an operation?

mvbit copies the bits. It does not move the bits, where it seems you want to have the moved bits reset to zero. What you have discovered is essentially an allowed aliasing issue. You are copy 1 from 0010 to third position to get 1010. Consider the following:
program foo
implicit none
integer(1) i, j
j = 0
i = 2
call mvbits(i, 1, 1, j, 3)
write(*,'(B8.8,1X,B8.8,1X,2I3)') i, j, i, j
call mvbits(i, 1, 1, j, 3)
write(*,'(B8.8,1X,B8.8,1X,2I3)') i, j, i, j
end program foo
Edit: Forgot to mention that integer(1) is not portable. It is an 8-bit integer with gfortran.

Related

How to check efficiently if in number binary representation all next bit is different?

I need to write the function to check if the number binary representation doesn't contain duplications. For example, the function must return true if N equals to 42, because bin(42) equals to 101010, but if N equals to 45 the function must return false, because of binary representation of 45 which equals to 101101 and which contains duplicates 11.
This allows only bits that alternate between 0 and 1, plus possibly leading zeros.
One way to check this is to look at (N << 2) | N. If N is of the correct form, then this is equal to N << 2, except for bit 0 or 1. We can compensate for that as follows:
unsigned N2 = N << 2;
return (N | N2) <= (N2 | 2);

How to multiply two 8 bit numbers using shift and add operations in 8085 microprocessor?

We are supposed to multiply two 8 bit numbers using shift and add operations of 8085 microprocessor. Answer should be a 16 bit number. Use of shift and add operation is compulsory
To understand the solution you must be familiar with Rotate instructions in 8085,particularly for this solution you need to understand two things
RRC instruction rotates bits to the right and LSB can be checked from carry flag
multiplying number by 2(10 in binary) results in left shif by one bit (verify yourself)
adding number with itself is equivaent to multiplying number by 2(10 in binary) and hence also shift bits by 1 bit
#ORG 8000
//initializing operands
LXI H,7000H //data is stored in 7000H
MOV E,M
MVI D,00H
INX H
MOV A,M
MVI C,08H
LXI H, 0000H
//multiplication algorithm starts here
LOOP : RRC
JNC SKIP
DAD D
//left shift is performed by adding number with itself
//three lines just below this comment is shifting DE pair to left by 1 bit
SKIP: XCHG //exchange HL and DE pair
DAD H //Add HL with itself and store in HL
XCHG //exchange HL and DE
DCR C
JNZ LOOP
SHLD 7050H
HLT
#ORG7000
#DB 25,2A
Suppose we want to multiply two integers 27 and 23. Since 23 (10111 in binary) can be written as
2*11 + 1 = 2*(2*5 + 1) + 1 = ... = 2*(2*(2*(2*(2*0 + 1) + 0) + 1) + 1) + 1. Thus, x * 23 can be expressed as: 2*(2*(2*(2*(2*0 + x) + 0) + x) + x) + x. Observe that the addend terms in each step follows the binary representation of 23 (1, 0, 1, 1, 1). With this observation, we can write the following pseudocode to perform the multiplication x * y using shift and add operations.
let x be the first operand and y be the second one
set sum = 0
repeat
set sum = sum * 2
left shift y by one place
if the overflow bit after the shift is set then
set sum = sum + x
until y ≠ 0
output the sum as the result of x*y
Let x=27 (0x1B) and y=23 (0x17) be two 8-bit intergers, the follwing microprogram performs the required multiplication. As the multiplication may require 16 bits to store the result we use the HL register pair for the calculation.
LXI D,001BH ; DE <- 27(x)
MVI A,17H ; A <- 23(y)
LXI H,0000H ; HL <- 0(sum)
LOOP: DAD H ; sum <- sum*2
STC
CMC ; clear the carry flag before rotate
RAL ; y <- y<<1
JNC SKIP ; if overflow bit from y was not set
DAD D ; sum <- sum + x
SKIP: ORA A ; to update the zero flag
JNZ LOOP
HLT
The result, 27*23 = 621 (0x026D), is available in the HL register pair.

Count number of odd digits in Integer Haskell

I'm trying to make program which counts the number of odd digits in integer using Haskell. I have ran into problem with checking longer integers. My program looks like this at the moment:
oddDigits:: Integer -> Int
x = 0
oddDigits i
| i `elem` [1,3,5,7,9] = x + 1
| otherwise = x + 0
If my integer is for example 22334455 my program should return value 4, because there are 4 odd digits in that integer. How can I check all numbers in that integer? Currently it only checks first digit and returns 1 or 0. I'm still pretty new to haskell.
You can first convert the integer 22334455 to a list "22334455". Then find all the elements satisfying the requirement.
import Data.List(intersect)
oddDigits = length . (`intersect` "13579") . show
In order to solve such problems, you typically split this up into smaller problems. A typical pipeline would be:
split the number in a list of digits;
filter the digits that are odd; and
count the length of the resulting list.
You thus can here implement/use helper functions. For example we can generate a list of digits with:
digits' :: Integral i => i -> [i]
digits' 0 = []
digits' n = r : digits' q
where (q, r) = quotRem n 10
Here the digits will be produced in reverse order, but since that does not influences the number of digits, that is not a problem. I leave the other helper functions as an exercise.
Here's an efficient way to do that:
oddDigits :: Integer -> Int
oddDigits = go 0
where
go :: Int -> Integer -> Int
go s 0 = s
go s n = s `seq` go (s + fromInteger r `mod` 2) q
where (q, r) = n `quotRem` 10
This is tail-recursive, doesn't accumulate thunks, and doesn't build unnecessary lists or other structures that will need to be garbage collected. It also handles negative numbers correctly.

MIPS Programming instruction count issue

I wrote this mips code to find the gcf but I am confused on getting the number of instructions executed for this code. I need to find a linear function as a function of number of times the remainder must be calculated before an answer. i tried running this code using Single step with Qtspim but not sure on how to proceed.
gcf:
addiu $sp,$sp,-4 # adjust the stack for an item
sw $ra,0($sp) # save return address
rem $t4,$a0,$a1 # r = a % b
beq $t4,$zero,L1 # if(r==0) go to L1
add $a0,$zero,$a1 # a = b
add $a1,$zero,$t4 # b = r
jr gcf
L1:
add $v0,$zero,$a1 # return b
addiu $sp,$sp,4 # pop 2 items
jr $ra # return to caller
There is absolutely nothing new to show here, the algorithm you just implemented is the Euclidean algorithm and it is well known in the literature1.
I will nonetheless write an informal analysis here as link only questions are evil.
First lets rewrite the code in an high level formulation:
unsigned int gcd(unsigned int a, unsigned int b)
{
if (a % b == 0)
return b;
return gcd(b, a % b);
}
The choice of unsigned int vs int was dicated by the MIPS ISA that makes rem undefined for negative operands.
Out goal is to find a function T(a, b) that gives the number of step the algorithm requires to compute the GDC of a and b.
Since a direct approach leads to nothing, we try by inverting the problem.
What pairs (a, b) makes T(a, b) = 1, in other words what pairs make gcd(a, b) terminates in one step?
We clearly must have that a % b = 0, which means that a must be a multiple of b.
There are actually an (countable) infinite number of pairs, we can limit our selves to pairs with the smallest, a and b2.
To recap, to have T(a, b) = 1 we need a = nb and we pick the pair (a, b) = (1, 1).
Now, given a pair (c, d) that requires N steps, how do we find a new pair (a, b) such that T(a, b) = T(c, d) + 1?
Since gcd(a, b) must take one step further then gcd(c, d) and since starting from gcd(a, b) the next step is gcd(b, a % b) we must have:
c = b => b = c
d = a % b => d = a % c => a = c + d
The step d = a % c => a = c + d comes from the minimality of a, we need the smallest a that when divided by c gives d, so we can take a = c + d since (c + d) % c = c % c d % c = 0 + d = d.
For d % c = d to be true we need that d < c.
Our base pair was (1, 1) which doesn't satisfy this hypothesis, luckily we can take (2, 1) as the base pair (convince your self that T(2, 1) = 1).
Then we have:
gcd(3, 2) = gcd(2, 1) = 1
T(3, 2) = 1 + T(2, 1) = 1 + 1 = 2
gcd(5, 3) = gcd(3, 2) = 1
T(5, 3) = 1 + T(3, 2) = 1 + 2 = 3
gcd(8, 5) = gcd(5, 3) = 1
T(8, 5) = 1 + T(5, 3) = 1 + 3 = 4
...
If we look at the pair (2, 1), (3, 2), (5, 3), (8, 5), ... we see that the n-th pair (starting from 1) is made by the number (Fn+1, Fn).
Where Fn is the n-th Fibonacci number.
We than have:
T(Fn+1, Fn) = n
Regarding Fibonacci number we know that Fn ∝ φn.
We are now going to use all the trickery of asymptotic analysis, particularly in the limit of the big-O notation considering φn or φn + 1 is the same.
Also we won't use the big-O symbol explicitly, we rather assume that each equality is true in the limit. This is an abuse, but makes the analysis more compact.
We can assume without loss of generality that N is an upper bound for both number in the pair and that it is proportional to φn.
We have N ∝ φn that gives logφ N = n, this ca be rewritten as log(N)/log(φ) = n (where logs are in base 10 and log(φ) can be taken to be 1/5).
Thus we finally have 5logN = n or written in reverse order
n = 5 logN
Where n is the number of step taken by gcd(a, b) where 0 < b < a < N.
We can further show that if a = ng and b = mg with n, m coprimes, than T(a, b) = T(n, m) thus the restriction of taking the minimal pairs is not bounding.
1 In the eventuality that you rediscovered such algorithm, I strongly advice against continue with reading this answer. You surely have a sharp mind that would benefit the most from a challenge than from an answer.
2 We'll later see that this won't give rise to a loss of generality.

Is ones complement distributive?

I know it's associative and commutative:
That is,
(~x1 + ~x2) + ~x3 = ~x1 + (~x2 + ~x3)
and
~x1 + ~x2 = ~x2 + ~x1
However, for the cases I tried, it doesn't seem to be distributive, i.e,
~x1 + ~x2 != ~(x1 + x2)
Is this true? Is there a proof?
I have C code as follows:
int n1 = 5;
int n2 = 3;
result = ~n1 + ~n2 == ~(n1 + n2);
int calc = ~n1;
int calc0 = ~n2;
int calc1 = ~n1 + ~n2;
int calc2 = ~(n1 + n2);
printf("(Part B: n1 is %d, n2 is %d\n", n1, n2);
printf("Part B: (calc is: %d and calc0 is: %d\n", calc, calc0);
printf("Part B: (calc1 is: %d and calc2 is: %d\n", calc1, calc2);
printf("Part B: (~%d + ~%d) == ~(%d + %d) evaluates to %d\n", n1, n2, n1, n2, result);
Which gives the following output:
Part B: (n1 is 5, n2 is 3
Part B: (calc is: -6 and calc0 is: -4
Part B: (calc1 is: -10 and calc2 is: -9
Part B: (~5 + ~3) == ~(5 + 3) evaluates to 0
[I know this is really old, but I had the same question, and since the top answers were contradictory...]
The one's compliment is indeed distributive over addition. The problem in your code (and Kaganar's kind but incorrect answer) is that you are dropping the carry bits -- you can do that in two-s compliment, but not in one's compliment.
Whatever you use to store the sum needs more memory space than what you are summing so that you don't drop your carry bits. Then fold the carry bits back into the number of bits you are using to store your operands to get the proper sum. This is called an "end-around carry" in one's compliment arithmetic.
From Wikipedia article ( https://en.wikipedia.org/wiki/Signed_number_representations#Ones'_complement ):
To add two numbers represented in this system, one does a conventional binary addition, but it is then necessary to do an end-around carry: that is, add any resulting carry back into the resulting sum. To see why this is necessary, consider the following example showing the case of the addition of −1 (11111110) to +2 (00000010):
binary decimal
11111110 –1
+ 00000010 +2
─────────── ──
1 00000000 0 ← Not the correct answer
1 +1 ← Add carry
─────────── ──
00000001 1 ← Correct answer
In the previous example, the first binary addition gives 00000000, which is incorrect. The correct result (00000001) only appears when the carry is added back in.
I changed your code a bit to make it easier to do the math myself for a sanity check and tested. It may require a bit more thought using signed integer datatypes or to account for end-around borrowing instead of carrying. I didn't go that far since my application is all about checksums (i.e. unsigned, and addition only).
unsigned short n1 = 5; //using 16-bit unsigned integers
unsigned short n2 = 3;
unsigned long oc_added = (unsigned short)~n1 + (unsigned short)~n2; //32bit
/* Fold the carry bits into 16 bits */
while (oc_added >> 16)
oc_added = (oc_added & 0xffff) + (oc_added >> 16);
unsigned long oc_sum = ~(n1 + n2); //oc_sum has 32 bits (room for carry)
/* Fold the carry bits into 16 bits */
while (oc_sum >> 16)
oc_sum = (oc_sum & 0xffff) + (oc_sum >> 16);
int result = oc_added == oc_sum;
unsigned short calc = ~n1;
unsigned short calc0 = ~n2;
unsigned short calc1 = ~n1 + ~n2; //loses a carry bit
unsigned short calc2 = ~(n1 + n2);
printf("(Part B: n1 is %d, n2 is %d\n", n1, n2);
printf("Part B: (calc is: %d and calc0 is: %d\n", calc, calc0);
printf("Part B: (calc1 is: %d and calc2 is: %d\n", calc1, calc2);
printf("Part B: (~%d + ~%d) == ~(%d + %d) evaluates to %d\n", n1, n2, n1, n2, result);
Check out the Wikiepdia article on Ones' complement. Addition in one's complement has end-carry around where you must add the overflow bit to the lowest bit.
Since ~ (NOT) is equivalent to - (NEGATE) in ones' complement, we can re-write it as:
-x1 + -x2 = -(x1 + x2)
which is correct.
One's compliment is used to represent negative and positive numbers in fixed-width registers. To distribute over addition the following must apply: ~a + ~b = ~(a + b). The OP states + represents adding 'two binary numbers'. This itself is vague, however if we take it to mean adding unsigned binary numbers, then no, one's compliment is not distributive.
Note that there are two zeroes in one's compliment: all bits are ones or all bits are zeroes.
Check to see that ~0 + ~0 != ~(0 + 0):
~0 is zero. However, ~0 is represented by all ones. Adding it to itself is doubling it -- the same as a left shift -- and thus introduces a zero in the right hand digit. But that is no longer one of the two zeroes.
However, 0 is zero, and 0 + 0 is also zero, and thus so is ~(0 + 0). But the left side isn't zero, so to distribution does not hold.
On the other hand... Consider two's compliment: flip all bits and add one. If care is taken to treat negatives in one's compliment specially, then that version of 'binary addition' is similar to two's compliment and is distributive as you end up with a familiar quotient ring just like in two's compliment.
The aforementioned Wikipedia article has more details on handling addition to allow for expected arithmetic behavior.
From De Morgan's laws:
~(x1 + x2) = ~x1 * ~x2