Konwersja liczb binarnych na dziesiętne za pomocą ones complement. Przypomnienie paru kwestii + funkcja.

Na początku przypomnienie, jak działa ones complement:

  • Jeżeli pierwsza z lewej to 0 to odwracasz 0 na 1 i vice versa i wyliczasz liczbę bez tej pierwszej, która jest znakiem
  • Jeżeli pierwsza z lewej to 1 to odwracasz 0 na 1 i vice wersa, wyliczasz liczbę bez tej pierwszej, która jest znakiem, i mnożysz razy -1 bo ujemną chcesz

Ok przypomnijmy sobie te kody:

function onesComplement(binArr){

        return binArr.map((n) => {
            return n === 0 ? 1 : 0
        });
}

To zamienia jedynki na zera i odwrotnie. Teraz bin2dec:

function _bin2dec(binArr){

        let base = 2;
        let position = 0;
    
        let weight;
    
        let decimalNumber = 0;
    
        while(binArr.length > 0){
    
            let lastDigit = binArr.pop();
    
            weight = Math.pow(base, position);
    
            decimalNumber += lastDigit * weight;
    
            position++;
            
        }
    
        return decimalNumber;
    }

Już ten mechanizm omawialiśmy, więc proponuję przejść od razu do rzeczy:

function bin2decOnes(binArr){

    let sign = binArr[0];

    function onesComplement(binArr){

        return binArr.map((n) => {
            return n === 0 ? 1 : 0
        });
    }

    function _bin2dec(binArr){

        let base = 2;
        let position = 0;
    
        let weight;
    
        let decimalNumber = 0;
    
        while(binArr.length > 0){
    
            let lastDigit = binArr.pop();
    
            weight = Math.pow(base, position);
    
            decimalNumber += lastDigit * weight;
    
            position++;
            
        }
    
        return decimalNumber;
    }

    if(sign === 0)
        return _bin2dec(binArr.slice(1));

    return -1 * _bin2dec(onesComplement(binArr.slice(1)));
}

Pobieramy znak, mamy funkcje pomocnicze do odwracania zer/jedynek oraz do zamiany na binarny. Jeżeli 0, liczba dodatnia, to pozostałe liczby wrzucamy w bin2dec.

Jeżeli 1, to ujemna, czyli musimy zamienić jedynki na 0 i dać do bin2dec, razy -1 pomnożyć.

Dla lepszej czytelności możemy to poprawić:

function bin2decOnes(binArr){

    let sign = binArr[0];

    function onesComplement(binArr){

        return binArr.map((n) => {
            return n === 0 ? 1 : 0
        });
    }

    function _bin2dec(binArr){

        let base = 2;
        let position = 0;
    
        let weight;
    
        let decimalNumber = 0;
    
        while(binArr.length > 0){
    
            let lastDigit = binArr.pop();
    
            weight = Math.pow(base, position);
    
            decimalNumber += lastDigit * weight;
    
            position++;
            
        }
    
        return decimalNumber;
    }

    if(sign === 0)
        return _bin2dec(binArr.slice(1));

    return -1 * bin2decOnes(onesComplement(binArr));
}

Teraz już powinniśmy rozumieć flow tego ones complement. Test:

console.log(bin2decOnes([0,1,1,0]));
//6

console.log(bin2decOnes([1, 0, 0, 1]));
//-6