{ }codelper
n줄 읽기실수 오차타입 바꾸기P0043

가진 돈과 딱 맞나

첫 줄에 물건 수 n이 주어지고, 다음 n줄에 물건값이 한 줄에 하나씩 주어진다.
마지막 줄에는 가진 돈 m이 주어진다.
값과 m은 모두 소수점 아래를 정확히 두 자리로 쓴 수다(예: 0.10, 12.30, 7.05).
물건값을 모두 더한 합이 m과 정확히 같으면 "예", 아니면 "아니요"를 출력하라.

입력
1 ≤ n ≤ 1,000, 0.01 ≤ 물건값 ≤ 10,000.00, 0.00 ≤ m ≤ 10,000,000.00
출력
"예" 또는 "아니요"
예시 1 · stdin
2
0.10
0.20
0.30
stdout
예
예시 2 · stdin
3
1.50
2.25
0.29
4.05
stdout
아니요
main.py
입력(stdin)

실행하면 이 줄들이 차례로 input()·표준 입력으로 들어가요(실행 중에 묻지 않아요).

$ 준비됐어요

코드를 입력해 풀려면 PC에서 열어 주세요. 모바일에서는 문제와 풀이를 볼 수 있어요.

다른 언어로는?언어별 풀이 보기 · 8개 언어 풀이

값을 실수(double)로 더해 ==로 비교하면 틀려요.
0.1과 0.2는 이진수로 정확히 적을 수 없어서 0.1 + 0.2는 0.30000000000000004예요.
Python float, JS·TS number, Java·C·C++ double이 모두 같은 IEEE 754 배정밀도라 똑같이 0.1 + 0.2 == 0.3이 거짓이에요.
크레이콘의 수도 JS double이라 비교는 거짓인데, 콘솔.쓰기가 소수 아홉째 자리에서 반올림해 0.3으로 보여 줘서 눈으로는 오차가 안 보여요.
100을 곱해 정수로 바꿀 때도 함정이 있어요: C·C++·Java·C#의 (int)(x * 100), Python int(), JS Math.trunc는 0 쪽으로 버리는데 0.29 * 100은 28.999999999999996이라 28이 돼요 — 바꾸려면 반올림(round, Math.round)을 써야 해요.
오차 허용 abs(a - b) < 1e-9도 위험해요: 천만 근처에서는 double 두 값의 간격 자체가 약 1.9e-9라 1e-9로는 같은 금액도 다르다고 나와요.
가장 확실한 방법은 처음부터 정수 센트로 읽는 것이에요.
글자에서 점을 빼면("12.34" → 1234) 끝: Python int(s.replace(".", "")), Java Long.parseLong, JS·TS Number, C scanf("%lld.%lld", &w, &f), 크레이콘 줄.바꾸기(".", "").수로변환().
최대 합 10억 센트는 32비트 int(약 21억)에 들어가지만 여유를 두려면 C·C++ long long, Java·C# long을 써요.
C#에는 십진 실수 decimal이 있어서 decimal.Parse로 더하면 0.1 + 0.2 == 0.3이 참이에요(Java는 BigDecimal, Python은 decimal.Decimal로 같은 일을 해요).

Pythonmain.py · 10 줄
# 값은 소수 두 자리로 정확히 주어지므로 점을 빼면 바로 '센트(1/100)' 단위 정수다def cents(s):    return int(s.strip().replace(".", "")) n = int(input())total = 0for _ in range(n):    total += cents(input())m = cents(input())print("예" if total == m else "아니요")
JavaScriptmain.js · 8 줄
const lines = require("fs").readFileSync(0, "utf8").split("\n");// "12.34" → 1234: 점을 빼면 센트 단위 정수가 된다const cents = (s) => Number(s.trim().replace(".", ""));const n = Number(lines[0]);let total = 0;for (let i = 1; i <= n; i++) total += cents(lines[i]);const m = cents(lines[n + 1]);console.log(total === m ? "예" : "아니요");
TypeScriptmain.ts · 9 줄
import { readFileSync } from "node:fs";const lines: string[] = readFileSync(0, "utf8").split("\n");// "12.34" → 1234: 점을 빼면 센트 단위 정수가 된다const cents = (s: string): number => Number(s.trim().replace(".", ""));const n: number = Number(lines[0]);let total = 0;for (let i = 1; i <= n; i++) total += cents(lines[i]);const m: number = cents(lines[n + 1]);console.log(total === m ? "예" : "아니요");
JavaMain.java · 19 줄
import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader; public class Main {    // "12.34" → 1234: 점을 빼면 센트 단위 정수가 된다    static long cents(String s) {        return Long.parseLong(s.trim().replace(".", ""));    }     public static void main(String[] args) throws IOException {        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));        int n = Integer.parseInt(in.readLine().trim());        long total = 0;        for (int i = 0; i < n; i++) total += cents(in.readLine());        long m = cents(in.readLine());        System.out.println(total == m ? "예" : "아니요");    }}
C#Main.cs · 14 줄
using System; class Program{    static void Main()    {        // C#의 decimal은 십진수라 0.1 + 0.2 == 0.3 이 참이다        int n = int.Parse(Console.ReadLine());        decimal total = 0m;        for (int i = 0; i < n; i++) total += decimal.Parse(Console.ReadLine());        decimal m = decimal.Parse(Console.ReadLine());        Console.WriteLine(total == m ? "예" : "아니요");    }}
C++main.cpp · 21 줄
#include <iostream>#include <string> // "12.34" → 1234: 점을 빼면 센트 단위 정수가 된다long long cents(std::string s) {    s.erase(s.find('.'), 1);    return std::stoll(s);} int main() {    int n;    std::cin >> n;    long long total = 0;    std::string s;    for (int i = 0; i < n; i++) {        std::cin >> s;        total += cents(s);    }    std::cin >> s;    std::cout << (total == cents(s) ? "예" : "아니요") << "\n";}
Cmain.c · 18 줄
#include <stdio.h> /* "12.34"를 정수 12와 34로 따로 읽는다 — 소수는 정확히 두 자리라 34는 센트다 */long long read_cents(void) {    long long whole, frac;    scanf("%lld.%lld", &whole, &frac);    return whole * 100 + frac;} int main(void) {    int n;    scanf("%d", &n);    long long total = 0;    for (int i = 0; i < n; i++) total += read_cents();    long long m = read_cents();    puts(total == m ? "예" : "아니요");    return 0;}
Craykonmain.cray · 14 줄
센트(줄){    // "12.34" → "1234" → 1234    돌려주기 줄.공백제거().바꾸기(".", "").수로변환();} n = 콘솔.줄읽기().수로변환();합 = 0;반복 (i = 0; i < n; i++){    합 += 센트(콘솔.줄읽기());}m = 센트(콘솔.줄읽기());콘솔.쓰기(합 == m ? "예" : "아니요");