자료구조와 자료형 : 숫자형

라용·2022년 11월 18일
0

모던 JavaScript 튜토리얼 내용 일부를 정리 요약한 내용입니다. 더 자세한 설명은 원문 링크를 참고하세요.

생각

아직 이렇게 디테일하게 숫자를 다루는 코드를 짜본 적이 없다. 했어도 그냥 문자열을 숫자로, 숫자를 문자로 바꾸는 정도? 정밀도 손실이란 개념도 처음 알게 되었는데 정확한 숫자로 표현해야 한다면 잘 파악해야 할 것 같다.


정리

숫자를 입력할 때 0을 많이 입력해야 한다면 e 를 붙이고 0의 개수를 붙여줄 수 있습니다.

let billion = 1e9; // 1000000000 - 1과 9개의 0

1e3 = 1 * 1000
1.23e6 = 1.23 * 1000000

0.000001 와 같은 소수점 표현도 가능합니다. e 를 사용하돼 소수점 이동 갯수를 -n 으로 붙여주면 됩니다.

let ms = 0.000001;
let ms = 1e-6; // 아래와 같은 원리, 10을 여섯번 거듭제곱한 수로 나눔
let ms = 1 / 1000000

16진수는 색을 나타내거나 문자를 인코딩할 때 쓰입니다. 16진수는 0x 를 사용해 표현할 수 있습니다.

alert( 0xff ) // 255

num.toString(base) 메서드는 base 진법으로 num 을 표현하고, 이를 문자형으로 반환합니다.

let num = 255;

num.toString(16) // ff
num.toString(2) // 11111111

base - 16 은 색, 문자 인코딩등을 표현할 때 사용합니다. 0부터 9, 10이상의 수는 A 부터 F 를 사용해 나타냅니다. base - 2 는 비트 연산 디버깅에 쓰입니다. 숫자 0, 1 로 표현됩니다.

어림수 구하는 것은 숫자를 다룰 때 가장 많이 사용되는 연산입니다. 관련 내장 함수를 살펴보면

Math.floor - 소수점 첫째 자리 내림, 3.1 은 3. -1.1 은 -2
Math.ceil - 소수점 첫째 자리 올림, 3.1 은 4, -1.1은 -1
Math.round - 소수점 첫째 자리 반올림, 3.1 은 3, 3.6 은 4, -1.1 은 -1

특정 소수점 자리까지 구하고 싶다면 두가지 방법이 있습니다. 하나는 소수점 두 번째 자리 숫자까지 남기고 싶을 때 숫자에 100을 곱하고 원하는 어림수 내장함수를 호출하고 처음 곱한 수를 다시 나누면 됩니다 .

let num = 1.23456;

alert(Math.floor(num * 100) / 100); // 1.23456 -> 123.456 -> 123 -> 1.23

다른 방법은 toFixed(n) 메서드를 사용하는 것입니다. toFixed 는 Math.round 와 비슷하게 가장 가까운 값으로 올림 혹은 버림해주는 데, 반환 값이 문자열입니다.

let num = 12.34;
alert(num.toFixed(1)); // "12.3"

let num2 = 12.36;
alert(num.toFixed(1)); // "12.4"

숫자를 저장하려면 64비트가 필요합니다. 52비트는 숫자를 저장하고 11비트는 소수점 위치를, 1비트는 부호를 저장하는 데 사용합니다. 이때 숫자가 너무 커지면 64비트 공간이 넘쳐서 Infinity 로 처리됩니다. 그 외에 정밀도 손실도 있습니다. 10진법에서 1/3을 정확히 나타낼 수 없듯 2진법에서 0.1 또는 0.2 를 정확하게 저장할 수 없습니다.

이를 해결하기 위해 toFixed(n) 을 사용해 어림수를 만듭니다. 이때 문자열로 반환되는 값을 숫자로 바꾸고 싶다면 단항 덧셈 연산자를 사용합니다.

let sum = 0.1 + 0.2;
sum.toFixed(2); // "0.30"

+sum.toFixed(2); // 0.3

단항 덧셈 연산자 + 또는 Number() 을 사용해 숫자형으로 변형하면 피연산자가 꼭 숫자여야 합니다.

alert(+"100px"); // NaN

이럴 때 사용하기 위해 parseIntparseFloat 이 존재합니다. 두 함수는 문자열에서 숫자를 읽어내는데 parseInt 는 정수, parseFloat 은 부동 소수점 숫자를 반환합니다.

alert(parseInt("100px")); // 100
alert(parseFloat("12.5em")) // 12.5

// 숫자가 아닌 값이 먼저 나오면 읽는 것이 중단됨

alert(parseInt("a123")) // NaN

parseInt(str, radix) 형태로 두번째 인자를 전달하면 16진수, 2진수 문자열을 파싱할 수 있습니다.

parseInt('0xff', 16); // 255

parseInt('ff', 16); // 255, 0x 가 없어도 동작

Math.random() 을 사용하면 0과 1 사이의 난수를 반환하고, Math.max(a, b, c..), Math.min(a, b, c.. )는 인수중 최대/최소값을 반환합니다. Math.pow(n, power)는 n을 power 번 거듭제곱한 값을 반환합니다.

isFinite(value) 는 인수가 일반 숫자이면 true 를 반환합니다.

isFinite("15"); // true
isFinite("str"); // false, NaN 이므로
isFinite(Infinity); // false, Infinity 이므로

사용자가 유효한 숫자형 값을 입력할 때까지 계속 입력을 받는 함수 readNumber 를 만드는 데 반환되는 값은 숫자형이어야 하고, 사용자가 아무것도 입력하지 않거나 취소를 누르면 null 을 반환하도록 하려면 아래처럼 작성할 수 있습니다.

function readNumber() {
    let num;
    do {
        num = prompt("Enter a number please?", 0);
    } while (!isFinite(num)); // 숫자가 입력되면 종료

    if (num === null || num === '') return null;

    return +num; // 숫자형 반환
}
profile
Today I Learned

0개의 댓글