2021-11-30(화) 4주차 2일

Jeongyun Heo·2021년 11월 30일
0

클래스 실행과 외부 라이브러리 관계

이클립스에서 실행하는 거니까 Run 버튼 누르는 거지
cmd창에서

자바에서 제공하는 게 아님

'나 여기에 있는 거 쓸 거야' 라고 알려줘야 됨

java -cp

클래스의 출입문 main
main 메소드 안에 SpringApplication

C:\Users\JYH\.gradle\caches\modules-2\files-2.1\org.springframework.boot\spring-boot\2.6.1\f670cee55752c1f1b304508e18bafd000e543174\spring-boot-2.6.1.jar

java -classpath bin/main com.eomcs.study.App

세미콜론 찍고 클래스가 들어 있는 jar 파일

다 적어야 됨...

다른 개발자가 만든 코드를 써야 됨
실행할 때 가리키거나 컴파일할 때 가리켜야 됨
프로그래밍 언어에 상관없이 공통

61개

윈도우 운영체제는 미리 환경 변수에 이 경로들을 다 저장시켜 놓고 환경 변수를 사용해서 쓰는 거

bat
배치 파일(batch file)
배치 스크립트 파일
운영체제에서 쓰는 파일

set CLASSPATH=bin\main;

java -cp bin/main com.eomcs.study.App

나 대신 명령어를 쳐줌

App이라고 치면 .bat 파일이 있는지 먼저 찾아봄
.exe 이라는 파일이 있는지 찾아봄
.com 이라는 파일이 있는지 찾아봄

이클립스는 자바 클래스 실행 안 함
실행하는 건 JVM
내가 이런 명령어를 직접 입력하는 대신 이클립스가 대신 명령어를 대신 실행한 것 뿐
Run 버튼 누르면 JDK를 사용해서 classpath 환경변수를 설정한 다음에 JVM을 이용해서 클래스를 실행하는 것 뿐
이클립스는 내가 직접 실행해야 되는 걸 대신 실행할 뿐
내가 실행하는 대신 이클립스가 대신 실행하는 거
이클립스는 편집기일뿐
이 클래스에 어떤 메소드가 있는지 Outline도 보여주고
실행했을 때 출력결과를 Console에서 보여주고
한눈에 일목요연하게 볼 수 있게 도와주는 도구일 뿐
이클립스는 컴파일러 기능도 없고 JVM 기능도 없음
다만 나 대신 JDK에 있는 컴파일러를 사용해서 대신 컴파일 하는 거고
나 대신 JVM을 사용해서 대신 실행해주는 거
이클립스는 컴파일러, JVM이 아니다. 다만 나 대신 대행해줄 뿐.
JDK 설치할 때 포함된 JVM을 실행
다만 JDK를 사용할 뿐이다.
이클립스도 나랑 똑같은 입장
다른 개발자가 만든 코드를 사용하려면

$ java com.eomcs.study.App

자바에서 기본으로 제공하는 명령 코드들(library) *.jar 에 들어있음
명령 코드들 = Library
보통 jar 안에 들어 있다.
기본으로 제공되는 라이브러리는 따로 클래스 경로를 알려줄 필요가 없음

.jar(Java Archive)
.war(Web Archive)
.tar(Tape Archive)
.ear(Enterprise Archive)

외부 라이브러리 사용

외부 라이브러리인 경우
App을 실행할 때 라이브러리 파일의 경로를 따로 알려줘야 한다.
안 알려주면 JVM이 외부 라이브러리를 못 찾음. 사용 못 함.
알려줄 때 어떻게 알려준다? 바로 CLASSPATH 환경변수에 등록한다.

-classpath [외부 라이브러리 경로, ...]

$ java -classpath [외부 라이브러리 경로, ...] com.eomcs.study.App

archive
.tar(tape archive)
예전(1950~1980)에 백업할 때 테이프 드라이브에 보관했다.
보관하기 전에 백업파일을 하나로 묶고 작업을

외부 라이브러리
App을 실행할 때 jar 파일의 경로를 따로 알려줘야 된다.
CLASSPATH 환경 변수에 등록한다.

이클립스가 알아서

이클립스가 나 대신 이 명령어를 실행하는 것 뿐임
이클립스가 이런 식으로 도와주는구나

61개의 외부 라이브러리를 참조하고 있는데 실행할 때마다 JVM이 찾을 수 있도록 CLASSPATH 환경 변수에 등록해야 됨

App.java를 먼저 실행시키니까 됨
왜?
App을 왜 실행해야 되는지
App이라는 클래스는 외부 라이브러리를 쓴다
먼저 외부라이브러리 경로를 설정을 해줘야 된다
App이라는 클래스는 SpringApplication를 쓰고
이클립스에서 Ctrl 키 누른 상태로 클릭하면 그 코드로 이동함
그래서 우리가 Referenced Libraries들을 다 등록한 거임
단축키로 등록
별명
61개 다 나열 안 하고 단축 형태로 쓴 거임

2교시 시작

스프링 부트 실행

$ java -cp ... com.eomcs.study.App

JVM이 App 클래스를 실행
App.class에서 스프링 부트를 실행
스프링 부트에서
Web Server, Servlet Container를 실행
Servlet Container가 Spring Web MVC를 실행
Spring Web MVC에서 Exam1, Exam2 실행

Web Server는 HTML, CSS, JS 실행

Servlet Container, Web Server가 한 묶음으로 동작하는데
이게 바로 Tomcat Server
스프링 부트가 Tomcat Server를 실행시킴

Exam1, Exam2를 실행하려면 스프링 부트가 실행되어야 함
스프링 부트를 실행시키는 건 App.class
App을 실행해야 위에 있는 것들이 돌아감

App 클래스를 실행시켜야지 웹에 나오는 거

Web Browser가 Web Server에게 요청을 하고 Web Server가 응답을 한다.

둘 사이는 HTTP 프로토콜에 따라서 통신한다.
우리는 브라우저를 사용하는 사용자

Exam1을 실행하려면 스프링 부트를 실행해야 되고 스프링 부트를 실행하려면 App.class를 실행해야 된다.

스프링 부트를 실행하는 방법이 뭐다?
한 줄의 문장
스프링 부트를 실행하는 명령문

SpringApplication.run(App.class, args);

Java Virtual Machine이 없으면 실행시킬 수 없고
App.class가 없으면 App class의 main 메소드가 없기 때문에 스프링 부트를 실행하는 명령문을 실행시킬 수 없어서 스프링 부트가 실행이 안 된다.

App.class가 실행된 채로 Exam1 테스트 하는 거
App.class를 실행 안 시키면 Exam1 실행이 안 됨

App.class 실행중이면 실행 멈추고 http://localhost:8080/lang/literal/exam1/test1

클래스에 엔트리 포인트가 없어서 아무것도 안 뜸
main 메소드가 없어서

Run As 보면 아무것도 안 나옴

App 클래스는 있음

이클립스는 실행할 게 없으면 가장 최근에 실행한 클래스를 실행함

App 클래스 Run 버튼 클릭

명령문, 메서드, 클래스, 패키지

@RequestMapping("/lang/literal/exam1")

@GetMapping("/test1")

명령문

메서드
특정 기능을 수행하는 명령문들의 묶음

클래스
특정 역할을 수행하는 메서드들의 묶음

패키지
비슷한 역할에 따라 클래스를 분류

// 리터럴 : 정수 리터럴이 표현할 수 있는 값의 범위

package com.eomcs.study.lang.literal;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/lang/literal/exam3")
public class Exam3 {

  @GetMapping("/test1")
  public String test1() {
    return "정수: " + 21_0000_0000;
    // 문자열과 숫자를 더하면?
    // 문자열 + (숫자 --> 문자열) = 한 개의 문자열로 합친다.
  }

}

http://localhost:8080/lang/literal/exam3/test1

return "정수: " + 21_4748_3647;

// 리터럴 : 정수 리터럴이 표현할 수 있는 값의 범위

package com.eomcs.study.lang.literal;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/lang/literal/exam3")
public class Exam3 {

  @GetMapping("/test1")
  public String test1() {
    return "정수: " + 21_4748_3647;
    // 문자열과 숫자를 더하면?
    // 문자열 + (숫자 --> 문자열) = 한 개의 문자열로 합친다.
  }

  @GetMapping("/test2")
  public String test2() {
    return "정수: " + -21_4748_3648;
  }

}

Data 크기와 메모리 관계

메모리는 비트로 이루어져 있다.

전기를 채우는 공간
① 완전히 채우거나
② 안 채우거나
⟶ 2가지 상태만 가능

채우는 것을 제어하는 것도 힘들고
얼마 만큼 채워졌는지 알아내는 것도 힘듦
채워진 전기의 양을 알아내는 것도 힘듦

정교하면 정교할수록 많은 비용이 듦

메모리의 값을 어떻게 지정하느냐

① 메모리에 값 저장?
비트의 전기를 채우고 안 채우고로 표현
bit에 전기를 채우고 / 안 채우고 상태로 표현

1 bit
빈 상태 : 0
전기가 찬 상태 : 1

2 bit

값은 우리가 정하기 나름

4 bit가 주어진다면?

숫자 메모리 따로 있고 색상 메모리 따로 있고 그런 게 아님
메모리에 저장되는 형태는 다 똑같음
메모리에 저장할 때는 전기적 신호로 저장됨
규칙은 우리가 정하는 거

값(Data)을 메모리에 저장?

그게 숫자든 문자든 색상이든 소리든 뭐든지 간에
비트의 전기적 상태로 값을 표현
단, 규칙에 따라
규칙이 필요

전기적 신호로 표현할 때 규칙이 필요하다.

데이터에 상관 없이 메모리는 전기가 있냐 없냐의 상태로 표현한다.

비트의 전기 상태를 표현하는 간단한 방법?

있다 없다를 표현하는 방법 중에서 가장 간단한 방법

2진수 표기법

1과 0으로 표현

전기가 있는 상태를 1
없는 상태를 0

값을 메모리에 저장

값에 대한 2진수 표현 규칙을 정의

어떤 값이든 2진수로 표현할 수 있다면 메모리의 전기적 상태로 저장할 수 있다.

메모리만 봤을 때는 어떤 게 숫자 9이고 어떤 게 문자 I인지 구분 못 함

그러니까 저장할 때 내가 지정을 해줘야 됨

숫자인지 문자인지 알려줘야 1001을 9로 출력하든지 I로 출력하든지 함

메모리 입장에서는 숫자 9와 문자 I의 비트 상태가 같다.
→ 읽는 쪽에서 구분해야 한다.

어떤 값이든 2진수로 바꿀 수만 있으면 비트로 저장할 수 있다.

어떤 값이든 비트에 저장하려면 2진수로 바꿀 수만 있으면 비트에 저장할 수 있음

값(Data)과 2진수의 관계

2진수로 표현할 수 있으면 저장할 수 있다.

메모리에 저장하려면 2진수로 표현할 수 있어야 한다. ⟹ 규칙이 필요

여기서 나온 규칙이 바로~~!

숫자는 2의 보수법

문자는 charset (문자 집합, character set) : ASCII, UTF-8, EUC-KR

색상은 RGB(빛의 3원색) : 빨강(R), 초록(G), 파랑(B)의 3원색

소리는 주파수 크기

냄새는 아직 2진수로 표현하는 규칙이 없다.
그래서 냄새를 저장할 수 없음.

2진수로 표현할 수 없는 건 저장할 수 없다

짠맛, 단맛, 신맛

2진수로 바꿀 수 있으면 비트로 표현할 수 있다.
그래서 2진수가 아주 중요하다.

실무에서는 Servlet만 쓰고 웹 서버 따로 띄움
그걸 스프링 부트와 연동하는 거
스프링 부트에 내장된 웹 서버 대신 실무에서는 바깥에 웹 서버를 따로 띄운다
톰캣에 있는 건 Servlet Container만 씀

3교시 시작

메모리의 크기와 값의 범위

정수가 메모리에 저장되는 방법부터 알아야 됨
정수의 2진수 변환 규칙
그 전에 메모리 크기와 값의 범위

메모리의 크기와 표현 가능 값의 범위

1 byte = 8 bit

정수를 2진수로 변환하는 규칙

128 64 32 16 8 4 2 1

① Sign-Magnitude (절대 부호 방식)
부호 절대값 방법
부호 절대값 방법은 최상위비트(MSB, Most Significant Bit)를 부호 비트로 사용하는 방법으로(부호 비트가 0이면 양수, 1이면 음수), 이 방법을 사용하면 이진수의 계산에 문제가 발생한다.

+5 → 0 101
-5 → 1 101

맨 앞에 있는 게 부호 비트

sign-magnitude 방법의 문제점 : 양수와 음수의 더하기가 불가능

+5-5를 더하면 0이 나와야 되는데 안 나옴

+5  0101
-5  1101
----------
 0  0010 = 2  ← 0이 아님

그래서 등장한 게 1의 보수 방법

② 1의 보수 (one’s complement)
숫자 + 보수 = 1
보수 : 보충하는 값
1이 되기 위해서 보충해주는 수
예를 들어 0이 1이 되려면 1을 보충해야 됨

양수의 각 비트를 뒤집어서 음수를 만든다.

각각의 비트에 대해서

+5  0101
-5  1010  ← -5
----------
 0  1111 = 15  ← 0이 아님

1을 더하면

 1111
+   1
------
 0000 = 0
+4  0100
-2  1101  ← 2(0010)의 1의 보수
----------
    0001 = 1
   +   1
----------
    0010 = 2

1의 보수 문제점 : 계산 결과에 1을 더해야만 정확해진다.

처음부터 음수를 만들 때 미리 1을 더해놓으면 되잖아요

2의 보수가 그래서 등장함

③ 2의 보수 (two's complement)

음수의 경우 1의 보수로 만든 후 미리 1을 더해준다.

+5 = 0101
-5 = 1010
     +  1 ← 미리 1을 더해준다.
   -------
     1011 ← 2의 보수
+5  0101
-5  1011  ← 2의 보수
----------
 0  0000  ← 0이 됨
+4 = 0100
-2 = 1101  ← 1의 보수
    +   1
   -------
     1110  ← 2의 보수
+4  0100
-2  1110  ← 2의 보수
----------
 2  0010  ← 2가 됨
-4 = 1011  ← 1의 보수
    +   1
   -------
     1100  ← 2의 보수
+2 = 0010  
-4  1100  ← 2의 보수
+2  0010  
----------
-2  1110  ← -2가 됨

현대 컴퓨터 대부분이 정수를 2진수로 표현할 때 2의 보수 방법을 사용한다.
⟹ 빼기 대신에 음수를 더하면 된다.
⟹ 빼기 연산이 필요 없다.

양수는 그대로. 음수에 2의 보수 사용.

com.eomcs.lang.ex03.Exam0240.java - eomcs-java-lang/src/main/java

④ K-초과(Excess-K)

음수 또는 양수에 K값을 더해서 결괏값을 만든다. 결괏값을 2진수로 표현한다.

음수/양수 + K값 = 결과값 → 2진수

k값은 2^(비트수 - 1) 제곱

예를 들어 4비트라면
2^(4-1) = 2³ = 8
k = 8

메모리 크기와 정수의 범위

4 bit = -8 ~ 7 (16개 상태)
0 ~ 7 (8개, 0 포함) 양수는 항상 음수보다 1개 적다
-1 ~ -8 (8개)

1의 보수나 부호 절댓값 +0 -0이 존재함
2의 보수는 그냥 0만 있음

Sign-Magnitude 방법과 1의 보수 방법의 문제점 : +0과 -0 존재

+1 0001
-1 1110

+0 0000  ← +0 ??
-0 1111  ← -0 ??

그게 16진수

16진수로 표현하면 간결함

모든 비트가 0인 경우
모든 비트가 1인 경우

1과 0으로
2진수로 하기엔 너무 숫자가 길어
2진수를 최대한 줄일 수 있는 거
줄이더라도
10진수 2진수로 바꾸고 2진수를 10진수로 바꾸는 건 계산을 해야 돼서 번거로움
16진수로 바꾸는 건 간단함. 4비트씩 끊으면 됨. 다시 2진수로 바꾸고 싶으면 4비트 2진수로 바꾸면 됨.

개발자 입장에서는 2진수가 훨씬 직관적임.
근데 32비트를 다 쓴다고 생각하면 너무 불편
2진수가 너무 기니까 표기의 편의성을 위해서 16진수를 사용하는 거

비트들에 전기가 있냐 없냐
어떤 값이든 2진수로 바꿀 수만 있다면 무조건 메모리에 저장할 수 있다.
2진수로 바꿀 수만 있다면 무엇이든 가능하다.

자바에서 정수는
1 byte 정수, 2 byte 정수, 4 byte 정수, 8 byte 정수로 다루게 된다.

메모리 크기 제약 조건 때문에 담을 수 있는 숫자의 범위가 정해진다.
한계가 정해진다.

자바의 정수 리터럴

자바의 정수 리터럴은 크게 4 byte 정수 리터럴과 8 byte 정수 리터럴로 나뉘어 진다.

리터럴은 딱 두 가지

① 4 byte 정수 리터럴
100
4 byte 메모리 사용
숫자 뒤에 접미사를 안 붙이면 4 byte 메모리 사용하는 거

② 8 byte 정수 리터럴
뒤에 접미사를 붙인다.
대문자 L 또는 소문자 l
100L
100l
8 byte로 저장
8 byte 메모리 사용

4 byte 메모리에 표현할 수 있는 값의 범위는 -21_4748_3648 ~ 21_4748_3647

숫자 하나를 늘리는 순간 32 bit 범위를 넘어간다. 오버플로우 발생!!
리터럴 범위 넘어갔어!! 라고 빨간밑줄로 알려줌.
그럴 땐 뒤에 접미사 L 붙여주면 빨간밑줄 사라짐.
8 byte 메모리를 사용하라고 표시한다.

BigInteger

// 리터럴 : 정수 리터럴이 표현할 수 있는 값의 범위

package com.eomcs.study.lang.literal;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/lang/literal/exam3")
public class Exam3 {

  @GetMapping("/test1")
  public String test1() {
    // return "정수: " + 21_4748_3648; // 컴파일 오류! 4 byte 메모리에 저장할 수 없다.
    return "정수: " + 21_4748_3647;
    // 문자열과 숫자를 더하면?
    // 문자열 + (숫자 --> 문자열) = 한 개의 문자열로 합친다.
  }

  @GetMapping("/test2")
  public String test2() {
    // return "정수: " + -21_4748_3649; // 컴파일 오류! 4 byte 메모리에 저장할 수 없다.
    return "정수: " + -21_4748_3648;
  }

  @GetMapping("/test3")
  public String test3() {
    return "정수: " + 21_4748_3647L; // OK! 리터럴을 저장할 때 8 byte 메모리를 사용하라고 표시한다.
  }

  @GetMapping("/test4")
  public String test4() {
    return "정수: " + -21_4748_3648l; // OK! 리터럴을 저장할 때 8 byte 메모리를 사용하라고 표시한다.
  }

}
// 리터럴 : 정수 리터럴이 표현할 수 있는 값의 범위

package com.eomcs.study.lang.literal;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/lang/literal/exam3")
public class Exam3 {

  @GetMapping("/test1")
  public String test1() {
    // return "정수: " + 21_4748_3648; // 컴파일 오류! 4바이트 메모리에 저장할 수 없다.
    return "정수: " + 21_4748_3647;
    // 문자열과 숫자를 더하면?
    // 문자열 + (숫자 --> 문자열) = 한 개의 문자열로 합친다.
  }

  @GetMapping("/test2")
  public String test2() {
    // return "정수: " + -21_4748_3649; // 컴파일 오류! 4바이트 메모리에 저장할 수 없다.
    return "정수: " + -21_4748_3648;
  }

  @GetMapping("/test3")
  public String test3() {
    return "정수: " + 21_4748_3648L; // OK! 리터럴을 저장할 때 8바이트 메모리를 사용하라고 표시한다.
  }

  @GetMapping("/test4")
  public String test4() {
    return "정수: " + -21_4748_3649l; // OK! 리터럴을 저장할 때 8바이트 메모리를 사용하라고 표시한다.
  }

  @GetMapping("/test5")
  public String test5() {
    return "정수: " + 922_0000_0000_0000_0000L; // OK! 리터럴을 저장할 때 8바이트 메모리를 사용하라고 표시한다.
  }

  @GetMapping("/test6")
  public String test6() {
    return "정수: " + -922_0000_0000_0000_0000l; // OK! 리터럴을 저장할 때 8바이트 메모리를 사용하라고 표시한다.
  }

}

정수 리터럴은 크게 두 가지가 있다.
4 byte 정수 리터럴은 여태까지 표현했던 거
알고 봤더니 8 btye 정수 리터럴 표기법이 있더라
그러면 4 byte를 넘어가는 값은 8 byte 정수 리터럴로 표기하면 됨
끝에다 대문자 L 또는 소문자 l을 붙이면 된다.

4교시 시작

숫자 뒤에 대문자L 또는 소문자l을 붙이는 것

실제 값이 메모

범위가 있는데 그 이유가 무엇인지
메모리 크기에 달려있구나
메모리는
정수 기본 4 byte (32 bit)
-21억 ~ 21억
이 범위를 넘어서는 값을 표현하고 싶으면 8 byte 정수 리터럴
끝에 대문자 L 또는 소문자 l을 붙이면 된다

Exam4.java

부동소수점이 메모리에 저장되는 원리

부동소수점을 메모리에 저장하는 방법

부동소수점을 2진수화 시켜야 메모리에 저장할 수 있다.

12.375

① 소수점 앞의 정수값
12 → 1100

② 소수점 뒤의 정수값
0.375 * 2 = 0.75 → 0
0.75 * 2 = 1.5 → 1
0.5 * 2 = 1.0 → 1
⟹ 0.375 → 0.011

③ 소수점 앞 2진수 + 소수점 뒤 2진수
1100.011

④ 정규화를 수행하여 소수점을 없앤다

소수점이 어디에 있는지 상관없이 뒤에 어떤 값을 곱하느냐에 따라 같은 값

소수점 위치가 정해져 있지 않다.

부동(float)
浮動 뜰 부, 움직일 동

정규화 → 소수점을 없앤다

소수점 왼쪽에 1만 남게 하라

1.100 011

원래 값이 되려면 2³을 곱해야 된다.

소수점 왼쪽의 숫자 1을 버린다.

소수점 왼쪽은 무조건 1임. (이진수니까)

소수점 왼쪽에 있는 숫자를 버린다.

0.100 011 × 2³

그리고 이걸 메모리에 저장한다.

32bit(4byte) 메모리에 저장한다.

첫 번째 비트는 부호 비트 (양수면 0, 음수면 1)

지수부에 3이라는 값을 그대로 저장하지 않는다.

Excess-K 형식으로 저장한다.

3 + (2)

130을 2진수로 저장

4146000

// 리터럴 : 부동소수점 리터럴과 값의 범위

package com.eomcs.study.lang.literal;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/lang/literal/exam4")
public class Exam4 {

  static float x = 12.375f;

  @GetMapping("/test1")
  public String test1() {
    return "부동소수점: " + 3.14f;
  }

}

갑자기 안 됨

IEEE (아이 트리플 이)

https://www.h-schmidt.net/FloatConverter/IEEE754.html

64비트 메모리에 담기

1026 = 0100 0000 0010

부동소수점 리터럴

소문자 f를 많이 씀

8비트는 안 적는 걸 선호

안 붙이는 게 편함

부동소수점을 쓸 때는 가능하면 8바이트 부동 소수점 사용을 권장

정수는 대문자 L

붙이면 불편

정수는 4바이트 주로 사용

부동소수점은 8바이트에 아무것도 안 붙임

5교시 시작

메모리 크기에 따른 부동소수점 값의 범위

소수점 앞의 정수값 → 2진수화 → 정규화 처리

이 과정을 통해 메모리에 값이 저장되기 때문에 명확하게 범위를 산정할 수 없다.

소수점 앞 자리수, 소수점 뒷자리수도 결정할 수 없다.

소수점은 움직이니까

다만 IEEE-754 방식에 따라 2진수로 바꾸더라도 값이 잘리지 않는 범위를 대략적으로 알 수 있다.

4 byte는 소수점을 제거했을 때 7개의 숫자라면 거의 99.9% 메모리에 저장할 수 있다.

유효자릿수라 부른다.

8 byte는 소수점 제거 후 15개의 숫자라면 거의 99.9% 메모리에 저장할 수 있다.

8 byte 메모니는 4 byte 메모리보다 2배 더 많은 수를 저장할 수 있다.

2배 더 정밀한 수 저장 가능

single precision 단정도
double precision 배정도

부동소수점의 유효범위

8 바이트 → 15자리 유효 (그 이상의 숫자는 짤린다.)

9.876543211234567f

부동소수점은 반올림 처리가 중요하다.

부동소수점을 이진수로 완벽하게 못 바꿀 때

15자리나 16자리나 비슷하다.

3차원 좌표 계산할 때 부동소수점이 쓰임

3D 세계에서 좌표의 변환은 반드시 부동소수점을 생성시킨다.
3D 그래픽 처리는 부동소수점 연산을 많이 수행한다.
CPU에 부담을 준다.
GPU가 담당을 하게 된다.

부동소수점을 활용하는 또다른 분야

암호
비트코인
GPU
CPU를 쓰는 게 아니라 GPU를 쓰게 됨
그래픽카드
비트코인 채굴기

0개의 댓글