반응형
SMALL

Node.js란?

Node.js는 Chrome V8 엔진으로 구동되는 JavaScript 런타임 환경이다.
즉, JavaScript를 브라우저가 아닌 서버에서도 실행할 수 있도록 만든 플랫폼이다.

🚀 쉽게 말해?
원래 JavaScript는 웹 브라우저에서만 실행되던 언어인데,
Node.js 덕분에 서버에서도 실행할 수 있게 됐다!

 

Node.js는 비동기 방식을 기본적으로 사용한다.
즉, 한 가지 작업이 끝날 때까지 기다리지 않고, 다음 작업을 실행한다.

 

Node.js는 기본적으로 단일 스레드(Single-threaded)로 작동하지만,
비동기 작업을 활용해 여러 작업을 동시에 처리할 수 있다.
I/O 작업(파일 읽기, 네트워크 요청 등)은 블로킹 없이 처리된다.

 

Windows, macOS, Linux 등 다양한 운영체제에서 실행 가능

오픈소스로 누구나 자유롭게 사용 가능

 

Node.js는 package.json 파일에 프로젝트의 모든 정보를 기록한다. 각 항목의 의미는 다음과 같다.

name: 프로젝트 이름
version: 프로젝트 버전 정보
description: 프로젝트 설명
main: 노드 어플리케이션일 경우 진입점 경로. 프론트엔드 프로젝트일 경우 사용하지 않는다.
scripts: 프로젝트 명령어를 등록할 수 있다.초기화시 test 명령어가 샘플로 등록되어 있다
author: 프로그램 작성자
license: 라이센스



🚀 1. 자바스크립트의 발전 속도 vs. 브라우저의 지원 속도

자바스크립트는 계속 새로운 기능이 추가되지만, 브라우저가 그 기능을 바로 지원하지 못하는 경우가 많다.
👉 최신 기능을 쓰려면 "징검다리 역할"을 하는 도구가 필요하다.
대표적으로 "Babel(바벨)"이 있는데, 이건 최신 자바스크립트 코드를 옛날 브라우저에서도 실행되도록 변환해 준다.

 


🔧 2. 개발을 더 편하게 해주는 도구들

프론트엔드 개발을 할 때는 여러 가지 도구들이 필요하다.
예를 들어:
✔ Webpack(웹팩): 여러 개의 자바스크립트, CSS, 이미지 같은 파일을 하나의 번들(Bundle)로 묶어주는 도구다.

👉 웹 개발을 하다 보면, 파일이 너무 많아지고 관리하기 힘들어지기 때문!
👉 여러 개의 파일을 하나로 합쳐서 성능을 최적화하면, 웹사이트 로딩 속도가 빨라진다!

🔹 웹팩이 하는 일
- 자바스크립트 파일 묶기 (import 또는 require로 불러온 파일들을 하나로 합침)
- CSS, 이미지 파일도 포함 가능 (예: SCSS, SASS, LESS 변환)
- 코드 압축 & 최적화 (파일 크기를 줄여서 로딩 속도를 빠르게!)
- 실시간 변경 적용 (Hot Reloading) (파일을 수정하면 자동으로 반영됨)

 

 

✔ NPM: 패키지 관리자로, 필요한 라이브러리를 쉽게 설치하고 관리할 수 있도록 도와줌
👉 개발할 때 남들이 만든 유용한 기능을 가져다 쓰면 더 빠르고 효율적으로 작업 가능!
👉 하지만, 일일이 파일을 다운로드하면 업데이트 관리가 어렵고 버전 충돌 위험이 있음.
👉 NPM을 사용하면, 명령어 하나로 패키지 설치 및 업데이트 가능!

 


이런 도구들은 Node.js 기반에서 동작하므로, Node.js가 설치되어 있어야 개발 환경을 만들 수 있다.

 


🎨 3. 고급 언어를 사용하려면 변환 과정이 필요하다

기본적인 HTML, CSS, JavaScript 외에도, 개발자들이 더 편하게 사용할 수 있는 언어들이 있다.

 

✔ TypeScript(타입스크립트): 자바스크립트를 더 체계적으로 작성할 수 있도록 도와줌

👉  마이크로소프트(Microsoft)에서 개발한 자바스크립트(JavaScript)의 상위 집합(Superset) 언어로, 자바스크립트의 기능을 확장하면서 정적 타입 검사(Static Type Checking) 및 객체 지향 프로그래밍(OOP) 기능을 추가한 언어이다.
👉  즉, TypeScript = JavaScript + 타입 시스템 + ES6 이상의 기능들


✔ SASS(사스): CSS를 더 강력하고 효율적으로 작성할 수 있도록 도와주는 CSS 전처리기(Preprocessor)

👉   CSS의 단점을 보완하여 변수, 중첩, 믹스인, 상속 등 프로그래밍적인 기능을 추가할 수 있다.
👉   SASS 파일(.scss 또는 .sass)을 작성한 후, 일반 CSS 파일로 변환해야 한다.

 

더보기

✅ SASS는 CSS를 더 강력하고 효율적으로 사용할 수 있도록 도와주는 도구다.
✅ 변수, 중첩, 믹스인, 상속 등 코드 재사용 기능을 제공하여 유지보수가 쉬워진다.
✅ SASS 파일을 작성한 후, CSS로 변환해야 웹에서 사용할 수 있다.
✅ 웹 개발에서 CSS보다 SASS를 많이 사용하며, 웹팩(Webpack)과 함께 자동 변환하는 것이 일반적

 

✏ SASS 기본 문법


SASS는 두 가지 문법을 제공한다.
1️⃣ .scss (가장 많이 사용됨, 일반 CSS와 비슷한 문법)
2️⃣ .sass (중괄호 {}와 세미콜론 ; 없이 들여쓰기로 구분)

🔹 1. 변수 사용 ($)

// SASS (SCSS 문법)
$main-color: #3498db; // 변수 선언

body {
  background-color: $main-color; // 변수 사용
}

//⬇ CSS 변환 후 ⬇
body {
  background-color: #3498db;
}

✔ 색상, 폰트 크기, 여백 등을 변수로 관리하면 유지보수가 쉬워진다!

 

🔹 2. 중첩(Nesting)

// SASS
.navbar {
  background: #333;
  color: white;
  
  a {
    text-decoration: none;
    color: inherit;

    &:hover {
      color: yellow;
    }
  }
}


//⬇ CSS 변환 후 ⬇
.navbar {
  background: #333;
  color: white;
}

.navbar a {
  text-decoration: none;
  color: inherit;
}

.navbar a:hover {
  color: yellow;
}

✔ 중첩을 사용하면 CSS 계층 구조를 더 직관적으로 표현할 수 있다.

 

 

🔹 3. 믹스인(Mixin) – 코드 재사용

// SASS
@mixin button-style {
  padding: 10px 20px;
  border-radius: 5px;
  background-color: blue;
  color: white;
}

// 믹스인 사용
.button {
  @include button-style;
}


//⬇ CSS 변환 후 ⬇
.button {
  padding: 10px 20px;
  border-radius: 5px;
  background-color: blue;
  color: white;
}

✔ 반복되는 스타일을 함수처럼 만들어서 재사용할 수 있다!

 

🔹 4. 상속(Extend) – 스타일 공유

// SASS
%box-style {
  border: 1px solid #ddd;
  padding: 10px;
  border-radius: 5px;
}

.card {
  @extend %box-style;
  background: white;
}

.alert {
  @extend %box-style;
  background: red;
  color: white;
}


//⬇ CSS 변환 후 ⬇
.card, .alert {
  border: 1px solid #ddd;
  padding: 10px;
  border-radius: 5px;
}

.card {
  background: white;
}

.alert {
  background: red;
  color: white;
}

✔ 공통 스타일을 상속받아 중복을 줄이고 코드 유지보수를 쉽게 할 수 있다.

 

 


하지만!
👉 브라우저는 TypeScript와 SASS를 직접 이해하지 못한다.
👉 그래서 "트랜스파일러"라는 변환 도구를 사용해서 자바스크립트와 CSS로 변환해야 한다.

 

 

대표적인 트랜스파일러 = Babel(바벨)

 

🎯 Babel(바벨)이란?

최신 자바스크립트 코드를 구형 브라우저에서도 실행할 수 있도록 변환해주는 도구(트랜스파일러)다.

 

자바스크립트는 계속 새로운 기능이 추가되지만, 모든 브라우저가 최신 기능을 바로 지원하는 것은 아니다.
✔ 크롬, 파이어폭스 같은 최신 브라우저는 대부분 지원하지만,
✔ 인터넷 익스플로러(IE)나 오래된 브라우저에서는 실행되지 않는 경우가 많다.

👉 Babel을 사용하면 최신 문법을 옛날 브라우저에서도 실행 가능하도록 변환할 수 있다!

👉  React, Vue 같은 최신 프레임워크를 사용할 때 (JSX 같은 문법을 변환하는 데에도 사용됨)

 

Babel이 변환하는 대표적인 문법
1. 화살표 함수 (=>) 변환

// 최신 문법 (ES6+)
const add = (a, b) => a + b;

// ES5 (옛날 브라우저도 실행 가능)
var add = function (a, b) {
    return a + b;
};

 

2. const, let 같은 최신 변수 선언 변환

// 최신 문법 (ES6+)
const name = "Alice";
let age = 25;

// ES5
var name = "Alice";
var age = 25;

 

3. 클래스 문법 변환

// 최신 문법 (ES6+)
class Person {
    constructor(name) {
        this.name = name;
    }
}

// ES5
function Person(name) {
    this.name = name;
}

 

Babel은 단독으로 사용하기도 하지만, 보통 Webpack과 함께 사용하여 자동 변환한다.

 


💡 결론
최신 웹 개발 환경을 만들려면, 단순히 HTML + CSS + JavaScript만 쓰는 게 아니라,
✔ Babel, Webpack 같은 도구를 사용해야 하고
✔ TypeScript, SASS 같은 고급 언어를 변환할 필요도 있으며
✔ 이 모든 걸 관리하려면 Node.js 환경이 필요하다!

즉, Node.js는 최신 프론트엔드 개발의 기반이 되는 필수 도구라고 볼 수 있다!

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

반응형
LIST

'[ javascript ]' 카테고리의 다른 글

스프레드 연산자 (...)란?  (0) 2025.02.27
대표적인 es6 문법 정리  (0) 2024.12.30
부동소수점 이슈  (0) 2024.03.29
Node.js & npm 업데이트 하기  (1) 2024.03.22
리액트란?  (0) 2024.03.19
반응형
SMALL

스프레드 연산자(...)는 배열, 객체, 문자열 등의 요소를 개별적으로 펼쳐서 사용할 수 있도록 해주는 JavaScript 연산자.

 

FullCalendar 사용할 때 아래처럼 eventSources에 일정을 배열로 넣어야하는데,

eventSources: [
    {
        id: "대한민국 공휴일",
        googleCalendarId: "ko.south_korea#holiday@group.v.calendar.google.com",
        color: "#FF0000",
        editable: false
    },
    {
        id: "일정2",
        color: "#FF0000",
        editable: false
    },
    ...
]

 

특정 eventList를 Map형태로 뽑아 전체를 넣기 위해 아래같이 사용함.

eventSources: [
    eventList.map(event => ({
        id: event.id,
        groupId: event.id,
        events: [],
        backgroundColor: event.bgColor,
    })), // ❌ 이렇게 하면 안됨
    {
        id: "대한민국 공휴일",
        googleCalendarId: "ko.south_korea#holiday@group.v.calendar.google.com",
        color: "#FF0000",
        editable: false
    }
]

문제는 eventList.map(...)이 이미 배열을 반환하기 때문에 이중배열([ [...mappedEvents], {...} ]) 형태가 되어 추가되지 않음.

 

이럴 때 사용하는게 스프레드 연산자!

   //이렇게 사용해야 한다.  
   eventSources: [
        ...eventList.map(event => ({ // 기본 이벤트 항목 추가
            id: event.id,
            groupId: event.id,
            events: [],
            backgroundColor: event.bgColor,
        })),
        {
            id: "대한민국 공휴일", // 대한민국 공휴일 추가
            googleCalendarId: "ko.south_korea#holiday@group.v.calendar.google.com",
            color: "#FF0000",
            editable: false
        }
    ],

 

 


📌 1. 배열에서의 스프레드 연산자 활용

배열을 복사하거나, 합칠 때 사용됩니다.

✅ 예제 1: 배열 복사 (얕은 복사)

const arr1 = [1, 2, 3];
const arr2 = [...arr1]; // arr1을 복사

console.log(arr2); // [1, 2, 3]


arr2 = [...arr1]를 사용하면 arr1의 개별 요소가 펼쳐져서 새로운 배열이 생성됩니다.

 

✅ 예제 2: 배열 합치기

const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];

const merged = [...arr1, ...arr2]; // 두 배열을 합침

console.log(merged); // [1, 2, 3, 4, 5, 6]


arr1과 arr2의 요소들이 개별적으로 풀려서 하나의 배열로 합쳐짐.

 

✅  예제 3: 배열의 중첩 구조 해결

const arr1 = [1, 2, 3];
const arr2 = [arr1, 4, 5];

console.log(arr2);
// [[1, 2, 3], 4, 5] <-- 배열이 중첩됨

const arr3 = [...arr1, 4, 5]; // 스프레드 연산자로 펼침

console.log(arr3);
// [1, 2, 3, 4, 5] <-- 중첩되지 않고 개별 요소가 추가됨

스프레드 연산자를 사용하면 배열의 중첩 없이 개별 요소로 추가할 수 있음.

 

📌 2. 객체에서의 스프레드 연산자 활용

객체를 복사하거나, 속성을 병합할 때 유용합니다.

 

✅ 예제 4: 객체 복사

 
const obj1 = { name: "Alice", age: 25 };
const obj2 = { ...obj1 }; // obj1을 복사

console.log(obj2); // { name: "Alice", age: 25 }

기존 객체를 새로운 객체로 복사하는 방법.

 

✅ 예제 5: 객체 속성 병합

 
const obj1 = { name: "Alice", age: 25 };
const obj2 = { job: "Developer", city: "Seoul" };

const mergedObj = { ...obj1, ...obj2 };

console.log(mergedObj);
// { name: "Alice", age: 25, job: "Developer", city: "Seoul" }

 

 

반응형
LIST

'[ javascript ]' 카테고리의 다른 글

Node.js 뜯어보기  (0) 2025.03.20
대표적인 es6 문법 정리  (0) 2024.12.30
부동소수점 이슈  (0) 2024.03.29
Node.js & npm 업데이트 하기  (1) 2024.03.22
리액트란?  (0) 2024.03.19
반응형
SMALL

1. let과 const

var 대신 블록 스코프(block scope)를 지원하는 let과 상수 선언용 const를 사용합니다.

let name = "Alice"; // 변경 가능
const age = 25;     // 변경 불가

if (true) {
  let name = "Bob";
  console.log(name); // "Bob"
}
console.log(name);   // "Alice"

 

 

2. 화살표 함수(Arrow Function)

간결한 함수 표현식입니다. this 바인딩이 기존 함수와 다르게 작동합니다.

// 일반 함수
function add(a, b) {
  return a + b;
}

// 화살표 함수
const add = (a, b) => a + b;

console.log(add(2, 3)); // 5

 

 

3. 템플릿 리터럴(Template Literal)

문자열 안에서 변수를 쉽게 포함할 수 있는 백틱(`) 문법.

const name = "Alice";
const message = `Hello, ${name}!`;
console.log(message); // "Hello, Alice!"

 

4. 디스트럭처링 할당(Destructuring Assignment)

객체나 배열의 값을 쉽게 추출하여 변수에 할당합니다.

// 배열
const [a, b] = [1, 2];
console.log(a, b); // 1, 2

// 객체
const user = { name: "Alice", age: 25 };
const { name, age } = user;
console.log(name, age); // "Alice", 25

 

5. 기본 매개변수(Default Parameters)

함수 매개변수에 기본값을 설정합니다.

const greet = (name = "Guest") => `Hello, ${name}!`;
console.log(greet()); // "Hello, Guest!"
console.log(greet("Alice")); // "Hello, Alice!"

 

6. 스프레드 연산자(Spread Operator)

배열이나 객체를 쉽게 복사하거나 병합할 수 있습니다.

// 배열
const numbers = [1, 2, 3];
const moreNumbers = [...numbers, 4, 5];
console.log(moreNumbers); // [1, 2, 3, 4, 5]

// 객체
const user = { name: "Alice", age: 25 };
const updatedUser = { ...user, age: 30 }; // age 업데이트
console.log(updatedUser); // { name: "Alice", age: 30 }

 

7. 클래스(Class)

ES6에서는 객체 지향 프로그래밍을 더 쉽게 작성할 수 있는 class 문법을 제공합니다.

class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }

  greet() {
    return `Hello, my name is ${this.name}.`;
  }
}

const alice = new Person("Alice", 25);
console.log(alice.greet()); // "Hello, my name is Alice."

 

8. 모듈(Modules)

ES6에서는 import와 export를 사용하여 모듈을 구성합니다.

// module.js
export const greet = (name) => `Hello, ${name}!`;

// main.js
import { greet } from './module.js';
console.log(greet("Alice")); // "Hello, Alice!"

 

9. 프로미스(Promises)

비동기 작업을 처리하는 새로운 방식.

const fetchData = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => resolve("Data loaded!"), 1000);
  });
};

fetchData().then((data) => console.log(data)); // 1초 후 "Data loaded!"

 

10. 맵(Map)과 셋(Set)

새로운 자료 구조를 지원합니다.

// Map
const map = new Map();
map.set("key", "value");
console.log(map.get("key")); // "value"

// Set
const set = new Set([1, 2, 3, 3]);
console.log(set); // Set(3) { 1, 2, 3 }

 

11. for...of 루프

이터러블 객체(배열 등)를 순회하기 위한 새로운 루프.

const array = [10, 20, 30];
for (const value of array) {
  console.log(value); // 10, 20, 30
}

 

 

12. 심볼(Symbol)

고유한 식별자를 생성할 때 사용.

const sym = Symbol("unique");
console.log(sym); // Symbol(unique)

 

13. Rest 파라미터(Rest Parameters)

함수 호출 시 전달되는 나머지 매개변수를 배열로 모아 처리할 수 있습니다.

const sum = (...numbers) => {
  return numbers.reduce((total, num) => total + num, 0);
};

console.log(sum(1, 2, 3, 4)); // 10

 

14. Symbol.iterator와 이터러블(Iterables)

객체를 이터러블로 만들어 for...of 문이나 spread 문법에서 사용할 수 있습니다.

const iterable = {
  *[Symbol.iterator]() {
    yield 1;
    yield 2;
    yield 3;
  }
};

for (const value of iterable) {
  console.log(value); // 1, 2, 3
}

 

15. Object.assign

객체를 복사하거나 병합할 때 사용됩니다.

const target = { a: 1 };
const source = { b: 2, c: 3 };

const merged = Object.assign({}, target, source);
console.log(merged); // { a: 1, b: 2, c: 3 }

 

16. Object.entries와 Object.values

객체의 키와 값을 배열 형태로 반환합니다.

const obj = { a: 1, b: 2 };

// Object.entries
for (const [key, value] of Object.entries(obj)) {
  console.log(key, value); // "a 1", "b 2"
}

// Object.values
console.log(Object.values(obj)); // [1, 2]

 

17. includes 메서드

배열이나 문자열에 특정 값이 포함되어 있는지 확인합니다.

const fruits = ["apple", "banana", "cherry"];
console.log(fruits.includes("banana")); // true

const sentence = "Hello, world!";
console.log(sentence.includes("world")); // true

 

18. find와 findIndex

배열에서 조건에 맞는 첫 번째 요소나 그 인덱스를 반환합니다.

const numbers = [10, 20, 30, 40];

// find
const found = numbers.find(num => num > 25);
console.log(found); // 30

// findIndex
const index = numbers.findIndex(num => num > 25);
console.log(index); // 2

 

19. Promise.all과 Promise.race

복수의 프로미스를 동시에 처리합니다.

const p1 = new Promise(resolve => setTimeout(() => resolve("P1"), 1000));
const p2 = new Promise(resolve => setTimeout(() => resolve("P2"), 2000));

// Promise.all
Promise.all([p1, p2]).then(results => console.log(results)); // ["P1", "P2"]

// Promise.race
Promise.race([p1, p2]).then(result => console.log(result)); // "P1"

 

 

20. Default Import와 Named Import

ES6 모듈에서 다양한 방식으로 코드를 가져옵니다.

// module.js
export const greet = name => `Hello, ${name}!`;
export default name => `Hi, ${name}!`;

// main.js
import defaultGreet, { greet } from "./module.js";

console.log(defaultGreet("Alice")); // "Hi, Alice!"
console.log(greet("Bob"));         // "Hello, Bob!"

 

21. 태스크 큐와 마이크로태스크 큐(Task Queue & Microtask Queue)

Promise와 setTimeout의 실행 순서를 이해할 수 있는 개념입니다.

console.log("Start");

setTimeout(() => console.log("Timeout"), 0);
Promise.resolve().then(() => console.log("Promise"));

console.log("End");

// 출력 순서:
// Start
// End
// Promise
// Timeout

 

22. SetTimeout과 SetInterval에 화살표 함수 사용

화살표 함수는 this를 고정해 주므로 setTimeout 등에서 유용합니다.

class Timer {
  start() {
    this.seconds = 0;
    setInterval(() => {
      this.seconds++;
      console.log(this.seconds);
    }, 1000);
  }
}

const timer = new Timer();
timer.start();

 

23. Class와 Static 메서드

클래스에서 인스턴스 생성 없이 호출할 수 있는 메서드를 정의할 수 있습니다.

class MathUtils {
  static add(a, b) {
    return a + b;
  }
}

console.log(MathUtils.add(5, 3)); // 8

 

24. 다중 객체 병합과 스프레드

ES6의 스프레드 연산자를 활용한 다중 병합이 가능합니다.

const defaultConfig = { theme: "light", fontSize: 14 };
const userConfig = { fontSize: 16, language: "en" };
const finalConfig = { ...defaultConfig, ...userConfig };

console.log(finalConfig); // { theme: "light", fontSize: 16, language: "en" }

 

25. 지연 평가(Lazy Evaluation)

generator를 사용해 필요한 데이터만 계산하도록 구현 가능합니다.

function* generateSequence() {
  yield 1;
  yield 2;
  yield 3;
}

const generator = generateSequence();
console.log(generator.next().value); // 1
console.log(generator.next().value); // 2

 

반응형
LIST

'[ javascript ]' 카테고리의 다른 글

Node.js 뜯어보기  (0) 2025.03.20
스프레드 연산자 (...)란?  (0) 2025.02.27
부동소수점 이슈  (0) 2024.03.29
Node.js & npm 업데이트 하기  (1) 2024.03.22
리액트란?  (0) 2024.03.19
반응형
SMALL

부동소수점이란?

부동소수점 또는 떠돌이 소수점 방식은 실수를 컴퓨터상에서 근사하여 표현할 때 소수점의 위치를 고정하지 않고 그 위치를 나타내는 수를 따로 적는 것으로, 유효숫자를 나타내는 가수와 소수점의 위치를 풀이하는 지수로 나누어 표현한다. (출처 위키백과)

 

정리하자면 실수를 표시하기 위해 소수점을  근사값으로 표시하는 것.

 

사람과 컴퓨터의 숫자 표현 방법

컴퓨터 : 2진법

사람 : 10진법

 

컴퓨터는 2진법으로 데이터를 전부 표시하는데, 사람은 10진법으로 숫자를 표현한다. 즉, 숫자 표현법이 달라지는 데에서 이를 최대한 근사하게 표시하기 위한 방법이 필요하다. 본래 이진법에서는 십진수 소수가 정확히 표현되지 않고 근삿값으로 표현된다.

 

예시를 잘 들어주신 분이 있어서 예제를 가져와봄.(출처 : https://velog.io/@dacircle/부동소수점이란 )

10진수의 경우

  • 1/3을 소수로 나타내면 0.3333333333333333333333333333333333… 무한소수가 된다.
  • 10진법로도 정확히 나타낼 수 없는 수가 있다.. 그렇다면 다른 진법으로는 어떨까?

2진법의 경우

  • 9.625를 2진법으로 나타내면 다음과 같다.
    9 = 2³ + 2² + 2¹ + 2⁰ ⇒ 1001
    0.625 =1/2¹ + 1/2² + 1/2³ ⇒ 101
    9.625 = 1001.101
  • 1/10을 2진법으로 나타내면 다음과 같다.
    1/10은 0.1이므로 소수부분만 나타내면 된다.
    1/2¹ + 1/2² + 1/2³ + 1/2⁴ + 1/2⁵ + 1/2⁶ + 1/2⁷ + 1/2⁸ + 1/2⁹ + 1/2¹⁰ + 1/2¹¹ + 1/2¹² + 1/2¹³ …
    0.0001100110011…
    0.0999755859375…
    ⇒ 0.1이 아니다!

 

컴퓨터가 숫자를 저장하기 위해 2진법으로 소수부를 표현할 때,

10진법에서는 무한소수가 아닌 명확한 유한소수이더라도 2진법으로는 표현이 안될 때가 있다.

 

10진법으로는 0.1 + 0.2 === 0.3 일 수 있지만,

2진법에서는 0.1 + 0.2 는 0.30000000000000004 이므로 같다고 볼 수 없다.

 

부동소수점 해결 방법

 

  • 간단한 계산: 정수 변환 또는 Math.round()를 사용.
  • 높은 정확도가 필요한 계산: 부동소수점 문제를 해결하기 위한 전문적인 라이브러리를 사용 (Decimal.js 또는 Big.js 가 유명하다)
  • 실시간 비교: Number.EPSILON 기반 비교.

 

 

1. 정수로 변환하여 계산

소수점을 제거하기 위해 값을 정수로 변환한 후 계산하고, 결과를 다시 소수로 변환한다.

const a = 0.1;
const b = 0.2;

// 정수로 변환하여 계산
const result = (a * 100 + b * 100) / 100;
console.log(result); // 0.3
 

 

2. toFixed() 메서드 사용

JavaScript의 toFixed() 메서드를 사용해 원하는 소수점 이하 자릿수로 결과를 제한한다.단, toFixed()는 문자열을 반환하므로, 숫자로 다시 변환하려면 Number()를 사용해야 함.

 

const a = 0.1;
const b = 0.2;

const result = (a + b).toFixed(2); // 소수점 둘째 자리까지 표시
console.log(result); // '0.30'
console.log(Number(result)); // 0.3 (문자열을 숫자로 변환)
 

3. Math.round()로 반올림

계산 후 원하는 자리수로 반올림한다.

const a = 0.1;
const b = 0.2;

// 소수점 10자리까지 계산 후 반올림
const result = Math.round((a + b) * 100) / 100;
console.log(result); // 0.3

 

4. EPSILON 비교 (허용 오차 사용)

부동소수점 문제를 근본적으로 없애는 것이 아니라, 값의 차이가 아주 작으면 같은 값으로 간주하는 방식.

const a = 0.1 + 0.2;
const b = 0.3;

// JavaScript의 가장 작은 차이값인 Number.EPSILON 사용
if (Math.abs(a - b) < Number.EPSILON) {
  console.log("같은 값입니다."); // 출력됨
} else {
  console.log("다른 값입니다.");
}
 

 

 

[제품 가이드]

Q. 계산이 딱 떨어지지 않고 .99999999 와 같이 근사치로 떨어집니다.

javascript 에서는 소수점이라는 형식이 없기 때문에 소수점 표시를 위해 6자리의 숫자를 곱해서 다시 나누는 방식으로 소수점을 표시한다. 제품의 Float 타입은 별도의 Format 을 지정하지 않는다면, 소수점 이하 6자리의 format (#,###.######) 이 지정되고, 소수점 표현을 위해서는 정수부자리수 + 소수점 + 소수부자리수 합쳐 18자리까지 표시 가능하다. 따라서 Format을 설정해서 소수점 자리를 제한하는 것이 필요하다. 소수점 이하 6자리가 넘어가면 제대로 표현이 안될 수 있음.

 

반응형
LIST
반응형
SMALL

+ Recent posts

반응형
LIST