본문 바로가기

카테고리 없음

엑셀에 긴 카드번호나 코드를 붙여넣었더니 뒷자리가 이상해졌다면, 서식 문제가 아닙니다

주문번호, 카드번호, 일련번호처럼 자릿수가 긴 값을 엑셀에 붙여넣었는데 1.23457E+18 같은 지수 표기로 바뀌고, 서식을 텍스트로 고쳐도 뒷자리 몇 개가 0으로 뭉개져 있는 걸 본 적 있으실 겁니다. "서식만 텍스트로 바꾸면 되겠지"라고 시도했다가 이미 늦었다는 걸 알게 되는 경우가 많습니다.

실제로 19자리 숫자를 파이썬 openpyxl로 엑셀 파일에 저장해 보고, 그 값이 파일 안에 정확히 어떻게 남는지 xlsx 내부 XML을 직접 열어 확인해 봤습니다.

 

19자리 숫자를 숫자로 저장했을 때와 텍스트로 저장했을 때 비교. 숫자로 저장하면 뒤 6자리부터 값이 실제로 달라지고(빨간 글자), 텍스트로 저장하면 원본이 그대로 유지됨

 

서식은 겉모습만 바꿉니다, 저장된 값 자체는 못 건드립니다

1234567890123456789라는 19자리 값을 셀에 그대로 넣고 저장한 뒤,

xlsx 압축을 풀어 시트 XML을 들여다봤습니다.

<c r="A1" t="n"><v>1.234567890123457e+18</v></c>

지수 표기는 화면에만 보이는 장식이 아니라, 실제로 저장된 값 자체였습니다.

원본과 나란히 놓아 보면 15번째 자리부터 숫자가 달라집니다.

입력한 값 : 1234567890123456789
저장된 값 : 1234567890123457000

더 확인해 보려고, 같은 값을 넣은 셀의 서식만 텍스트("@")로 바꾸고 다시 저장해 봤습니다. 결과는 똑같이 1.234567890123457e+18이었습니다.

서식은 셀을 어떻게 보여줄지에 대한 지시일 뿐,

이미 숫자로 저장되어 반올림된 값을 되돌리지는 못합니다.


정확히 몇 자리부터 깨질까, 하나씩 늘려가며 재봤습니다

엑셀은 숫자를 컴퓨터가 소수를 다루는 표준 방식인 배정밀도 부동소수점(IEEE 754 double)으로 저장합니다.

"대략 15자리 안팎"이라고만 알려져 있길래,

13자리부터 18자리까지 한 자리씩 늘려가며 실제로 어디서부터 깨지는지 직접 재 봤습니다.

자릿수 입력한 값 저장된 값 일치 여부
13자리 1234567890123 1234567890123 일치
14자리 12345678901234 12345678901234 일치
15자리 123456789012345 123456789012345 일치
16자리 1234567890123456 1234567890123456 일치
17자리 12345678901234567 12345678901234570 불일치
18자리 123456789012345678 123456789012345696 불일치

이번 측정 기준으로는 16자리까지는 정확히 저장됐고, 17자리부터 값이 어긋나기 시작했습니다. "대략 15자리"보다는 여유가 조금 더 있는 셈인데, 정확한 경계는 숫자를 이루는 자릿값의 조합에 따라 한 자리 정도 앞뒤로 움직일 수 있습니다. 그래서 "16자리는 무조건 안전하다"고 단정하기보다는, 16자리 근방부터는 안심할 수 없는 구간이라고 여기고 미리 텍스트로 다루는 편이 안전합니다.

카드번호(16자리)가 딱 이 경계에 걸립니다. 일부 사업자와 계좌 결합 번호, 바코드, 긴 주문번호도 마찬가지로 위험 구간에 들어갑니다.

 

반대로 텍스트로 저장하면

같은 값을 파이썬 문자열로 저장했더니 결과가 달랐습니다.

<c r="A3" t="inlineStr"><is><t>1234567890123456789</t></is></c>

글자 그대로 저장되어 반올림이 끼어들 여지가 없습니다. 문제는 순서입니다.

값을 입력하기 전에 셀 서식이 텍스트여야 이렇게 저장되고, 이미 숫자로 입력해 반올림된 뒤에는 서식을 바꿔도 소용이 없습니다.


실무에서 미리 막는 법

상황 방법
빈 셀에 직접 타이핑 숫자 앞에 작은따옴표( ' )를 붙이고 입력, 엑셀이 텍스트로 인식
다른 곳에서 표를 붙여넣을 예정 붙여넣기 전에 대상 열 전체를 선택해 서식을 "텍스트"로 먼저 바꿔 둠
CSV를 엑셀에서 열 때 바로 열지 말고 [데이터] → [텍스트 마법사]로 불러오며 해당 열만 "텍스트"로 지정
파이썬으로 파일을 생성할 때 숫자가 아니라 처음부터 문자열(str)로 셀에 대입

핵심은 하나입니다. 텍스트 서식은 반드시 값을 넣기 전에 지정해야 하고, 이미 반올림된 값은 서식을 되돌려도 복구되지 않습니다.

 

 

자주 묻는 질문

 

Q. 이미 뭉개진 값을 살릴 방법은 없나요?
파일 안에서는 복구할 수 없습니다. 원본 데이터(원본 CSV, 발급 시스템의 원본 값 등)에서 다시 텍스트 형식으로 불러오는 것 외에는 방법이 없습니다.

 

Q. 16자리보다 짧은 숫자는 완전히 안전한가요?
이번 측정 기준으로는 그렇습니다. 다만 맨 앞자리가 0으로 시작하는 값(예: 우편번호, 사번)은 자릿수가 짧아도 숫자로 저장하는 순간 앞자리 0이 사라지는데, 이건 정밀도가 아니라 다른 원인이라 별도로 다룬 글이 있습니다.

 

Q. 왜 하필 16, 17자리 근처인가요?
IEEE 754 배정밀도가 값을 표현하는 데 쓰는 가수부(값의 유효숫자를 담는 부분)가 52비트인데, 이걸 10진수 자릿수로 환산하면 대략 15.95자리가 나옵니다. 16자리까지는 대체로 정확히 담기고 17자리부터 위태로워지는 이번 측정 결과가 이 숫자와 방향이 일치합니다.

 

Q. 구글 시트도 같은 문제가 있나요?
같은 IEEE 754 방식을 쓰는 프로그램이라면 정도의 차이는 있어도 비슷한 한계를 가질 가능성이 높습니다. 프로그램별 정확한 동작은 직접 확인이 필요합니다.

 

지수 표기로 바뀐 화면만 보면 서식 문제처럼 느껴지지만, 실제로는 저장 시점에 이미 벌어진 일입니다. 긴 번호를 다루는 표라면 서식을 나중에 고칠 게 아니라, 셀에 아무것도 넣기 전에 텍스트 서식부터 지정해 두는 순서가 안전합니다.

 

위 저장 값은 실제로 19자리 숫자를 xlsx로 저장한 뒤, 압축을 풀어 내부 XML의 값을 직접 읽어 확인한 결과입니다.

 

 

 

PNG를 화질 손실 없이 WebP로, 무손실 변환하면 용량이 얼마나 줄어들까 확인해보니

WebP는 흔히 화질을 조금 줄여 용량을 아끼는 형식으로 알려져 있습니다. 그런데 WebP에는 무손실 모드가 따로 있어서, 픽셀을 하나도 건드리지 않고 용량만 줄이는 것도 가능합니다. 로고나 화면

richyeon.com

 

 

JPG 저장할 때 화질(quality)을 몇으로 두면 좋을까, 옵션별 용량 실측 방법

사진을 JPG로 저장할 때 화질 값을 묻는 프로그램이 많습니다.보통 0부터 100 사이의 숫자인데, 이 값을 얼마로 두느냐에 따라 파일 크기가 몇 배씩 달라집니다.무작정 100으로 두면 용량이 커지고,

richyeon.com

 

 

큰 CSV를 엑셀 대신 SQL로 다루기, SQLite에 불러와 조회하는 방법

수천 행짜리 CSV에서 도시별 매출 합계나 특정 조건의 주문만 뽑아내려면, 엑셀에서는 피벗 테이블과 필터를 여러 번 거쳐야 합니다. 이럴 때 CSV를 SQLite라는 가벼운 데이터베이스에 한 번 넣어

richyeon.com