Scalar::Util looks_like_number returning number types - perl

I notice that looks_like_number doesn't simply return true/false as I'd assumed, but actually returns a byte indicating the type of number the perl internals say is stored in the scalar. For example:
perl -e'use Scalar::Util qw/looks_like_number/; for (qw/ 1 3 10 34.23 545435.234 2343.0 234 -1423 1sddf -865178652134876152348761253487613254 sdf 24363456345636534563567253765734655 8764325hjkh435 iuh340874 &*^*& 786521948761324876132497821347816.23452345 -8762135487126387432.12435154243 0 nan inf/) { print $_, ": ", looks_like_number($_), "\n" } '
1: 1
3: 1
10: 1
34.23: 5
545435.234: 5
2343.0: 5
234: 1
-1423: 9
1sddf: 0
-865178652134876152348761253487613254: 10
sdf: 0
24363456345636534563567253765734655: 2
8764325hjkh435: 0
iuh340874: 0
&*^*&: 0
786521948761324876132497821347816.23452345: 6
-8762135487126387432.12435154243: 14
0: 1
nan: 36
inf: 20
It's not actually documented in Scalar::Util that I can find, just a mention of it returning perlapi's looks_like_number value, which also isn't in the documentation. At a glance, it appears to be:
& 1 = numeric
& 2 = 64 bit
& 4 = floating point
& 8 = negative
& 16 = infinity
& 32 = not a number
Are these masks portable and safe to use in code?

No, if they are not documented, they are subject to change. And "numeric" and "64 bit" aren't really adequate descriptions of those flags. What they do do doesn't seem particularly useful to know in Perl code.
What problem are you trying to solve?

Don't rely on undocumented behaviour, the return value is bound to Perl's internals, it can (and likely will) change in the future; it may even be different depending on which platform/architecture your script is running on!
If you want to test for NaN, infinity or negative zero, see this question.

Related

find indices according to input string operator

Lets suppose we have a vector in a function
b = 1:100
The input to the function would be a condition and threshold like ('<' , 10)
and the function returns the indices which are greater than , greater than equal to , equal to etc
A conventional way would be to make list of ifs something like
if(strcmp('>',condition))
indices = find(b > threshold)
for each operator but what if i just want to do it in one line like if the input condition is greater than >operater the find() function simply finds b greater than the threshold instead of making if for each operator
As you state in the comments, using eval is not good pratice. However, passing operators as strings will force you to do so, meaning you either have to use it, or you'll have to change the inputs to your function.
If you don't want to be forced to use eval, instead of passing a string representing an operator to the function, you'd rather want to pass it directly a handle to one of these functions :
ge : Greater or equal
gt : Greater than
le : Lower or equal
lt : Lower
The function (I'll let you do the error/wrong input checking) would be :
function out=Myfun(FunHandle,Threshold)
b=1:100;
out=find(FunHandle(b,Threshold));
end
Outputs :
Myfun(#ge,90)
Columns 1 through 8
90 91 92 93 94 95 96 97
Columns 9 through 11
98 99 100
Myfun(#lt,12)
Columns 1 through 8
1 2 3 4 5 6 7 8
Columns 9 through 11
9 10 11
use MATLAB's eval function:
eval(['indices = find(b' op num2str(t) ')'])
where op is a string, contains the specific operation ('<','>','>=' etc), and t is the threshold.
Example
b = 1:10;
op = '>';
t = 4;
eval(['indices = find(b' op num2str(t) ')'])
result:
indices =
5 6 7 8 9 10
Use eval
Example:
operator = '<';
number = 10;
threshold = 3;
condition = [num2str(number) operator num2str(thr)];
eval(condition)
Will return False, since number is not lower than thr. Try changing < for > and will evaluate True

How to do bitwise operation decently?

I'm doing analysis on binary data. Suppose I have two uint8 data values:
a = uint8(0xAB);
b = uint8(0xCD);
I want to take the lower two bits from a, and whole content from b, to make a 10 bit value. In C-style, it should be like:
(a[2:1] << 8) | b
I tried bitget:
bitget(a,2:-1:1)
But this just gave me separate [1, 1] logical type values, which is not a scalar, and cannot be used in the bitshift operation later.
My current solution is:
Make a|b (a or b):
temp1 = bitor(bitshift(uint16(a), 8), uint16(b));
Left shift six bits to get rid of the higher six bits from a:
temp2 = bitshift(temp1, 6);
Right shift six bits to get rid of lower zeros from the previous result:
temp3 = bitshift(temp2, -6);
Putting all these on one line:
result = bitshift(bitshift(bitor(bitshift(uint16(a), 8), uint16(b)), 6), -6);
This is doesn't seem efficient, right? I only want to get (a[2:1] << 8) | b, and it takes a long expression to get the value.
Please let me know if there's well-known solution for this problem.
Since you are using Octave, you can make use of bitpack and bitunpack:
octave> a = bitunpack (uint8 (0xAB))
a =
1 1 0 1 0 1 0 1
octave> B = bitunpack (uint8 (0xCD))
B =
1 0 1 1 0 0 1 1
Once you have them in this form, it's dead easy to do what you want:
octave> [B A(1:2)]
ans =
1 0 1 1 0 0 1 1 1 1
Then simply pad with zeros accordingly and pack it back into an integer:
octave> postpad ([B A(1:2)], 16, false)
ans =
1 0 1 1 0 0 1 1 1 1 0 0 0 0 0 0
octave> bitpack (ans, "uint16")
ans = 973
That or is equivalent to an addition when dealing with integers
result = bitshift(bi2de(bitget(a,1:2)),8) + b;
e.g
a = 01010111
b = 10010010
result = 00000011 100010010
= a[2]*2^9 + a[1]*2^8 + b
an alternative method could be
result = mod(a,2^x)*2^y + b;
where the x is the number of bits you want to extract from a and y is the number of bits of a and b, in your case:
result = mod(a,4)*256 + b;
an extra alternative solution close to the C solution:
result = bitor(bitshift(bitand(a,3), 8), b);
I think it is important to explain exactly what "(a[2:1] << 8) | b" is doing.
In assembly, referencing individual bits is a single operation. Assume all operations take the exact same time and "efficient" a[2:1] starts looking extremely inefficient.
The convenience statement actually does (a & 0x03).
If your compiler actually converts a uint8 to a uint16 based on how much it was shifted, this is not a 'free' operation, per se. Effectively, what your compiler will do is first clear the "memory" to the size of uint16 and then copy "a" into the location. This requires an extra step (clearing the "memory" (register)) that wouldn't normally be needed.
This means your statement actually is (uint16(a & 0x03) << 8) | uint16(b)
Now yes, because you're doing a power of two shift, you could just move a into AH, move b into AL, and AH by 0x03 and move it all out but that's a compiler optimization and not what your C code said to do.
The point is that directly translating that statement into matlab yields
bitor(bitshift(uint16(bitand(a,3)),8),uint16(b))
But, it should be noted that while it is not as TERSE as (a[2:1] << 8) | b, the number of "high level operations" is the same.
Note that all scripting languages are going to be very slow upon initiating each instruction, but will complete said instruction rapidly. The terse nature of Python isn't because "terse is better" but to create simple structures that the language can recognize so it can easily go into vectorized operations mode and start executing code very quickly.
The point here is that you have an "overhead" cost for calling bitand; but when operating on an array it will use SSE and that "overhead" is only paid once. The JIT (just in time) compiler, which optimizes script languages by reducing overhead calls and creating temporary machine code for currently executing sections of code MAY be able to recognize that the type checks for a chain of bitwise operations need only occur on the initial inputs, hence further reducing runtime.
Very high level languages are quite different (and frustrating) from high level languages such as C. You are giving up a large amount of control over code execution for ease of code production; whether matlab actually has implemented uint8 or if it is actually using a double and truncating it, you do not know. A bitwise operation on a native uint8 is extremely fast, but to convert from float to uint8, perform bitwise operation, and convert back is slow. (Historically, Matlab used doubles for everything and only rounded according to what 'type' you specified)
Even now, octave 4.0.3 has a compiled bitshift function that, for bitshift(ones('uint32'),-32) results in it wrapping back to 1. BRILLIANT! VHLL place you at the mercy of the language, it isn't about how terse or how verbose you write the code, it's how the blasted language decides to interpret it and execute machine level code. So instead of shifting, uint32(floor(ones / (2^32))) is actually FASTER and more accurate.

Is there any way to reverse the order of bits in matlab

What I am trying is getting binary value of a number e.g
de2bi(234)
Which results me in having this answer :
0 1 0 1 0 1 1 1
now what I want is that is its reverse order without changing its values like this :
11101010
i have tried bitrevorder() function but i am not having my desired answer. any help and suggestions will be appreciated.
Example:
>>de2bi(234)
ans = 0 1 0 1 0 1 1 1
>> fliplr(ans)
ans =
1 1 1 0 1 0 1 0
Use the function fliplr. It can be used to reverse the order of array.
Try using the flag 'left-msb' (according to the documentation in http://www.mathworks.com/help/comm/ref/de2bi.html)
The commands below show how to convert a decimal integer to base three without specifying the number of columns in the output matrix. They also show how to place the most significant digit on the left instead of on the right.
t = de2bi(12,[],3) % Convert 12 to base 3.
tleft = de2bi(12,[],3,'left-msb') % Significant digit on left
The output is
t =
0 1 1
tleft =
1 1 0
You just need to use the 'left-msb' option in de2bi:
>>de2bi(234, 'left-msb')
ans =
1 1 1 0 1 0 1 0
You can use a more simple command called dec2bin which produces the desired result:
>> dec2bin(234)
ans =
11101010
Here is the docs: http://www.mathworks.com/help/matlab/ref/dec2bin.html?refresh=true
While this is an old question, I needed to do the same thing for a CRC checksum and feel I should share the results.
In my case I need to reverse 16bit numbers, so, I've tried three methods:
1) Using fliplr() to reverse as per the suggestions:
uint16(bin2dec(fliplr(dec2bin(data,16))))
To test out the speed I decided to try and checksum 12MB of data. Using the above code in my CRC, it took 2000 seconds to complete! Most of this time was performing the bit reversal.
2) I then devised a more optimal solution, though not a one line code it is optimised for speed:
reverse = uint16(0);
for i=1:16
reverse = bitor(bitshift(reverse,1), uint16(bitand(forward,1)));
forward = bitshift(forward,-1);
end
Using the same CRC code, but with this used instead of (1), it took a little over 500 seconds to complete, so already it makes the CRC calculations four times faster!
3) That is still too much time for my liking, so instead I moved everything to a mex function. This allows the use of code from the bit twiddling examples that are floating around for optimum performance. I moved the whole CRC code to the mex function and used the following two other functions to do the bit reversal.
unsigned char crcBitReverse8(unsigned char forward) {
return (unsigned char)(((forward * 0x0802LU & 0x22110LU) | (forward * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16);
}
unsigned short crcBitReverse16(unsigned short forward) {
unsigned char inByte0 = (forward & 0xFF);
unsigned char inByte1 = (forward & 0xFF00) >> 8;
return (unsigned short )((crcBitReverse8(inByte0) << 8) | (crcBitReverse8(inByte1)));
}
Just for comparison, it took just 0.14 seconds to compute the CRC for the same 12MB data chunk (and there is no mistake in the calculation, the CRC checksums for all three methods match what is expected).
So basically, if you have to do this a lot of times (e.g. for CRC) I seriously suggest you write a mex function for doing the reversal. For such a simple operation, native MATLAB code is embarrassing slow.
why not use bitget?
>> bitget( 234, 8:-1:1 )
ans =
1 1 1 0 1 0 1 0

Brainfuck compare 2 numbers as greater than or less than

How can I compare two numbers with an inequality? (greater than or less than)
I want to compare single digits
For example
1 2
5 3
9 2
etc.
This is the best way to compare two numbers.Why because, if you are intelligent enough, you can use the same code in bigger programs.It's highly portable.
Assume we have two numbers a,b.
we have two blocks : if( a>=b ) and else,
Hope its enough.
0 1 0 a b 0
Make the array like this. And point to the (4) i.e. point to the a
+>+< This is for managing if a=0 and b=0
[->-[>]<<] This is a magic loop. if a is the one which
reaches 0 first (a<b),then pointer will be at(4).
Else it will be at (3)
<[-
// BLOCK (a>=b)
//You are at (2) and do whatever you want and come back to (2).
//Its a must
]
<[-<
// BLOCK(a<b)
//You are at (1) and do whatever you want and come back to (1).
//Its a must
]
It will not affect the following program code as both the code blocks will end up in (1) You can do further coding assuming that pointer will reach (1)
Please remove the documentation if you copy the code. Because code contains some valid brainfuck symbols like < . , etc.
Once you know which is the distance between the two numbers you should or decrement both of them in the same loop iteration and then check both for being zero: you will understand which one is the smaller.
Eg:
+++++ > +++ < [->-< check is first is zero, then second]
(this is just to give you a hint, you will have to take care about equal numbers and similar issues.
I was thinking about this too, and while I'm sure this isn't the best solution, at least it can answer the question of which number is larger =)
The program asks for two characters, outputs '<' if the first is smaller, '>' if it is larger, and '=' if they are equal. After outputting one char, the program halts by asking for additional input.
+>,>,<<[>-[>>>]<[>>-[>++++++++++[->++++++<]>.,]++++++++++[->++++++<]>+.,]<-[>>>]<<[>>>++++++++++[->++++++<]>++.,]<<<]
Hopefully somewhat clearer:
+ init (0) to 1
>, read (1)
>, read (2)
<<[ loop forever
>-[>>>] decrement (1) going to (4) if (1) != 0
<[ goto (0) == 1 if (1) reached 0 (otherwise goto (3))
>>-[>++++++++++[->++++++<]>.,] decrement (2) printing lessthan if larger than 0
++++++++++[->++++++<]>+., if (2) == 0 print '='
]
<-[>>>] decrement (2) going to (5) if (2) != 0
<<[ goto (0) == 1 if (2) reached 0 (otherwise goto (3))
>>>++++++++++[->++++++<]>++., print largerthan since (2) reached 0 first
]
<<< goto(0)
]
I made a solution, that gives you back a boolean and the pointer always at the same point.
This is how it looks like at the beginning:
0 0 0 a b 0 0
p
And these are the two possible outputs:
0 0 0 0 0 1 0 #true
p
0 0 0 0 0 0 0 #false
p
The code:
>>>>
[ # while cell != 0
- # decrement a
[ # if a != 0
>- # decrement b
[ # if b != 0
< # go left
<-< # undo the finally-block;
] # finally-block
<[-]> # clear a
>+> # res = 1; move to end-position
<<< # undo the finally-block
] # finally-block
>[-]>> # clear b; res = 0; move to end-position
] #
minified version:
>>>>[-[>-[< <-<]<[-]>>+><<<]>[-]>>]
Given two numbers A and B, the following code will print A if A is greater than B, B if B is greater than A and C if both are equal.
>>>>>>>>>++++++[>+++++++++++<-]>[>+>+>+<<<-]>+>->
<<<<<<<<<<<,>,<
[->-<[>]<<]>>>[>>]>>>>>>>>.
No such thing exists in BF. The > and < in BF move the pointer to the right and to the left, respectively.

How do I factor integers using Perl?

I want split integers into their factors. For example, if the total number of records is:
169 - ( 13 x 13 times)
146 - ( 73 x 2 times)
150 - ( 50 x 3 times)
175 - ( 25 x 7 times)
168 - ( 84 x 2 )
160 - ( 80 x 2 times)
When it's more than 10k - I want everything on 1000
When it's more than 100k - I want everything on 10k
In this way I want to factor the number. How to achieve this? Is there any Perl module available for these kinds of number operations?
Suppose total number of records is 10k. It should be split by 1000x10 times only; not by 100 or 10s.
I can use sqrt function. But it's not always what I am expecting. If I give the input 146, I have to get (73, 2).
You can use the same algorithms you find for other languages in Perl. There isn't any Perl special magic in the ideas. It's just the implementation, and for something like this problem, it's probably going to look very similar to the implementation in any language.
What problem are you trying to solve? Maybe we can point you at the right algorithm if we know what you are trying to do:
Why must numbers over 10,000 use the 1,000 factor? Most numbers won't have a 1,000 factor.
Do you want all the factors, or just the largest and its companion?
What do you mean that the sqrt function doesn't work as you expect? If you're following the common algorithm, you just need to iterate up to the floor of the square root to test for factors. Most integers don't have an integral square root.
If the number is not a prime you can use a factoring algorithm.
There is an example of such a function here: http://www.classhelper.org/articles/perl-by-example-factoring-numbers/factoring-numbers-with-perl.shtml
Loop through some common numbers in an acceptable range (say, 9 to 15), compute the remainder modulo your test number, and choose the lowest.
sub compute_width {
my ($total_records) = #_;
my %remainders;
for(my $width = 9; $width <= 15; $width += 1) {
my $remainder = $total_records % $width;
$remainders{$width} = $remainder;
}
my #widths = sort {
$remainders{$a} <=> $remainders{$b} ||
$a <=> $b
} keys %remainders;
return $widths[0];
}