diff --git a/src/hw12_doubleExp/CMakeLists.txt b/src/hw12_doubleExp/CMakeLists.txt new file mode 100644 index 0000000..b6794b7 --- /dev/null +++ b/src/hw12_doubleExp/CMakeLists.txt @@ -0,0 +1,6 @@ +cmake_minimum_required(VERSION 4.0) +project(hw12_doubleExp C) + +set(CMAKE_C_STANDARD 17) + +add_executable(hw12_doubleExp main.c doubleExp.c doubleExp.h) diff --git a/src/hw12_doubleExp/doubleExp.c b/src/hw12_doubleExp/doubleExp.c new file mode 100644 index 0000000..32d7502 --- /dev/null +++ b/src/hw12_doubleExp/doubleExp.c @@ -0,0 +1,76 @@ +#include "doubleExp.h" +#include +#include "doubleExp.h" + +typedef union DoubleUnion { + double value; + unsigned char bytes[8]; +} DoubleUnion; + +// Получение бита i +static int getBitI(const DoubleUnion *d, int i) +{ + int byte = i / 8; + int bit = i % 8; + + // Пролучаем нужный байт и сдвигаем его на позицию 0 + char neededByte = d->bytes[byte]; + char changePosition = neededByte >> bit; + + return changePosition & 1; +} + +void doubleExp(double x) +{ + DoubleUnion d; + d.value = x; + + // Определяем знак + int signI = getBitI(&d, 63); + char sign; + if (signI) + sign = '-'; + else + sign = '+'; + + int exp = 0; + for (int i = 62; i >= 52; i--) { + exp = (exp << 1) | getBitI(&d, i); + } + + // Достаем мантиссу + long long mantissaBits = 0; + for (int i = 51; i >= 0; i--) { + mantissaBits = (mantissaBits << 1) | getBitI(&d, i); + } + + // Проверка для INF и NaN + if (exp == 2047) { + if (mantissaBits == 0) { + printf("%cINF\n", sign); + } else { + printf("NaN\n"); + } + return; + } + + // Проверка для +0 и -0 + if (exp == 0 && mantissaBits == 0) { + printf("%c0\n", sign); + return; + } + + double mantissa = 1.0; + double fractionPart = 0.5; + for (int i = 51; i >= 0; i--) { + if (getBitI(&d, i)) { + mantissa += fractionPart; + } + fractionPart /= 2.0; + } + + // Так как в double порядок смещен на 1023, то получаем настоящий вычетанием + int power = exp - 1023; + + printf("Результат: %c%.20f*2^%d\n", sign, mantissa, power); +} diff --git a/src/hw12_doubleExp/doubleExp.h b/src/hw12_doubleExp/doubleExp.h new file mode 100644 index 0000000..18c4157 --- /dev/null +++ b/src/hw12_doubleExp/doubleExp.h @@ -0,0 +1,3 @@ +#include + +void doubleExp(double x); diff --git a/src/hw12_doubleExp/main.c b/src/hw12_doubleExp/main.c new file mode 100644 index 0000000..150f2ac --- /dev/null +++ b/src/hw12_doubleExp/main.c @@ -0,0 +1,12 @@ +#include +#include "doubleExp.h" + +int main(void) +{ + double x; + printf("Введите число: "); + scanf("%lf", &x); + doubleExp(x); + + return 0; +}