{ }codelper
printing decimalsP0221

Weight on the scale

A shop scale shows, in kilograms, the total weight on it every time something is put on or taken off. At first the scale is empty. The first line gives the number of changes n. Each of the next n lines gives one change w, in the order they happened. A positive w means that much was put on, and a negative w means that much was taken off. w is an integer or a number written with 1 to 3 digits after the decimal point (for example 2, 0.5, -1.25, 0.125, 1.500). After every change, print on its own line the total the scale shows. The total the scale shows is the exact sum of all w given so far. Write the total with the trailing zeros after the decimal point removed (1.250 → 1.25). If the fractional part is all zeros, leave out the decimal point too (2.000 → 2). If the total is less than 1, write a 0 before the decimal point (0.5, not .5). If the total is 0, write 0 (not -0). Nothing is ever taken off that is not on the scale, so the exact total is always 0 or more.

Input
1 ≤ n ≤ 1,000, -100 ≤ w ≤ 100, w ≠ 0, w has 0 to 3 digits after the decimal point, the exact total is always 0 or more
Output
n lines, each the total at that moment (trailing zeros and a lone decimal point removed)
Example 1 · stdin
3
0.1
0.2
-0.3
stdout
0.1
0.3
0
Example 2 · stdin
5
2
0.5
-1.25
0.125
0.875
stdout
2
2.5
1.25
1.375
2.25
main.py
Input (stdin)

When you run, these lines are fed to input()/stdin in order (the program doesn't stop to ask).

$ Ready

Open this on a computer to write and run code. On mobile you can read the problem and the solutions.

In other languagesShow solutions by language · 8 languages

This problem is about printing a sum of floating-point numbers, with its tiny errors, in a form people can read.
0.1 and 0.2 are not stored exactly in binary, so 0.1 + 0.2 is 0.30000000000000004.
Printed plainly, Python print(x) and JS/TS console.log(x) show 0.30000000000000004, and Python and Java print 2 as 2.0.
So first make a string rounded to three decimals: Python f"{x:.3f}", C snprintf(buf, sizeof buf, "%.3f", x), C++ std::fixed << std::setprecision(3), Java String.format(Locale.ROOT, "%.3f", x), C# x.ToString("F3", CultureInfo.InvariantCulture).
Then remove the trailing zeros, and the decimal point too if it is left alone (Python .rstrip("0").rstrip("."), C# .TrimEnd('0').TrimEnd('.')).
Removing only the zeros turns 2.000 into 2..
C's %g also drops trailing zeros, but it keeps only 6 significant digits, so 99999.999 prints as 100000.
The second trap is -0.
0.3 - 0.1 - 0.2 is not 0 but -0.0000000000000000277, so printing it to three decimals gives -0.000 in C, C++, Python, Java, C# (since .NET Core 3.0) and JS toFixed.
If the trimmed result is -0, change it to 0 (from Python 3.11 the z in f"{x:z.3f}" prints -0 as 0).
In JS/TS you can also round the number with Math.round(x * 1000) / 1000 and print it as is, because turning a number into a string writes no trailing zeros and writes -0 as 0.
Craykon Console.WriteLine also prints without trailing zeros, and it rounds to nine decimals, so 0.1 + 0.2 shows as 0.3.
But it cannot hide the error that builds up from adding large weights hundreds of times (99.999 added 491 times shows 49099.509000001), so round to three decimals first: Mathf.Floor(x * 1000 + 0.5) / 1000.
If you want no error at all, add the weights as integers multiplied by 1000 (grams).

Pythonmain.py · 11 lines
n = int(input())total = 0.0out = []for _ in range(n):    total += float(input())    # 소수 셋째 자리까지 찍고 끝의 0과 남은 소수점을 지운다    s = f"{total:.3f}".rstrip("0").rstrip(".")    if s == "-0":          # 0 바로 아래의 작은 오차는 "-0.000"으로 찍힌다        s = "0"    out.append(s)print("\n".join(out))
JavaScriptmain.js · 11 lines
const lines = require("fs").readFileSync(0, "utf8").split("\n");const n = Number(lines[0]);let total = 0;const out = [];for (let i = 1; i <= n; i++) {  total += Number(lines[i]);  // 1000분의 1로 반올림한 수를 그대로 찍으면 끝의 0이 없다(2.5, 2). -0도 "0"으로 찍힌다  const shown = Math.round(total * 1000) / 1000;  out.push(String(shown));}console.log(out.join("\n"));
TypeScriptmain.ts · 12 lines
import { readFileSync } from "node:fs";const lines: string[] = readFileSync(0, "utf8").split("\n");const n: number = Number(lines[0]);let total = 0;const out: string[] = [];for (let i = 1; i <= n; i++) {  total += Number(lines[i]);  // 1000분의 1로 반올림한 수를 그대로 찍으면 끝의 0이 없다(2.5, 2). -0도 "0"으로 찍힌다  const shown: number = Math.round(total * 1000) / 1000;  out.push(String(shown));}console.log(out.join("\n"));
JavaMain.java · 22 lines
import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.util.Locale; public class Main {    public static void main(String[] args) throws IOException {        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));        int n = Integer.parseInt(in.readLine().trim());        double total = 0;        StringBuilder out = new StringBuilder();        for (int i = 0; i < n; i++) {            total += Double.parseDouble(in.readLine().trim());            // Double.toString은 2.0처럼 찍으니 소수 셋째 자리로 찍고 끝의 0을 지운다            String s = String.format(Locale.ROOT, "%.3f", total);            s = s.replaceAll("0+$", "").replaceAll("\\.$", "");            if (s.equals("-0")) s = "0";            out.append(s).append('\n');        }        System.out.print(out);    }}
C#Main.cs · 22 lines
using System;using System.Globalization;using System.Text; class Program{    static void Main()    {        int n = int.Parse(Console.ReadLine());        double total = 0;        var sb = new StringBuilder();        for (int i = 0; i < n; i++)        {            total += double.Parse(Console.ReadLine(), CultureInfo.InvariantCulture);            // "F3"으로 셋째 자리까지 찍고 끝의 0과 소수점을 지운다            string s = total.ToString("F3", CultureInfo.InvariantCulture).TrimEnd('0').TrimEnd('.');            if (s == "-0") s = "0";            sb.Append(s).Append('\n');        }        Console.Write(sb);    }}
C++main.cpp · 24 lines
#include <iomanip>#include <iostream>#include <sstream>#include <string> int main() {    std::ios::sync_with_stdio(false);    int n;    std::cin >> n;    double total = 0;    for (int i = 0; i < n; i++) {        double w;        std::cin >> w;        total += w;        std::ostringstream os;        os << std::fixed << std::setprecision(3) << total;        std::string s = os.str();        // 끝의 0과 남은 소수점을 지운다        while (s.back() == '0') s.pop_back();        if (s.back() == '.') s.pop_back();        if (s == "-0") s = "0";        std::cout << s << "\n";    }}
Cmain.c · 22 lines
#include <stdio.h>#include <string.h> int main(void) {    int n;    double w, total = 0;    char buf[64];    scanf("%d", &n);    for (int i = 0; i < n; i++) {        scanf("%lf", &w);        total += w;        snprintf(buf, sizeof buf, "%.3f", total);        /* 끝의 0을 지우고, 소수점만 남으면 그것도 지운다 */        size_t len = strlen(buf);        while (buf[len - 1] == '0') len--;        if (buf[len - 1] == '.') len--;        buf[len] = '\0';        if (strcmp(buf, "-0") == 0) strcpy(buf, "0");        puts(buf);    }    return 0;}
Craykonmain.cray · 9 lines
n = Console.ReadLine().ToNumber();total = 0;for (i = 0; i < n; i++){    total += Console.ReadLine().Trim().ToNumber();    // 1000분의 1 단위로 맞춘다. 쓰기는 끝의 0 없이 찍는다(2.5, 2)    shown = Mathf.Floor(total * 1000 + 0.5) / 1000;    Console.WriteLine(shown);}