u3: adds jet and tests for +fein:ob

This commit is contained in:
Joe Bryan 2021-03-30 09:29:08 -07:00
parent 229ae81bf1
commit e7f552aeab
4 changed files with 144 additions and 0 deletions

View File

@ -150,6 +150,8 @@
u3_noun u3qe_shal(u3_atom, u3_atom);
u3_noun u3qe_sha1(u3_atom, u3_atom);
u3_atom u3qe_fein_ob(u3_atom pyn);
u3_noun u3qe_hmac(u3_noun, u3_atom, u3_atom,
u3_atom, u3_atom, u3_atom, u3_atom);

View File

@ -175,6 +175,8 @@
u3_noun u3we_shal(u3_noun);
u3_noun u3we_sha1(u3_noun);
u3_noun u3we_fein_ob(u3_noun);
u3_noun u3weo_raw(u3_noun);
u3_noun u3wee_puck(u3_noun);

View File

@ -0,0 +1,82 @@
/* j/3/fein.c
**
*/
#include "all.h"
#include <murmur3.h>
// +feis:ob constant parameters to +fe:ob
//
static const c3_w a_w = 0xffff;
static const c3_w b_w = 0x10000;
static const c3_w k_w = 0xffff0000;
// +raku:ob
//
static const c3_w rak_w[4] = { 0xb76d5eed, 0xee281300, 0x85bcae01, 0x4b387af7 };
static c3_w
_feis_fe(c3_w m_w)
{
c3_w l_w = m_w % a_w;
c3_w r_w = m_w / a_w;
c3_w f_w, tmp_w;
c3_d tmp_d;
c3_y k_y[2];
c3_y j_y;
for ( j_y = 0; j_y < 4; j_y++ ) {
k_y[0] = r_w & 0xff;
k_y[1] = (r_w >> 8) & 0xff;
MurmurHash3_x86_32(k_y, 2, rak_w[j_y], &f_w);
tmp_d = (c3_d)f_w + l_w;
tmp_w = tmp_d % (!(j_y & 1) ? a_w: b_w);
l_w = r_w;
r_w = tmp_w;
}
return ( a_w == r_w ) ? (r_w * a_w) + l_w : (l_w * a_w) + r_w;
}
static c3_w
_feis(c3_w m_w)
{
c3_w c_w = _feis_fe(m_w);
return ( c_w < k_w ) ? c_w : _feis_fe(c_w);
}
u3_atom
u3qe_fein_ob(u3_atom pyn)
{
c3_w sor_w = u3r_met(4, pyn);
if ( (sor_w < 2) || (sor_w > 4) ) {
return u3k(pyn);
}
if ( 2 == sor_w ) {
c3_w pyn_w = u3r_word(0, pyn);
c3_w out_w = b_w + _feis(pyn_w - b_w);
return u3i_word(out_w);
}
else {
c3_w pyn_w[2];
u3r_words(0, 2, pyn_w, pyn);
if ( pyn_w[0] < b_w ) {
return u3k(pyn);
}
else {
pyn_w[0] = b_w + _feis(pyn_w[0] - b_w);
return u3i_words(2, pyn_w);
}
}
}
u3_noun
u3we_fein_ob(u3_noun cor)
{
return u3qe_fein_ob(u3x_atom(u3x_at(u3x_sam, cor)));
}

View File

@ -245,6 +245,59 @@ _test_base16(void)
return ret_i;
}
static c3_w
_fein_ob_w(c3_w inp_w)
{
u3_atom inp = u3i_word(inp_w);
u3_atom act = u3qe_fein_ob(inp);
c3_w act_w = u3r_word(0, act);
u3z(inp); u3z(act);
return act_w;
}
static c3_i
_expect_fein_ob_w(c3_w inp_w, c3_w exp_w)
{
c3_w act_w = _fein_ob_w(inp_w);
if ( act_w != exp_w ) {
fprintf(stderr, "fein: inp=0x%08x exp=0x%08x act=0x%08x\n",
inp_w, exp_w, act_w);
return 0;
}
return 1;
}
static c3_i
_test_fein_ob(void)
{
c3_i ret_i = 1;
ret_i &= _expect_fein_ob_w(0, 0);
ret_i &= _expect_fein_ob_w(0xffff, 0xffff);
ret_i &= _expect_fein_ob_w(0x1b08f, 0x76b920e5);
ret_i &= _expect_fein_ob_w(0x10000, 0x423e60bf);
ret_i &= _expect_fein_ob_w(0x10001, 0xd4400acb);
ret_i &= _expect_fein_ob_w(0x10002, 0xf429043);
ret_i &= _expect_fein_ob_w(0x10000000, 0xa04bc7fa);
ret_i &= _expect_fein_ob_w(0x1234abcd, 0x686f6c25);
ret_i &= _expect_fein_ob_w(0xabcd1234, 0x4a220c8);
ret_i &= _expect_fein_ob_w(0xdeadbeef, 0x909bc4a9);
ret_i &= _expect_fein_ob_w(0xfffff, 0x6746b96b);
ret_i &= _expect_fein_ob_w(0xffffffff, 0xbba4dcce);
return ret_i;
}
static c3_i
_test_ob(void)
{
c3_i ret_i = 1;
ret_i &= _test_fein_ob();
return ret_i;
}
static c3_i
_test_jets(void)
{
@ -255,6 +308,11 @@ _test_jets(void)
ret_i = 0;
}
if ( !_test_ob() ) {
fprintf(stderr, "test jets: ob: failed\r\n");
ret_i = 0;
}
return ret_i;
}