1ν•™λ…„ (2023)/C μ–Έμ–΄

[C] Study: λ³€μˆ˜μ™€ μžλ£Œν˜• - (4) λΆ€λ™μ†Œμˆ˜μ ν˜•

waterproof 2023. 8. 17. 19:23

 

 

 

 


 μ‹€μˆ˜λŠ” 123.456κ³Ό 같이 μ†Œμˆ˜μ μ„ 가진 μˆ˜μ΄λ‹€.

 

 μ‹€μˆ˜λŠ” 맀우 큰 μˆ˜λ‚˜ 맀우 μž‘μ€ 수λ₯Ό λ‹€λ£¨λŠ” μžμ—° κ³Όν•™μ΄λ‚˜ 곡학 λΆ„μ•Όμ˜ ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•  λ•ŒλŠ” μ—†μ–΄μ„œλŠ” μ•ˆ 될 μ€‘μš”ν•œ μš”μ†Œμ΄λ‹€.

 

 Cμ—μ„œλŠ” λΆ€λ™μ†Œμˆ˜μ  λ°©μ‹μœΌλ‘œ μ‹€μˆ˜λ₯Ό ν‘œν˜„ν•œλ‹€. 

 

 λΆ€λ™μ†Œμˆ˜μ μ€ μ†Œμˆ˜μ μ˜ μœ„μΉ˜κ°€ 고정돼 μžˆμ§€ μ•ŠμœΌλ©°, κ°€μˆ˜μ™€ μ§€μˆ˜λ₯Ό μ‚¬μš©ν•˜μ—¬ μ‹€μˆ˜λ₯Ό ν‘œν˜„ν•œλ‹€.

 

 κ°€μˆ˜λŠ” 유효숫자, μ§€μˆ˜λŠ” μ†Œμˆ˜μ μ˜ μœ„μΉ˜λ₯Ό λ‚˜νƒ€λ‚Έλ‹€.

 

 

 

Cμ—μ„œλŠ” float, double, long double의 3κ°€μ§€μ˜γ…œλΆ€λ™μ†Œμˆ˜μ  μžλ£Œν˜•μ΄ μžˆλ‹€. PCμ—μ„œλŠ” doubleκ³Ό long double은 κ°™λ‹€.

 

 

주어진 λΉ„νŠΈ μ•ˆμ—μ„œ μ§€μˆ˜μ™€ κ°€μˆ˜λ₯Ό μ–΄λ–»κ²Œ ν‘œν˜„ν•˜λŠλƒμ— λŒ€ν•œ μ—¬λŸ¬κ°€μ§€ 규격이 μžˆλ‹€. C μ–Έμ–΄μ˜ λΆ€λ™μ†Œμˆ˜μ μŒ IEEE 754 κ·œκ²©μ„ μ‚¬μš©ν•œλ‹€(μ˜ˆμ „ C 컴파일러 μ œμ™Έ). 예λ₯Ό λ“€μ–΄μ„œ float ν˜•μ€ λ‹€μŒκ³Ό 같은 IEEE 754 Single-Precision κ·œκ²©μ„ μ‚¬μš©ν•œλ‹€.

 

 

floatλŠ” 32λΉ„νŠΈ, double은 64λΉ„νŠΈλ₯Ό μ‚¬μš©ν•œλ‹€. floatλŠ” μ•½ 6개의 유효 숫자, double은 μ•½ 16개의 유효 숫자λ₯Ό κ°€μ§ˆ 수 μžˆλ‹€.

 

λΆ€λ™μ†Œμˆ˜μ ν˜•μ€ λΉ„νŠΈμ˜ κ°œμˆ˜κ°€ μ œν•œλ˜μ–΄ μžˆμœΌλ―€λ‘œ μ•„μ£Ό μ •ν™•ν•˜κ²Œ 값을 μ €μž₯ν•˜κΈ°κ°€ μ–΄λ €μš΄ κ²½μš°κ°€ μžˆλ‹€.

 

 

λΆ€λ™μ†Œμˆ˜μ  μžλ£Œν˜•

 

 

μ°Έκ³ 

유효 μˆ«μžλž€ 믿을 수 μžˆλŠ” 의미 μžˆλŠ” 숫자λ₯Ό λ§ν•œλ‹€. 예λ₯Ό λ“€μ–΄μ„œ 2,696을 μ‹­μ˜ μžλ¦¬μ—μ„œ λ°˜μ˜¬λ¦Όν•˜λ©΄ 2,700이닀. μ—¬κΈ°μ„œ 2와 7은 μ˜λ―ΈμžˆλŠ” μˆ«μžμ΄λ‹€. λ°˜λ©΄μ— 뒀에 뢙은 00은 λ‹¨μˆœνžˆ 자릿수λ₯Ό λ‚˜νƒ€λ‚΄λŠ”λ° μ‚¬μš©λœλ‹€. 유효 숫자의 κ°œμˆ˜λŠ” μ†Œμˆ˜μ μ˜ μœ„μΉ˜μ™€λŠ” 상관이 μ—†λ‹€. 2,700을 2.7e3이라고 ν‘œν˜„ν•΄λ„ 유효 μˆ«μžλŠ” μ—­μ‹œ 2κ°œμ΄λ‹€.

 

μ°Έκ³ 

λΆ€λ™μ†Œμˆ˜μ ν˜•μ€ μ†Œμˆ˜μ μ˜ μœ„μΉ˜κ°€ μ›€μ§μΈλ‹€λŠ” μ˜λ―Έμ—μ„œ λΆ€λ™μ†Œμˆ˜μ  수라고 ν•œλ‹€.

 

 

 


λΆ€λ™μ†Œμˆ˜μ  μƒμˆ˜

 

 λΆ€λ™μ†Œμˆ˜μ  μƒμˆ˜λ₯Ό ν‘œκΈ°ν•˜λŠ” λ°©λ²•μ—λŠ” 두 가지가 μžˆλ‹€.

 

    1. μ†Œμˆ˜μ  ν‘œκΈ°λ²•: μ†Œμˆ˜μ μ„ μ΄μš©ν•˜μ—¬ μ‹€μˆ˜λ₯Ό ν‘œν˜„ν•˜λŠ” 방법.

 

    2. μ§€μˆ˜ ν‘œκΈ°λ²•: μ§€μˆ˜λ₯Ό μ΄μš©ν•˜μ—¬ μ‹€μˆ˜λ₯Ό ν‘œκΈ°ν•˜λŠ” 방법

 

 

 μ¦‰ 12345.6은 1,23456x10^4둜 ν‘œκΈ°κ°€ κ°€λŠ₯ν•˜κ³  이것을 Cμ—μ„œλŠ” 1.23456e4둜 ν‘œκΈ°ν•œλ‹€. μ§€μˆ˜ 뢀뢄은 Eλ‚˜ eλ₯Ό μ‚¬μš©ν•˜μ—¬ ν‘œμ‹œν•œλ‹€.

 

 

 μ£Όμ˜ν•  점: μ •μˆ˜λΌκ³  ν•˜λ”λΌλ„ 2.0처럼 뒀에 μ†Œμˆ˜μ μ„ 뢙이면 이것은 λΆ€λ™μ†Œμˆ˜μ  μƒμˆ˜λ‘œμ„œ κ°„μ£Όλ˜μ–΄ doubleν˜•μ΄ λœλ‹€.

 

μ§€μˆ˜ ν‘œκΈ°λ²•μ€ 주둜 맀우 큰 μˆ˜λ‚˜ μž‘μ€ 수λ₯Ό ν‘œκΈ°ν•˜λŠ”λ° μœ μš©ν•˜λ‹€.

 

λΆ€λ™μ†Œμˆ˜μ  μƒμˆ˜λŠ” 기본적으둜 doubleν˜•μœΌλ‘œ κ°„μ£Όλœλ‹€.

 

λ§Œμ•½ doubleν˜•μ΄ μ•„λ‹ˆκ³  floatν˜• μƒμˆ˜λ₯Ό λ§Œλ“€λ €λ©΄ μƒμˆ˜ 끝에 fλ‚˜ Fλ₯Ό λΆ™μ—¬μ£Όλ©΄ λœλ‹€.

 

3.141592F

 

 

λ‹€μŒμ€ μœ νš¨ν•œ λΆ€λ™μ†Œμˆ˜μ  μƒμˆ˜μ˜ μ˜ˆμ΄λ‹€.

 

.        // μ†Œμˆ˜μ λ§Œ 뢙여도 λœλ‹€.
.28      // μ •μˆ˜λΆ€κ°€ 없어도 λœλ‹€.
9.26E3   // 9.26x10^3
0.67e-7  // 0.67x10^-7

 

 

 

 


ν˜•μ‹ μ§€μ •μž

 

 floatν˜•μ˜ 값을 좜λ ₯ν•˜κ±°λ‚˜ μž…λ ₯ν•˜λ €λ©΄ ν˜•μ‹ μ§€μ •μžλ‘œ "%d"λ₯Ό μ‚¬μš©ν•œλ‹€.

 

 doubleν˜•μ˜ 값을 μž…μΆœλ ₯ν•˜λ €λ©΄ "%lf"을 μ‚¬μš©ν•œλ‹€. 특히 doubleν˜•μ˜ 값을 μž…λ ₯ν•  λ•Œ "%lf"을 μ‚¬μš©ν•˜μ§€ μ•ŠμœΌλ©΄ 값이 μ΄μƒν•˜κ²Œ μ €μž₯λœλ‹€.

 

double radius;
printf("λ°˜μ§€λ¦„ 값을 μž…λ ₯ν•˜μ‹œμ˜€.")
scanf("%lf", &radius);          // λ°˜λ“œμ‹œ "%lf"을 μ‚¬μš©ν•˜μ—¬μ•Ό ν•œλ‹€.

 

 

 

예제 #1

λ‹€μŒμ˜ μ˜ˆμ œλŠ” 유효 숫자 κ°œλ…μ„ μ•Œμ•„λ³΄κΈ° μœ„ν•˜μ—¬ λΆ€λ™μ†Œμˆ˜μ  μƒμˆ˜λ₯Ό floatν˜• λ³€μˆ˜μ™€ doubleν˜• λ³€μˆ˜μ— 1234567890.12345678901234567890을 λŒ€μž…ν•˜μ—¬ λ³Έλ‹€.

 

#include <stdio.h>

int main(void)
{
	float fvalue = 1234567890.12345678901234567890;
	double dvalue = 1234567890.12345678901234567890;
	printf("floatν˜• λ³€μˆ˜=%30.25f\n", fvalue);
	printf("doubleν˜• λ³€μˆ˜=%30.25lf\n", dvalue);
	
    return 0;
}

 

 

ν”„λ‘œκ·Έλž¨ μ„€λͺ…

floatν˜•μ€ 6개 μ •λ„μ˜ 유효 숫자λ₯Ό κ°€μ§ˆ 수 μžˆμœΌλ―€λ‘œ 8번째 μžλ¦Ώμˆ˜λΆ€ν„°λŠ” μ •ν™•ν•œ 값이 λ‚˜μ˜€μ§€ μ•ŠλŠ”λ‹€. λ°˜λ©΄μ— doubleν˜•μ€ 15자리 μ •λ„μ˜ 유효 숫자λ₯Ό 가짐을 확인할 수 μžˆλ‹€. ν˜•μ‹ μ§€μ •μž % μ•žμ— 뢙은 30.25λŠ” 전체 좜λ ₯ ν•„λ“œμ˜ 크기λ₯Ό 30으둜 ν•˜κ³  μ†Œμˆ˜ 뢀뢄을 25자리둜 좜λ ₯ν•˜λΌλŠ” μ˜λ―Έμ΄λ‹€.

 

μ°Έκ³ 

λΆ€λ™μ†Œμˆ˜μ ν˜•μ˜ ν•œκ³„λ₯Ό μ•Œλ €μ£ΌλŠ” ν—€λ”νŒŒμΌμ΄ μ‘΄μž¬ν•œλ‹€. 헀더 파일 float.h에 μžˆλŠ” FLT_MINκ³Ό FLT_MAXλŠ” float둜 λ‚˜νƒ€λ‚Ό 수 μžˆλŠ” κ°€μž₯ μž‘μ€ κ°’κ³Ό κ°€μž₯ 큰 값을 μ˜λ―Έν•œλ‹€.
λΉ„μŠ·ν•˜κ²Œ doubleν˜•μ— λŒ€ν•΄μ„œλ„ DBL_MINκ³Ό DBL_MAXκ°€ μ •μ˜λ˜μ–΄ μžˆλ‹€.

 

Q float같은 μ‹€μˆ˜λ₯Ό int같은 μ •μˆ˜μ— 넣을 경우, μ–΄λ–€ 일이 λ°œμƒν•˜λŠ”κ°€?
A μ»΄νŒŒμΌλŸ¬λŠ” μ΄λŸ¬ν•œ κ²½μš°μ— κ²½κ³ λ₯Ό ν•œλ‹€. μ‹€μˆ˜ μ€‘μ—μ„œ μ†Œμˆ˜μ  μ΄ν•˜λŠ” 없어지고 μ •μˆ˜ λΆ€λΆ„λ§Œ μ •μˆ˜ λ³€μˆ˜μ— λŒ€μž…λœλ‹€. 12.7μ΄λΌλŠ” μ‹€μˆ˜λ₯Ό μ •μˆ˜ λ³€μˆ˜μ— λŒ€μž…ν•˜λ©΄ 12만 λ‚¨λŠ”λ‹€.

 

 

 

 


μ˜€λ²„ν”Œλ‘œμš°μ™€ μ–Έλ”ν”Œλ‘œμš°

 

 μ˜€λ²„ν”Œλ‘œμš°(overflow): λ³€μˆ˜μ— λŒ€μž…λœ μˆ˜κ°€ λ„ˆλ¬΄ μ»€μ„œ λ³€μˆ˜κ°€ μ €μž₯ν•  수 μ—†λŠ” 상황을 μ˜λ―Έν•œλ‹€.

 

 floatν˜• λ³€μˆ˜λŠ” μ•½ 1x10^38 이상을 λ„˜λŠ” μˆ˜λŠ” μ €μž₯ν•˜μ§€ λͺ»ν•œλ‹€. 이보닀 큰 값을 λŒ€μž…ν•˜λ©΄ μ˜€λ²„ν”Œλ‘œμš°κ°€ λ°œμƒν•  것이닀.

 

 μ–Έλ”ν”Œλ‘œμš°(underflow): μ˜€λ²„ν”Œλ‘œμš°μ™€ λ°˜λŒ€μ˜ 상황. λΆ€λ™μ†Œμˆ˜μ μ˜ μˆ˜κ°€ λ„ˆλ¬΄ μž‘μ•„μ„œ ν‘œν˜„ν•˜κΈ°κ°€ νž˜λ“  상황

 

 

#include <stdio.h>

int main(void)
{
	float x = 1e39;
	float y = 1.23456e-46;

	printf("x=%e\n", x);
	printf("y=%e\n", y);
	return 0;
}

 

 

 

 

ν”„λ‘œκ·Έλž¨ μ„€λͺ…

(line 5)  λΆ€λ™μ†Œμˆ˜μ μ˜ 경우, μ˜€λ²„ν”Œλ‘œμš°κ°€ λ°œμƒν•˜λ©΄ μ»΄νŒŒμΌλŸ¬λŠ” ν•΄λ‹Ή λ³€μˆ˜μ— λ¬΄ν•œλŒ€λ₯Ό μ˜λ―Έν•˜λŠ” νŠΉλ³„ν•œ 값을 λŒ€μž…ν•˜κ³  printf()λŠ” 이 값을 inf라고 좜λ ₯ν•œλ‹€.
(line 8, 9) μ‹€ν–‰ κ²°κ³Όλ₯Ό 보면 λ³€μˆ˜ y의 값은 μ–Έλ”ν”Œλ‘œμš°κ°€ μΌμ–΄λ‚˜μ„œ 0으둜 좜λ ₯λ˜μ—ˆλ‹€. μ„œμ‹ μ§€μ •μž %eλŠ” μ§€μˆ˜ ν‘œκΈ°λ²•μœΌλ‘œ 좜λ ₯ν•˜λΌλŠ” μ˜λ―Έμ΄λ‹€.

 

 

 


λΆ€λ™μ†Œμˆ˜μ ν˜•μ€ λΆ€μ •ν™•ν•  μˆ˜λ„ μžˆλ‹€!

 

 λ‹€μŒμ˜ μ½”λ“œλ₯Ό μ‹€ν–‰ν•΄λ³΄μž.

 

#include <stdio.h>

int main(void)
{
	float value = 0.1;
    printf("%.20f \n", value);
    return 0;
}

 

 

 0.1의 값이 μ •ν™•ν•˜κ²Œ 좜λ ₯λ˜μ§€ μ•ŠλŠ”λ‹€. μ΄μœ λŠ” λ¬΄μ—‡μΌκΉŒ?

 

 μ΄μ§„λ²•μœΌλ‘œλŠ” μ •ν™•ν•˜κ²Œ λ‚˜νƒ€λ‚Ό 수 μ—†λŠ” 값듀이 있기 λ•Œλ¬Έμ΄λ‹€. 0.1도 κ·Έ μ€‘μ˜ ν•˜λ‚˜μ΄λ‹€.

 

 μ‹­μ§„λ²•μœΌλ‘œ 예λ₯Ό λ“€μ–΄λ³΄μž. μ‹­μ§„λ²•μ—μ„œλŠ” 1/3을 μ •ν™•ν•˜κ²Œ λ‚˜νƒ€λ‚Ό 수 μ—†λ‹€.(0.3333...이 λ¬΄ν•œνžˆ λ°˜λ³΅λœλ‹€.)

 

 μ΄μ§„λ²•μ—μ„œλŠ” 0.1이 κ·Έλ ‡λ‹€. μ‹­μ§„λ²•μ—μ„œλŠ” 0.1둜 μ •ν™•ν•˜κ²Œ ν‘œν˜„λ˜μ§€λ§Œ, μ΄μ§„λ²•μ—μ„œλŠ” 0.1을 μ •ν™•ν•˜κ²Œ ν‘œν˜„ν•˜λŠ” 것이 λΆˆκ°€λŠ₯ν•˜λ‹€.

 

 "0.000110011..."둜 μ‹œμž‘λ˜μ–΄μ„œ λ¬΄ν•œνžˆ 이어진닀. λ¬Όλ‘  μ€‘κ°„μ—μ„œ λ°˜μ˜¬λ¦Όν•˜λ©΄ μ–Όλ§ˆλ“ μ§€ μ‹€μš©μ μœΌλ‘œλŠ” μ‚¬μš©μ΄ κ°€λŠ₯ν•˜λ‹€.