create Makefile and hw1/main.c

This commit is contained in:
2025-09-12 22:36:10 +09:00
parent 2c75620ec9
commit 60b7c68313
4 changed files with 238 additions and 1 deletions

3
.gitignore vendored
View File

@@ -10,4 +10,5 @@ wheels/
.venv
#
.vscode
.vscode
out

61
Makefile Normal file
View File

@@ -0,0 +1,61 @@
BUILD_DIR := ./build
CC := gcc
CFLAGS := -Wall -g -std=c90
LDFLAGS := -lm
LIB_DIR := ./lib/nr/ansi
LIB_INCLUDE := $(LIB_DIR)/other
LIB_SRCS := $(LIB_DIR)/recipes/machar.c
LIB_OBJS := $(patsubst %.c,$(BUILD_DIR)/lib/%.o,$(notdir $(LIB_SRCS)))
HW_DIR := ./hws
ifeq ($(strip $(hw)),)
else
TARGET_NAME := hw$(hw)
SRC_DIR := $(HW_DIR)/hw$(hw)
endif
ifeq ($(strip $(TARGET_NAME)),)
all:
@echo "에러: 'target'을 지정해주세요."
else
TARGET_EXEC := $(BUILD_DIR)/$(TARGET_NAME).out
TARGET_SRCS := $(wildcard $(SRC_DIR)/*.c)
TARGET_OBJS := $(patsubst %.c,$(BUILD_DIR)/hw$(hw)/%.o,$(notdir $(TARGET_SRCS)))
OBJS := $(TARGET_OBJS) $(LIB_OBJS)
SRCS := $(TARGET_SRCS) $(LIB_SRCS)
all: run
endif
init:
@mkdir -p $(BUILD_DIR)
@mkdir -p $(BUILD_DIR)/lib
@mkdir -p $(BUILD_DIR)/$(TARGET_NAME)
clean:
@echo "빌드 결과물을 삭제합니다..."
@rm -rf $(BUILD_DIR)
build: init $(TARGET_EXEC)
@echo "빌드 완료"
$(TARGET_EXEC): $(OBJS)
@echo "링킹 중: $@"
$(CC) $(CFLAGS) $(LDFLAGS) $^ -o $@
$(OBJS): %.o:
@echo "컴파일 중: $@"
$(eval TARGET_C_BASENAME := $(patsubst %.o,%.c,$(notdir $@)))
$(eval FOUND_SRC := $(foreach src,$(SRCS),$(if $(filter $(TARGET_C_BASENAME),$(notdir $(src))),$(src))))
$(CC) $(CFLAGS) $(LDFLAGS) -I $(LIB_INCLUDE) -c $(FOUND_SRC) -o $@
run: clean build
@echo "실행 시작"
@echo "============"
@$(TARGET_EXEC)
dist:
mkdir -p out
zip -j -9 out/$(TARGET_NAME).zip $(TARGET_SRCS)

View File

View File

@@ -0,0 +1,175 @@
#include "nr.h"
#include <stdio.h>
#include <math.h>
void get_eps(float *eps) {
*eps = 1.0f;
while ((1.0f + *eps / 2.0f) > 1.0f) {
*eps /= 2.0f;
}
}
void get_eps_double(double *eps) {
*eps = 1.0;
while ((1.0 + *eps / 2.0) > 1.0) {
*eps /= 2.0;
}
}
#define CONV(i) ((double) (i))
void machar_double(int *ibeta, int *it, int *irnd, int *ngrd, int *machep, int *negep, int *iexp, int *minexp, int *maxexp,
double *eps, double *epsneg, double *xmin, double *xmax) {
int i, itemp, iz, j, k, mx, nxres;
double a, b, beta, betah, betain, one, t, temp, temp1, tempa, two, y, z, zero;
one = CONV(1);
two = one + one;
zero = one - one;
a = one;
do {
a += a;
temp = a + one;
temp1 = temp - a;
} while (temp1 - one == zero);
b = one;
do {
b += b;
temp = a + b;
itemp = (int) (temp - a);
} while (itemp == 0);
*ibeta = itemp;
beta = CONV(*ibeta);
*it = 0;
b = one;
do {
++(*it);
b *= beta;
temp = b + one;
temp1 = temp - b;
} while (temp1 - one == zero);
*irnd = 0;
betah = beta / two;
temp = a + betah;
if (temp - a != zero) *irnd = 1;
tempa = a + beta;
temp = tempa + betah;
if (*irnd == 0 && temp - tempa != zero) *irnd = 2;
*negep = (*it) + 3;
betain = one / beta;
a = one;
for (i = 1; i <= (*negep); i++) a *= betain;
b = a;
for (;;) {
temp = one - a;
if (temp - one != zero) break;
a *= beta;
--(*negep);
}
*negep = -(*negep);
*epsneg = a;
*machep = -(*it) - 3;
a = b;
for (;;) {
temp = one + a;
if (temp - one != zero) break;
a *= beta;
++(*machep);
}
*eps = a;
*ngrd = 0;
temp = one + (*eps);
if (*irnd == 0 && temp * one - one != zero) *ngrd = 1;
i = 0;
k = 1;
z = betain;
t = one + (*eps);
nxres = 0;
for (;;) {
y = z;
z = y * y;
a = z * one;
temp = z * t;
if (a + a == zero || fabs(z) >= y) break;
temp1 = temp * betain;
if (temp1 * beta == z) break;
++i;
k += k;
}
if (*ibeta != 10) {
*iexp = i + 1;
mx = k + k;
} else {
*iexp = 2;
iz = (*ibeta);
while (k >= iz) {
iz *= *ibeta;
++(*iexp);
}
mx = iz + iz - 1;
}
for (;;) {
*xmin = y;
y *= betain;
a = y * one;
temp = y * t;
if (a + a != zero && fabs(y) < *xmin) {
++k;
temp1 = temp * betain;
if (temp1 * beta == y && temp != y) {
nxres = 3;
*xmin = y;
break;
}
} else
break;
}
*minexp = -k;
if (mx <= k + k - 3 && *ibeta != 10) {
mx += mx;
++(*iexp);
}
*maxexp = mx + (*minexp);
*irnd += nxres;
if (*irnd >= 2) *maxexp -= 2;
i = (*maxexp) + (*minexp);
if (*ibeta == 2 && !i) --(*maxexp);
if (i > 20) --(*maxexp);
if (a != y) *maxexp -= 2;
*xmax = one - (*epsneg);
if ((*xmax) * one != *xmax) *xmax = one - beta * (*epsneg);
*xmax /= (*xmin * beta * beta * beta);
i = (*maxexp) + (*minexp) + 3;
for (j = 1; j <= i; j++) {
if (*ibeta == 2) *xmax += *xmax;
else
*xmax *= beta;
}
}
#undef CONV
int main() {
int ibeta, it, irnd, ngrd, machep, negep, iexp, minexp, maxexp;
float eps, epsneg, xmin, xmax;
machar(&ibeta, &it, &irnd, &ngrd, &machep, &negep, &iexp, &minexp, &maxexp,
&eps, &epsneg, &xmin, &xmax);
printf("Machine Accuracy for float (machar): \t\t%0.20f\n", eps);
get_eps(&eps);
printf("Machine Accuracy for float (get_eps): \t\t%0.20f\n", eps);
double eps_double, epsneg_double, xmin_double, xmax_double;
machar_double(&ibeta, &it, &irnd, &ngrd, &machep, &negep, &iexp, &minexp, &maxexp,
&eps_double, &epsneg_double, &xmin_double, &xmax_double);
printf("Machine Accuracy for double (machar_double): \t%0.20f\n", eps_double);
get_eps_double(&eps_double);
printf("Machine Accuracy for double (get_eps_double): \t%0.20f\n", eps_double);
return 0;
}