J'utilise JMP10 et remarque pour Hex To Number (hextext), hextext est limité à 31 bits. Y a-t-il un moyen de contourner ceci?
Hex vers nombre ("7FFFFFFF") = 2147483647, Hex vers nombre(" 80000000 ") = -2147483648.
J'ai besoin de multiplier deux chaînes hexadécimales (chacune pouvant contenir jusqu'à 4 octets) et dans le nombre résultant, en fonction de l'état du bit MSB, extraire Bits[29:14] ou Bits [27:12]. Cela peut-il être fait en JSL?
JMP 10 présente certaines limitations ; il semble que les chaînes de chiffres hexadécimaux dans JMP 10 doivent être un nombre pair de caractères hexadécimaux. La fonction ci-dessus semble fonctionner dans JMP 10 (faites vos propres tests !), mais le faisceau de test utilise des fonctionnalités de versions ultérieures.
JMP utilise virgule flottante 64 bits pour représenter les numéros JSL ; le nombre de bits de fraction disponibles n'est que de 52 ou 53. Si vous multipliez deux entiers de 32 bits, vous aurez peut-être besoin de 64 bits pour représenter la réponse. Si la réponse est supérieure à 52 ou 53 bits, vous perdrez en précision sur les bits de poids faible... peut-être que 11 ou 12 bits peuvent être perdus.
Voici quelques JSL qui pourraient vous aider.
// crude unsigned hex multiply, poorly tested, no idea what negative numbers are
// do your own testing to make sure this meets your needs
// expects upper case hex ABCDEF, not abcdef
hextonum = [
"0"=>0,"1"=>1,"2"=>2,"3"=>3,
"4"=>4,"5"=>5,"6"=>6,"7"=>7,
"8"=>8,"9"=>9,"A"=>10,"B"=>11,
"C"=>12,"D"=>13,"E"=>14,"F"=>15
];
numtohex = Associative Array( hextonum << getvalues, hextonum << getkeys );
hexmultiply = Function( {a, b}, // "123AE" and "EF012" for example
{// locals
ia, na=length(a),amat = J( na, 1, 0 ), ib,nb=length(b), bmat = J( nb, 1, 0 ),ir,nr=na+nb,result = J( nr+1, 1, 0 ),r="", carry,remainder},
a = Reverse( a );
For( ia = 1, ia <= na, ia++,
amat[ia] = hextonum[Substr( a, ia, 1 )]
);
b = Reverse( b );
For( ib = 1, ib <= nb, ib++,
bmat[ib] = hextonum[Substr( b, ib, 1 )]
);
for(ia=1,ia<=na,ia+=1,
for(ib=1,ib<=nb,ib+=1, // this inner loop might speed up by replacing it with matrix math
result[ia+ib-1] += amat[ia]*bmat[ib];
)
);
for(ir=1,ir<=nr,ir++, // do the carry. doing it last is fast, but places some sort of a limit on the total length
remainder = mod(result[ir],16);
carry = floor(result[ir]/16);
result[ir] = remainder;
result[ir+1] += carry;
r = numtohex[result[ir]] || r; // build hex result
);
r // return value
);
// example hexmultiply
show( hextonumber(hexmultiply("AE2","3B75")));
show( hextonumber("AE2")*hextonumber("3B75"));
// test code...
ntests=0;
start = tickseconds();
For( num1 = 0, num1 < 2e9, num1 = Floor( num1 * 1.07 + 1 ),
For( num2 = 0, num2 < 2e9, num2 = Floor( num2 * 1.05 + 1 ),
If( num1 * num2 > 2 ^ 53,
Continue(); // because double multiply gets wrong answer
);
ntests+=1;
t1 = hexmultiply( Hex( num1, "integer" ), Hex( num2, "integer" ) );
If( Hex To Number( Substr( t1, 2 ) ) != num1 * num2,
Show( num1, num2, t1, Hex To Number( Substr( t1, 2 ) ), num1 * num2 )
);
)
);
stop=tickseconds();
show(ntests,stop-start,ntests/(stop-start));
// long test...no promises here...this is not a meaningful test...
show( hexmultiply("00123456789ABCDEF0","00200000000000000000000000000000000000"));