Round Register up to multiple of 8 - x86-64

I am trying to round a 64bit register up so it's a multiple of 8. So it ends with either an 8 or 0.
Is there an efficient way to do this, I am currently doing it as follows:
xor r9, r9
_R:
add r9, 08h
cmp r8, r9
ja _R
mov r8, r9

To round a value up to a multiple of eight requires two statements and no loops:
add r9, 7
and r9, 0fffffffffffffff8H
The first moves any value that's not already a multiple of eight into the "next highest section". The second rounds that down to a multiple of eight. So you'll get results like:
orig add and
0 7 0
1 8 8
: : :
7 14 8
8 15 8
9 16 16
Note that, if you want to round up even those numbers which are already multiples of eight (e.g., 8 -> 16), just add eight instead of seven.

Related

the usage of offset for storing (stw) in powerpc assembly

long long int i=57745158985; #the C code
0000000000100004: li r7,13
0000000000100008: lis r8,29153
000000000010000c: ori r8,r8,0x3349
0000000000100010: stw r7,24(rsp)
0000000000100014: stw r8,28(rsp)
0000000000100018: lfd fp0,24(rsp)
000000000010001c: stfd fp0,8(rsp)
Can anyone explain the part of after the ori instruction? Thanks in advance.
It looks like this is on a 32-bit big endian machine. I will assume i is a local variable.
Starting with these instructions...
li r7,13
lis r8,29153
ori r8,r8,0x3349
After these instructions:
r7 contains 13
r8 contains ((29153 << 16) | 0x3349)
The required value for i is 57745158985, which is equal to
(13<<32) | ((29153 << 16) | 0x3349)
Clearly this value is too big to fit in a single 32-bit register.
The next instructions are where the 64-bit local variable i is "created" on the stack.
stw r7,24(rsp)
stw r8,28(rsp)
rsp is the stack pointer for the function.
Here i is being initialized to it's initial value of 57745158985.
stw r7,24(rsp) stores the four bytes of r7 starting at an offset of 24 bytes into the stack.
stw r8,28(rsp) stores the four bytes r8 starting at an offset of 28 bytes into the stack.
So i is the 8 bytes starting from an offset of 24 on the stack.
As this is a big-endian architecture the most significant bytes are placed first in memory.
Placing the value of r7 at lower address performs acts like the (13<<32) when considering the 8 bytes as one long long int.
These next instructions load the value of i into a floating point register and save it at a different location on the stack.
lfd fp0,24(rsp)
stfd fp0,8(rsp)
These 3 are loading up two 32 bit literal values into GPRs r7 and r8
0000000000100004: li r7,13
0000000000100008: lis r8,29153
000000000010000c: ori r8,r8,0x3349
These two are storing the two 32 bit values out consecutive 32 bit memory locations pointed to by rsp (which is the stack pointer == r1) + 24
0000000000100010: stw r7,24(rsp)
0000000000100014: stw r8,28(rsp)
This is a 64 bit load from the same location (ie rsp + 24) into floating point register 0 (ie fp0). (you can't move GPRs to FPR directly on this processor, so you go via memory)
0000000000100018: lfd fp0,24(rsp)
This is storing the same 64 bit FPR0 out to a different offset from the stack point.
000000000010001c: stfd fp0,8(rsp)

Adding MSB and LSB to get 0-511

I'm trying to get 9 bits out of a MIDI controller. According to the manual, the position of a fader on the MIDI controller is sent out as 9 bits, which would make it 0-511.
In my software (Max/MSP), the MSB comes in as only 7 bits (0-127) and the LSB flickers between 0/64 generally and occasionally I see 32 and 96.
I think I need to do some bit shifting and then add the MSB and LSB somehow to get the full 0-511.
Any ideas?
from the manual:
MSB=0 M M M M M M M
LSB=0 L L 0 0 0 0 0
The position is sent out with 9 bits of accuracy. The 2 least significant bits can be ignored for 7-bit accuracy.
MIDI data values can only use 7 bits, so it's spread the most significant 7 to that first CC data byte, and the last couple bits to the next CC data byte.
If you convert the least significant bits, possible values are 0, 32, 64, and 96 as you have seen. But of course, those aren't meant to be taken out of context.
Assemble your bits like this:
0000 000M MMMM MMLL

How do I set random numbers that fall in a range in kdb+?

In Kdb+, how do I use the "roll" function to make the random numbers generated fall within a range that doesn't start with 0? For example what if I wanted the range to be within 2-10 instead of 0-10?
What do I have to add to the code to make it fall into a range instead of the default 0-x? I have tried and looked for every method but can't seem to find one.
You could also just roll from 0-8 then add two. This doesn't require a list to be pre-generated
q)2+5?9
10 2 7 10 7
Assuming you want 2-10 inclusive
// quick and simple method
q)10?2+til 8
6 2 4 3 4 3 4 5 4 7
// or function (x)=num to be dealt, (y) start range, (z) end range
q)f:{x?y+til 1+z-y}
q)f[10;10;20]
12 17 10 11 19 12 11 18 18 11
If you supply a list in the right hand argument then you will get a random value from that list. To roll for a random range from 2-10 you can use til to generate the range:
q)2+til 9
2 3 4 5 6 7 8 9 10
q)1?2+til 9
,6
You can even supply a general list to randomly draw from:
q)3?(`abc;2 3f;10;20;30;"text")
2 3f
`abc
"text"
Simple math function for random number generator is:
(rand() mod (1+max- min)) + min
q) f:{x+rand[0] mod 1+y-x}
q) f[5;10]
q) 7
Update: I failed to notice that you wanted to generate couple of random numbers in the range. You could easily modify above function for that:
q) f:{x+(z?0) mod 1+y-x}
q) f[2;10;4]
q) 6 4 7 2

Convert from base10 to base8

Converting from base-10 to base-8 is a little trickier,
but still straightforward. We basically have to reverse the process from above. Let's start with an example: 150 of base-10.
We first find the largest power of 8 that is smaller than our number. Here, this is 82 or 64 (83 is 512). We count how many groups of 64 we can take from 150. This is 2, so the first digit in our base-8 number is 2. We have now accounted for 128 out of 150, so we have 22 left over.
The largest power of 8 that is smaller than 22 is 81 (that is, 8). How many groups of 8 can we take from 22? Two groups again, and thus our second digit is 2.
Finally, we are left with 6, and can obviously take 6 groups of one from this, our final digit. We end up with 226 of base-8.
In fact, we can make this process a touch clearer with math. Here are the steps:
150/82 = 2 remainder 22
22/81 = 2 remainder 6
6/80 = 6
Our final answer is then all of our non-remainder digits, or 226.
my question is same way if we want 65 of base-10 to convert to base-8 what happens ?
any help is appreciated..thanks in advance

MATLAB: Step through iterations of a vector

all.
I have a 15 element array = [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15];.
I was wondering if there was a command such that it would step through iterations of the array without repeating itself. In other words, since there is a chance that randperm() will create the same matrix twice, I want to step through each permutation only once and perform a calculation.
I concede that there are factorial(15) permutations, but for my purposes, these two vectors (and similar) are identical and don't need to be counted twice:
[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15]
[15 14 13 12 11 10 9 8 7 6 5 4 3 2 1]
Thus, is there any way to step through this?
Thanks.
I think what you are looking for is perms. randperm returns a single random permutation, you want all the permutations.
So use
my_permuations = perms([1:15]);
If forward-backward is the same as backward-foward then you can use the top half of the list only...
my_permutation_to_use = my_permutations(1:length(my_permutations)/2, :);
You may compare all permutations, but this would require to store all past permutations. Instead a local decision is better. I recommend this simple rule:
A permutation is valid, if the first element is smaller than the last element.
A permutation is redundant, if the first element is larger than the last element.
For small sizes, this could simply be done with this code:
%generate all permutations
x=perms(1:10)
%select only the valid lines, remove all redundant lines
x(x(:,1)<x(:,end),:)
Remains the problem, that generating x for 1:15 breaks all memory limits and would require about 100h.