Author |
Topic |
|
corei5
18 Posts |
Posted - 05/10/2018 : 5:56:58 PM
|
Origin Ver. and Service Release (Select Help-->About Origin): b9.5.5.409 Operating System: Win 10
I'm trying to perform "bitand" on a 32-bit integer, but it looks like "bitand" works only up to a 31-bit integer.
For example if I run the calculation:
bitand(2147483647,2147483647)
I get the result 2147483647.
But if I run the calculation:
bitand (2147483648, 2147483648)
I get the result 2147483647.
Does anyone have a solution to perform a bitand on a 32-bit (or greater) integer and is this really a limitation in Origin or am I doing something wrong?
Thanks
Fred |
|
Castiel
343 Posts |
Posted - 05/10/2018 : 10:12:59 PM
|
quote: Originally posted by corei5
Origin Ver. and Service Release (Select Help-->About Origin): b9.5.5.409 Operating System: Win 10
I'm trying to perform "bitand" on a 32-bit integer, but it looks like "bitand" works only up to a 31-bit integer.
For example if I run the calculation:
bitand(2147483647,2147483647)
I get the result 2147483647.
But if I run the calculation:
bitand (2147483648, 2147483648)
I get the result 2147483647.
Does anyone have a solution to perform a bitand on a 32-bit (or greater) integer and is this really a limitation in Origin or am I doing something wrong?
Thanks
Fred
2,147,483,648 exceeds the range of 32-bit integer, which is from −2,147,483,648 to 2,147,483,647.
Have a try of "&" for 32-bit unsigned integers:
2147483648 & 2147483648 =
#####
#### _\_ ________
##=-[.].]| \
#( _\ | |------|
# __| | ||||||||
\ _/ | ||||||||
.--'--'-. | | ____ |
/ __ `|__|[o__o]|
_(____nm_______ /____\____
|
|
|
corei5
18 Posts |
Posted - 05/10/2018 : 11:47:56 PM
|
That worked perfectly. Thank you!
Any idea how to perform a bitand for 33-bit (and greater) unsigned integers?
Fred |
|
|
Castiel
343 Posts |
Posted - 05/11/2018 : 02:52:02 AM
|
quote: Originally posted by corei5
That worked perfectly. Thank you!
Any idea how to perform a bitand for 33-bit (and greater) unsigned integers?
Fred
In what case do you want to perform a bitand for large integers?
#####
#### _\_ ________
##=-[.].]| \
#( _\ | |------|
# __| | ||||||||
\ _/ | ||||||||
.--'--'-. | | ____ |
/ __ `|__|[o__o]|
_(____nm_______ /____\____
|
|
|
corei5
18 Posts |
Posted - 05/11/2018 : 12:57:29 PM
|
I'm looking at embedded controllers that output variables to indicate how the control system is working. For example, the output variable I'm interested in indicates the on/off status of various sub-systems. The output variable is a 32-bit integer (where each individual bit is the on/off status of subsystem 1 through subsystem 32).
I'm anticipating a case where a 33-bit integer (or greater) will be used by some embedded controllers to indicate the on/off status of 33 (or more) total subsystems.
|
|
|
Hideo Fujii
USA
1582 Posts |
Posted - 05/14/2018 : 4:12:21 PM
|
Hi Fred,
As a double has 52 bits as fraction, if you are okay to sacrifice the speed, you can use the following double version of and, dbitand:////////////////////////////////////////////////////////////////////////////
function double rs1(double dv) { //right shift 1 bit
string tt$=format(dv,*51)$;
if(right(tt$,1)$=="1" || right(tt$,1)$=="3" || right(tt$,1)$=="5" || right(tt$,1)$=="7" || right(tt$,1)$=="9")
return (dv-1)/2;
else return dv/2;
}
function double lb1(double dv) { //lowest bit
return dv-rs1(dv)*2;
}
function string sbits(double dv, int nbits) { //convert fraction part to string
string bstr$="";
string zfill$="000000000000000000000000000000000000000000000000000";
for(;dv>0;) {
if(lb1(dv)==0) bstr$="0"+bstr$; else bstr$="1"+bstr$;
dv=rs1(dv);
}
return right(zfill$+bstr$,nbits)$;
}
function double dnthbit(double dv, int ibit) {
double dmax=51;
return value(mid(sbits(dv,dmax)$,dmax-ibit+1,1)$);
}
function double sbits2d(string sbits$) {
double tmp=0;
lsbits=len(sbits$);
double pos1=lsbits-find(sbits$,"1");
loop(ii,0,pos1) {if(mid(sbits$,lsbits-ii,1)$=="1") tmp=tmp+2^ii;}
return tmp;
}
function double dbitand(double dv1, double dv2) {
double dmax=51;
string sbits1$=sbits(dv1,dmax)$;
string sbits2$=sbits(dv2,dmax)$;
string tmpstr$="";
loop(ii,1,dmax) {tmpstr$=tmpstr$+text(value(mid(sbits1$,ii,1)$)&value(mid(sbits2$,ii,1)$))$;}
return sbits2d(tmpstr$);
}
//////////////////////////////////////////////////////////////////////////// I got the following result:dbitand(2147483648,2147483648)=2147483648 Maybe people can provide faster versions.
--Hideo Fujii OriginLab |
Edited by - Hideo Fujii on 05/16/2018 3:36:50 PM |
|
|
cpyang
USA
1406 Posts |
Posted - 05/15/2018 : 2:51:30 PM
|
We will see if we can improve this on a future version.
I added to our JIRA system as ORG-17751
CP
|
|
|
Hideo Fujii
USA
1582 Posts |
Posted - 05/16/2018 : 3:43:34 PM
|
Hi Fred,
I have fixed the problem of the previous code as shown in GREEN. The problem was that int() function also work only within 32 bits, and I had to avoid using it.
--Hideo Fujii OriginLab |
|
|
corei5
18 Posts |
Posted - 05/18/2018 : 7:15:58 PM
|
Thanks!! |
|
|
Hideo Fujii
USA
1582 Posts |
Posted - 06/07/2018 : 5:19:06 PM
|
Hi corei5,
Here is an appendical comment - what if you need to handle more than 52 bits... One possible way may be to handle multiple data objects, if you don't mind to manage juggling them. Another way may be to use a string as a container of bits (let us call 'sbits' for now). Origin's string can hold 8191 characters, that are 8191 sbits. You can construct bitwise functions on them easily, for example in Origin C like:
#define MAXSTRLEN 8191 //maximum length of a string in Origin
/////////////////////////////////////////////
string sbit0s(int n){ //returns n 0's
// sbit0s(65)$=;
// 00000000000000000000000000000000000000000000000000000000000000000
int ii;
if(n>MAXSTRLEN) return "";
string str="00000000000000000000"; //20 sbits
for(ii=1; ii<4; ii++)
str=str+str+str+str+str+str+str+str; //produce 10240 sbits
return str.Mid(0,n);
}
string sbitAnd(string sb1, string sb2) { //AND operation on two sbit strings
// sbitAnd("10101010", "11100")$=;
// 00001000
string str="";
int lensb1=sb1.GetLength(), lensb2=sb2.GetLength();
if(lensb1<lensb2) {string tmpstr=sb1; sb1=sb2; sb2=tmpstr; int tmplen=lensb1; lensb1=lensb2; lensb2=tmplen;}
sb1=sb1.Right(lensb2);
for(int ii=0; ii<lensb2; ii++)
if(sb1.Mid(ii,1)=="1" && sb2.Mid(ii,1)=="1") str=str+"1"; else str=str+"0";
return sbit0s(lensb1-lensb2)+str;
}
string sbitSet(string sb, int n, int v) { //Set n-th sbit to v(0 or 1)
// sbitSet("0110001010",3,1)$=;
// 0110001110
int lensb=sb.GetLength();
string sv;
if(v==0) sv="0";
else if(v==1) sv="1";
else return "";
if(n>lensb) return sv+sbit0s(n-lensb-1)+sb;
else return sb.Mid(0,lensb-n)+sv+sb.Mid(lensb-n+1,n);
}
int sbitTest(string sb, int n) { //If n-th sbit is 1, then TRUE(1), otherwise FALSE(0)
// if(sbitTest("000000001000",4)) type TRUE; else type FALSE;
// TRUE
int lensb=sb.GetLength();
if(n>lensb) return 0;
else if(sb.Mid(lensb-n,1)=="1") return 1; else return 0;
}
////////////////////////////////////////////////////////// Additional advantage of this approach may be not only able to indicate a binary level, but multiple levels, say 0--15 levels by a hexdigit.
--Hideo Fujii OriginLab |
|
|
Hideo Fujii
USA
1582 Posts |
Posted - 06/13/2018 : 5:40:24 PM
|
Hi corei5,
In the recently released Origin 2019 Beta version, the Hexadecimal display format of the numerical data (in Double) is supported. That is, you will be able to directly apply a bit-wise operator like BitAnd beyond 32-bit. Please contact us (tech@originlab.com) if you are interested in trying this Beta version.
--Hideo Fujii OriginLab |
Edited by - Hideo Fujii on 06/13/2018 5:41:33 PM |
|
|
|
Topic |
|
|
|