Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions HW7/DoubleToExponential/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
CC = gcc
CFLAGS = -Iinclude -Wall -Wextra

SRC = main.c src/doubleToExponential.c
TEST_SRC = tests/tests.c

OUT = program
TEST_OUT = testProgram

all: $(OUT)

$(OUT): $(SRC)
$(CC) $(CFLAGS) $(SRC) -o $(OUT)

test: $(TEST_SRC) src/doubleToExponential.c
$(CC) $(CFLAGS) -DTEST_MAIN src/doubleToExponential.c $(TEST_SRC) -o $(TEST_OUT)

clean:
rm -f $(OUT) $(TEST_OUT)

format:
find . -path ./build -prune -o -type f \( -path "./src/*" -o -path "./include/*" -o -path "./tests/*" -o -name "main.c" \) \( -name '*.c' -o -name '*.h' \) -print | xargs clang-format --style=file -i

format-check:
find . -path ./build -prune -o -type f \( -path "./src/*" -o -path "./include/*" -o -path "./tests/*" -o -name "main.c" \) \( -name '*.c' -o -name '*.h' \) -print | xargs clang-format --style=file --dry-run -Werror

3 changes: 3 additions & 0 deletions HW7/DoubleToExponential/include/doubleToExponential.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#pragma once

char* doubleToExponential(double num);
19 changes: 19 additions & 0 deletions HW7/DoubleToExponential/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#include "include/doubleToExponential.h"
#include <stdio.h>
#include <stdlib.h>

int main() {
double number;
printf("Enter a number: ");

if (scanf("%lf", &number) != 1) {
printf("Invalid input!\n");
return 1;
}

char* result = doubleToExponential(number);
printf("Result: %s\n", result);
free(result);

return 0;
}
53 changes: 53 additions & 0 deletions HW7/DoubleToExponential/src/doubleToExponential.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#include "../include/doubleToExponential.h"
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>

typedef union {
double value;
struct {
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
uint64_t mantissa : 52;
uint64_t exponent : 11;
uint64_t sign : 1;
#else
uint64_t sign : 1;
uint64_t exponent : 11;
uint64_t mantissa : 52;
#endif
} parts;
} DoubleUnion;

char* doubleToExponential(double num) {
DoubleUnion du;
du.value = num;

int sign = du.parts.sign;
int codedExponent = du.parts.exponent;
uint64_t mantissa = du.parts.mantissa;

if (codedExponent == 0 && mantissa == 0) {
char *result = malloc(9);
sprintf(result, "%c0.0*2^0", sign ? '-' : '+');
return result;
}

int exponent;
double normalizedMantissa;

if (codedExponent == 0) {
// denormalized numbers
exponent = -1022;
normalizedMantissa = (double)mantissa / (1ULL << 52);
}
else {
// normalized numbers
exponent = codedExponent - 1023;
normalizedMantissa = 1.0 + (double)mantissa / (1ULL << 52);
}

char* result = malloc(100);
sprintf(result, "%c%.20g*2^%d", sign ? '-' : '+', normalizedMantissa, exponent);
return result;
}
66 changes: 66 additions & 0 deletions HW7/DoubleToExponential/tests/tests.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#include "../include/doubleToExponential.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int assertOutput(const char* testName, double input, const char* expected) {
char* result = doubleToExponential(input);

if (strcmp(result, expected) == 0) {
printf("Passed %s\n", testName);
free(result);
return 1;
}
else {
printf("Failed %s: got: %s, expected: %s\n", testName, result, expected);
free(result);
return 0;
}
}

void testZero() {
printf("Zero values:\n");
assertOutput("positive zero", 0.0, "+0.0*2^0");
assertOutput("negative zero", -0.0, "-0.0*2^0");
}

void testPowersOfTwo() {
printf("Powers of two:\n");
assertOutput("2^-1", 0.5, "+1*2^-1");
assertOutput("2^0", 1.0, "+1*2^0");
assertOutput("2^1", 2.0, "+1*2^1");
assertOutput("2^2", 4.0, "+1*2^2");
assertOutput("2^3", 8.0, "+1*2^3");
assertOutput("2^4", 16.0, "+1*2^4");
assertOutput("2^5", 32.0, "+1*2^5");
assertOutput("negative power", -4.0, "-1*2^2");
}

void testKnownValues() {
printf("Known values:\n");
assertOutput("negative decimal", -2.5, "-1.25*2^1");
assertOutput("positive decimal", 10.0, "+1.25*2^3");
}

void runTests() {
printf("Running tests:\n");

testZero();
printf("\n");

testPowersOfTwo();
printf("\n");

testKnownValues();
printf("\n");

printf("All tests finished.\n");
}

#ifdef TEST_MAIN
int main()
{
runTests();
return 0;
}
#endif