hex to dec converter

0

Zacząłem tworzyć aplikację, którą zamierzam docelowo wykorzystywać w mojej obecnej pracy (automatyka). Po prostu potrzebuję konwertera z jednego systemu liczbowego na inny. Dodatkowo musi on działać w konkretny (wygodny dla mnie) sposób. Więc zacząłem coś dłubać. Na razie jest to prosta konwersja hex => dec. Docelowo będą też inne systemy jak i funkcjonalności. Projekt ma charakter nie tylko praktyczny, ale i edukacyjny. Dlatego konwersji dokonuję "ręcznie", a w sposób wykorzystujący natywne możliwości JS (hexString = yourNumber.toString(16);).

Chciałem się dowiedzieć, co sądzicie o kodzie w obecnej postaci. Mianowicie:

  • czytelność kodu (nazwy funkcji i zmiennych)
  • czy logika oraz UI nie są pomieszane
  • sposób walidacji danych wejściowych
  • czy popełniłem jakieś karygodne błędy

W następnej kolejności chcę wykorzystać poniższy kod to nauki pisania testów. Z tego co mi wiadomo, testy powinno się pisać na bieżąco. Nie po ukończeniu aplikacji. Więc na tym etapie robię checkpoint i proszę o konstruktywną krytykę.

Oto kod:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="converter.css">
    <script src="converter.js" defer></script>
</head>
<body>
    <div id="background">
        <input type="text" id="HexValueField" placeholder="put hex value here">
        <p id="ErrorMessageField">ok</p>
        <button type="button" id="ConvertButton">Convert!</button> 
        <p id="DecValueField">result</p>  
    </div>
</body>
</html>
#background
{
    height: 100vh;
    width: 100vw;
}
#HexValueField
{
    display: block;
    text-align: center;
    margin: auto;
    margin-bottom: 10px;
}
#ConvertButton
{
    display: block;
    margin: auto;
    margin-bottom: 20px;
}
#DecValueField, #ErrorMessageField
{
    color: blue;
    margin: 0;
    margin-bottom: 20px;
    padding: 0;
    text-align: center;
}
#ErrorMessageField
{
    color: red;
    visibility: hidden;
}
const HexValueFiled = document.getElementById("HexValueField");
const ErrorMessageField = document.getElementById("ErrorMessageField");
const ConvertButton = document.getElementById("ConvertButton");
const DecValueFiled = document.getElementById("DecValueField");

// ========================================================== //

HexValueFiled.addEventListener("input", e => validateInput(e));

function validateInput(e)
{
    let EnteredValue = e.target.value; 
    let AllowedCharacters = /^[A-Fa-f0-9]*$/;
    if (AllowedCharacters.test(EnteredValue))
    {
        hideError()
    }
    else
    (
        displayError("Invalid character detected!")
    );
}

function hideError()
{
    ErrorMessageField.style.visibility = "hidden";
    ErrorMessageField.textContent = "ok";
    ConvertButton.disabled = false;
}

function displayError(message)
{
    ErrorMessageField.style.visibility = "visible";
    ErrorMessageField.textContent = message;
    ConvertButton.disabled = true;
}

// ========================================================== //

ConvertButton.addEventListener("click", convertToDecimal)

function convertToDecimal()
{
    let HexValue = HexValueFiled.value;
    let HexValueReversed = [...HexValue].reverse();
    let DecValue = 0;

    HexValueReversed.map((element, index) => 
    {
        DecValue += decodeLettersToNumbers(element) * Math.pow(16, index)
    })

    displayResult(DecValue);
}

function decodeLettersToNumbers(character)
{
    switch (character) 
    {
        case '1':
            return parseInt(character);
        case '2':
            return parseInt(character);
        case '3':
            return parseInt(character);
        case '4':
            return parseInt(character);
        case '5':
            return parseInt(character);
        case '6':
            return parseInt(character);
        case '7':
            return parseInt(character);
        case '8':
            return parseInt(character);
        case '9':
            return parseInt(character);
        case 'A':
        case 'a':
            return parseInt(10);
        case 'B':
        case 'b':
            return parseInt(11);
        case 'C':
        case 'c':
            return parseInt(12);
        case 'D':
        case 'd':
            return parseInt(13);
        case 'E':
        case 'e':
            return parseInt(14);
        case 'F':
        case 'f':
            return parseInt(15);
        default:
            displayError("Something went wrong!");
    }
}

function displayResult(result)
{
    DecValueFiled.textContent = result;
}

screenshot-20221019182030.png
screenshot-20221019182104.png

1

@kosmonauta80:

w decodeLettersToNumbers ten case z parseInt() jest dziwny ...

DecValue += decodeLettersToNumbers(element) * Math.pow(16, index)
A tu wystawiasz się wszelkie błędy arytmetyczne od biblioteki zmiennoprzecinkowej, a to są znaczące rzeczy jakby przeliczać 8 cyfrowe hexy

0

w decodeLettersToNumbers ten case z parseInt() jest dziwny ...

Wejście funkcji to string. Chciałem, by wyjściem był Int. Widzę też, że kod można uprościć tj. wystarczy użyć jednego return parseInt(character); dla zakresu 1-9.

DecValue += decodeLettersToNumbers(element) * Math.pow(16, index)
A tu wystawiasz się wszelkie błędy arytmetyczne od biblioteki zmiennoprzecinkowej, a to są znaczące rzeczy jakby przeliczać 8 cyfrowe hexy

Czyli lepiej zrobić coś takiego?

function calculateHexPower(exponent)
{ 
  let result = 1;
  
  if (exponent == 0)
  {
    return result;
  }
  else
  {
    for (let i=1; i<=exponent; i++)
    {
      result *= 16; 
    }
  }
  return result;
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1