// -*- compile-command: "g++ -g -c f16.cc" -*-
// Correction of at most 2 nibbles in 6 with Reed-Solomon code
// Current correction algorithm is exhaustiv search,
// fixes about 6000 double errors by second on my Mac
// It might be worth implementing a Bezout algorithm for error correction
// Most important functions are
// inline polyf16 convert(unsigned u);
// creates from a 8 bits integer u, 3 8 bits integers data=u and 2 controls
// inline bool correct(polyf16 & p);
// if p is OK returns false otherwise corrects p and returns true
/*
* Copyright (C) 2017 B. Parisse, Institut Fourier, 38402 St Martin d'Heres
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
#ifndef _F16_H
#define _F16_H
#include
#include
// add/mult GF(2,4) with min poly x^4+x+1
/*
short addtab[]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
1,2,3,2,5,4,7,6,9,8,11,10,13,12,15,14,
2,3,0,1,6,7,4,5,10,11,8,9,14,15,12,13,
3,2,1,0,7,6,5,4,11,10,9,8,15,14,13,12,
4,5,6,7,0,1,2,3,12,13,14,15,8,9,10,11,
5,4,7,6,1,0,3,2,13,12,15,14,9,8,11,10,
6,7,4,5,2,3,0,1,14,15,12,13,10,11,8,9,
7,6,5,4,3,2,1,0,15,14,13,12,11,10,9,8,
8,9,10,11,12,13,14,15,0,1,2,3,4,5,6,7,
9,8,11,10,13,12,15,14,1,0,3,2,5,4,7,6,
10,11,8,9,14,15,12,13,2,3,0,1,6,7,4,5,
11,10,9,8,15,14,13,12,3,2,1,0,7,6,5,4,
12,13,14,15,8,9,10,11,4,5,6,7,0,1,2,3,
13,12,15,14,9,8,11,10,5,4,7,6,1,0,3,2,
14,15,12,13,10,11,8,9,6,7,4,5,2,3,0,1,
15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0};
*/
short multab[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ,
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 ,
0,2,4,6,8,10,12,14,3,1,7,5,11,9,15,13 ,
0,3,6,5,12,15,10,9,11,8,13,14,7,4,1,2 ,
0,4,8,12,3,7,11,15,6,2,14,10,5,1,13,9 ,
0,5,10,15,7,2,13,8,14,11,4,1,9,12,3,6 ,
0,6,12,10,11,13,7,1,5,3,9,15,14,8,2,4 ,
0,7,14,9,15,8,1,6,13,10,3,4,2,5,12,11 ,
0,8,3,11,6,14,5,13,12,4,15,7,10,2,9,1 ,
0,9,1,8,2,11,3,10,4,13,5,12,6,15,7,14 ,
0,10,7,13,14,4,9,3,15,5,8,2,1,11,6,12 ,
0,11,5,14,10,1,15,4,7,12,2,9,13,6,8,3 ,
0,12,11,7,5,9,14,2,10,6,1,13,15,3,4,8 ,
0,13,9,4,1,12,8,5,2,15,11,6,3,14,10,7 ,
0,14,15,1,13,3,2,12,9,7,6,8,4,10,11,5 ,
0,15,13,2,9,6,4,11,1,14,12,3,8,7,5,1};
short invtab[]={0,1,9,14,13,11,7,6,15,2,12,5,10,4,3,8};
struct f16{
short i; // additive representation (polynomial bit by bit)
f16(short i_):i(i_ % 16){};
f16():i(0){};
void dbgprint() const {std::cout << "f16 " << i << ":" << i/8 << (i/4)%2 << (i/2)%2 << i%2 << std::endl;}
};
inline f16 operator + (const f16 & a,const f16 & b) {return a.i ^ b.i;}
inline f16 operator * (const f16 & a,const f16 & b){ return multab[a.i*16+b.i]; }
inline f16 operator - (const f16 & a){return a;}
inline f16 operator - (const f16 & a,const f16 & b){ return a.i^b.i;}
//inline f16 inverse (const f16 & a){return invtab[a];} // note: returns 0 for inverse(0)
//inline f16 operator / (const f16 & a,const f16 & b){return a*inverse(b);}
std::istream & operator >> (std::istream & in,f16 & f){return in >> f.i;}
std::ostream & operator << (std::ostream & out,const f16 & f){ return out<