diff --git a/pkg/urbit/jets/e/fein_ob.c b/pkg/urbit/jets/e/fein_ob.c index fd9333126c..80e1135120 100644 --- a/pkg/urbit/jets/e/fein_ob.c +++ b/pkg/urbit/jets/e/fein_ob.c @@ -14,15 +14,16 @@ static const c3_w k_w = 0xffff0000; // static const c3_w rak_w[4] = { 0xb76d5eed, 0xee281300, 0x85bcae01, 0x4b387af7 }; +/* _fe_ob(): +fe:ob, with constant parameters factored out. +** correct over the domain [0x0, 0xfffe.ffff] +*/ static c3_w -_feis_fe(c3_w m_w) +_fe_ob(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; + c3_w f_w, t_w; + c3_y j_y, k_y[2]; for ( j_y = 0; j_y < 4; j_y++ ) { k_y[0] = r_w & 0xff; @@ -30,20 +31,28 @@ _feis_fe(c3_w m_w) 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; + // NB: this addition can overflow a c3_w (before mod) + // + t_w = ((c3_d)f_w + l_w) % (!(j_y & 1) ? a_w : b_w); + l_w = r_w; + r_w = t_w; } - return ( a_w == r_w ) ? (r_w * a_w) + l_w : (l_w * a_w) + r_w; + // legendary @max19 + // + return ( a_w == r_w ) + ? (r_w * a_w) + l_w + : (l_w * a_w) + r_w; } +/* _feis_ob(): +feis:ob, also offsetting by 0x1.000 (as in +fein:ob). +** correct over the domain [0x1.0000, 0xffff.ffff] +*/ static c3_w -_feis(c3_w m_w) +_feis_ob(c3_w m_w) { - c3_w c_w = _feis_fe(m_w); - return ( c_w < k_w ) ? c_w : _feis_fe(c_w); + c3_w c_w = _fe_ob(m_w - b_w); + return b_w + (( c_w < k_w ) ? c_w : _fe_ob(c_w)); } u3_atom @@ -56,10 +65,7 @@ u3qe_fein_ob(u3_atom 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); + return u3i_word(_feis_ob(u3r_word(0, pyn))); } else { c3_w pyn_w[2]; @@ -69,7 +75,7 @@ u3qe_fein_ob(u3_atom pyn) return u3k(pyn); } else { - pyn_w[0] = b_w + _feis(pyn_w[0] - b_w); + pyn_w[0] = _feis_ob(pyn_w[0]); return u3i_words(2, pyn_w); } } diff --git a/pkg/urbit/jets/e/fynd_ob.c b/pkg/urbit/jets/e/fynd_ob.c index f32ca1a74f..203d94f4d7 100644 --- a/pkg/urbit/jets/e/fynd_ob.c +++ b/pkg/urbit/jets/e/fynd_ob.c @@ -10,46 +10,53 @@ static const c3_w a_w = 0xffff; static const c3_w b_w = 0x10000; static const c3_w k_w = 0xffff0000; -// +raku:ob +// (flop raku:ob) // -static const c3_w rak_w[4] = { 0xb76d5eed, 0xee281300, 0x85bcae01, 0x4b387af7 }; +static const c3_w kar_w[4] = { 0x4b387af7, 0x85bcae01, 0xee281300, 0xb76d5eed }; +/* _fen_ob(): +fen:ob, with constant parameters factored out. +** correct over the domain [0x0 ... 0xfffe.ffff] +*/ static c3_w -_tail_fen(c3_w m_w) +_fen_ob(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_y k_y[2]; - c3_y j_y; + c3_w f_w, t_w; + c3_y j_y, k_y[2]; + // legendary @max19 + // if ( a_w == l_w ) { - tmp_w = l_w; + t_w = l_w; l_w = r_w; - r_w = tmp_w; + r_w = t_w; } - for ( j_y = 4; j_y > 0; j_y-- ) { + for ( j_y = 0; j_y < 4; j_y++ ) { k_y[0] = l_w & 0xff; k_y[1] = (l_w >> 8) & 0xff; - MurmurHash3_x86_32(k_y, 2, rak_w[j_y - 1], &f_w); + MurmurHash3_x86_32(k_y, 2, kar_w[j_y], &f_w); - tmp_w = ( j_y & 1 ) - ? ((r_w + a_w) - (f_w % a_w)) % a_w - : ((r_w + b_w) - (f_w % b_w)) % b_w; + t_w = ( j_y & 1 ) + ? ((r_w + a_w) - (f_w % a_w)) % a_w + : ((r_w + b_w) - (f_w % b_w)) % b_w; r_w = l_w; - l_w = tmp_w; + l_w = t_w; } return (r_w * a_w) + l_w; } +/* _tail_ob(): +feis:ob, also offsetting by 0x1.000 (as in +fynd:ob). +** correct over the domain [0x1.0000, 0xffff.ffff] +*/ static c3_w -_tail(c3_w m_w) +_tail_ob(c3_w m_w) { - c3_w c_w = _tail_fen(m_w); - return ( c_w < k_w ) ? c_w : _tail_fen(c_w); + c3_w c_w = _fen_ob(m_w - b_w); + return b_w + (( c_w < k_w ) ? c_w : _fen_ob(c_w)); } u3_atom @@ -62,10 +69,7 @@ u3qe_fynd_ob(u3_atom pyn) } if ( 2 == sor_w ) { - c3_w pyn_w = u3r_word(0, pyn); - c3_w out_w = b_w + _tail(pyn_w - b_w); - - return u3i_word(out_w); + return u3i_word(_tail_ob(u3r_word(0, pyn))); } else { c3_w pyn_w[2]; @@ -75,7 +79,7 @@ u3qe_fynd_ob(u3_atom pyn) return u3k(pyn); } else { - pyn_w[0] = b_w + _tail(pyn_w[0] - b_w); + pyn_w[0] = _tail_ob(pyn_w[0]); return u3i_words(2, pyn_w); } }