Hour to Millisecond Converter (h to ms)

Conversion: 1 Hour (h) = 3600000 Millisecond (ms)

In 1949, ENIAC spent 70 hours calculating π to 2,037 decimal places. A modern program running the exact same 1706 formula does it in about 6 milliseconds — a roughly 43-million-to-one gap. Use the converter above for an instant hour-to-millisecond result, or the formula below to work it out by hand.

Hour to Millisecond Conversion Formula

The conversion formula is:

1 h = 3,600,000 ms

To convert a value in hours to milliseconds, multiply it by 3,600,000:

milliseconds = hours × 3,600,000

This conversion uses exact definitions. The NIST Guide to the SI defines one hour as 3,600 seconds. Its table of SI prefixes defines milli as one thousandth, so 1 ms = 0.001 s. Therefore, one hour contains exactly 3,600,000 milliseconds.

Hours to Milliseconds Conversion Table

Common conversions from hours to milliseconds
Hours (h) Milliseconds (ms)
0.001 h3,600 ms
0.01 h36,000 ms
0.1 h360,000 ms
0.25 h900,000 ms
0.5 h1,800,000 ms
1 h3,600,000 ms
2 h7,200,000 ms
3 h10,800,000 ms
6 h21,600,000 ms
8 h28,800,000 ms
12 h43,200,000 ms
24 h86,400,000 ms
48 h172,800,000 ms
72 h259,200,000 ms
100 h360,000,000 ms
168 h604,800,000 ms

Calculating Pi: From 70 Hours to About 6 Milliseconds

In 1949, ENIAC calculated π to 2,037 decimal places in around 70 hours. A modern C# benchmark using the same mathematical formula reported a median calculation time of 5.863 milliseconds. Expressed in the same units, those reported times differ by roughly 43 million to one.

The historical calculation is described in Borwein and Borwein's account of π computation. It represents an early milestone in electronic computing, although comparing it with a modern program requires care: the machines, arithmetic implementations and timing procedures were very different.

A Formula That Predates Electronic Computers

Both calculations used Machin's formula, an identity dating to 1706. John Machin used it to calculate 100 decimal places of π centuries before electronic computers existed. The formula expresses π using two inverse tangent values:

π = 16 × arctan(1/5) − 4 × arctan(1/239)

Each inverse tangent can be evaluated by adding and subtracting terms from a power series:

arctan(x) = x − x3/3 + x5/5 − x7/7 + …

For the small values 1/5 and 1/239, successive terms decrease rapidly. Calculating enough terms gives a precise approximation of π without retrieving its digits from a stored list. Wolfram MathWorld provides further details about the identity.

The Modern C# Calculation

C# benchmark results comparing execution times for calculating 2,037 decimal places of pi, with a median time of about 5.9 milliseconds.
C# benchmark results comparing execution times for calculating 2,037 decimal places of pi, with a median time of about 5.9 milliseconds.

The benchmark supplied for this article used C#'s BigInteger type for fixed-point arithmetic. The calculation retained 20 additional guard digits to limit the effect of intermediate truncation, then produced 2,037 decimal places, truncated rather than rounded.

The first calculation took 28.631 milliseconds, with the supplied notes attributing part of that initial cost to just-in-time compilation. Across 100 warmed calculations, the reported results were:

  • Median time: 5.863 milliseconds.
  • Mean time: 6.244 milliseconds.
  • Fastest calculation: 4.285 milliseconds.
  • Slowest calculation: 12.108 milliseconds.
  • Reported runtime: .NET 10.0.12, x64.

The benchmark notes report that the output agreed with a calculation using 40 guard digits and another using a different arctangent identity. They also describe an error-bound check. These are author-supplied results; the source code, output digits and timing logs were not provided for independent verification.

Converting Hours to Milliseconds

To compare the reported times, first convert 70 hours into milliseconds. Each hour contains 3,600 seconds, and each second contains 1,000 milliseconds:

70 × 3,600 × 1,000 = 252,000,000 milliseconds

Dividing this figure by the modern median gives:

252,000,000 ÷ 5.863 ≈ 42,981,409

The resulting ratio is approximately 43 million to one. Using the rounded headline time of 6 milliseconds gives 42 million to one instead. The difference comes from rounding the modern measurement before performing the division.

Why the Comparison Needs Context

Sharing a formula does not make these identical benchmarks. According to Wittenberg University's historical account, ENIAC's 70-hour workflow included punching intermediate results onto cards and reading them back into the machine.

The modern measurements, by contrast, exclude process startup, verification, decimal formatting and file output. They also benefit from modern arithmetic software. The ratio therefore compares two reported durations; it does not isolate the improvement in processor speed.

To reproduce the modern result, readers would need the program's source code, processor model, operating system, build settings, timing procedure and raw measurements. Performance will vary between computers and runs.

Even with those limitations, the comparison gives a concrete sense of the change in computing timescales. A mathematical task that occupied an early electronic computer for almost three days took only a few thousandths of a second in the supplied modern benchmark—all while using an identity developed more than three centuries ago.

C# Source Code for the Pi Benchmark

The complete 107-line program used for this benchmark is included below. It calculates 2,037 decimal places of π using Machin's formula and measures repeated runs after an initial warm-up.

View the complete C# benchmark code
            
            using System.Diagnostics;
            using System.Globalization;
            using System.Numerics;
            using System.Runtime.InteropServices;

            const int digits = 2037;
            const int guardDigits = 20;
            const int repetitions = 100;

            // Measure the first calculation separately: it includes first-use JIT costs,
            // but excludes process startup, formatting, verification, and file I/O.
            var timer = Stopwatch.StartNew();
            var first = CalculatePi(digits, guardDigits);
            timer.Stop();
            double firstMs = timer.Elapsed.TotalMilliseconds;

            // Verify every output digit with extra precision and a different identity:
            // pi = 48 atan(1/18) + 32 atan(1/57) - 20 atan(1/239).
            if (first.Value != CalculatePi(digits, 40).Value ||
            first.Value != CalculatePi(digits, 40, alternate: true).Value)
            throw new InvalidOperationException("Independent verification failed.");

            // Warm up before collecting individual wall-clock measurements.
            for (int i = 0; i < 20; i++) CalculatePi(digits, guardDigits);
            var samples = new double[repetitions];
            for (int i = 0; i < repetitions; i++)
            {
            timer.Restart();
            var result = CalculatePi(digits, guardDigits);
            timer.Stop();
            samples[i] = timer.Elapsed.TotalMilliseconds;
            if (result.Value != first.Value) throw new InvalidOperationException("Unstable result.");
            }
            Array.Sort(samples);
            double median = (samples[49] + samples[50]) / 2;
            string raw = first.Value.ToString(CultureInfo.InvariantCulture);
            string pi = raw.Insert(1, ".");
            if (raw.Length != digits + 1) throw new InvalidOperationException("Incorrect digit count.");
            File.WriteAllText("pi-2037.txt", pi + Environment.NewLine);

            string report = $"""
            Machin's formula: pi = 16 atan(1/5) - 4 atan(1/239)
            Decimal places: {digits} (truncated, not rounded)
            Arithmetic: BigInteger fixed point, {guardDigits} guard digits
            Series terms: {first.Terms}
            Verification: all 2,037 places agree at 40 guard digits and with an alternate identity.
            Error bounds: both ends of the computed interval give the same 2,037 decimal places.
            Runtime: {RuntimeInformation.FrameworkDescription}, {RuntimeInformation.ProcessArchitecture}
            OS: {RuntimeInformation.OSDescription}
            CPU: {Environment.GetEnvironmentVariable("PROCESSOR_IDENTIFIER") ?? "Unknown"}
            First calculation (includes first-use JIT): {firstMs:F3} ms
            Warmed calculations: {repetitions}
            Minimum: {samples[0]:F3} ms
            Median: {median:F3} ms
            Mean: {samples.Average():F3} ms
            Maximum: {samples[^1]:F3} ms
            70 hours / median calculation time: {70 * 3600 * 1000 / median:N0}x
            Timing excludes process startup, verification, decimal formatting, and file I/O.
            This uses the same mathematical formula, not a simulation of ENIAC's hardware or program.
            Digits saved to: {Path.GetFullPath("pi-2037.txt")}
            """;
            Console.WriteLine(report);
            Console.WriteLine($"First 100 decimal places: {pi[..102]}");
            File.WriteAllText("benchmark-results.txt", report + Environment.NewLine);

            static (BigInteger Value, int Terms) CalculatePi(int places, int guard, bool alternate = false)
            {
            BigInteger scale = BigInteger.Pow(10, places + guard);
            BigInteger divisor = BigInteger.Pow(10, guard);
            var components = alternate
            ? new[] { (48, 18), (32, 57), (-20, 239) }
            : new[] { (16, 5), (-4, 239) };
            BigInteger sum = 0, error = 0;
            int terms = 0;
            foreach (var (coefficient, denominator) in components)
            {
            var a = AtanReciprocal(denominator, scale);
            sum += coefficient * a.Value;
            error += Math.Abs(coefficient) * (BigInteger)(a.Terms + 1);
            terms += a.Terms;
            }
            // Each truncated term has error < 1 scaled unit; the remaining alternating
            // tail is smaller than the first omitted term (< 1 scaled unit).
            // Agreement of the interval endpoints certifies every retained digit.
            BigInteger lower = (sum - error) / divisor;
            BigInteger upper = (sum + error) / divisor;
            if (lower != upper) throw new InvalidOperationException("More guard digits required.");
            return (lower, terms);
            }

            static (BigInteger Value, int Terms) AtanReciprocal(int q, BigInteger scale)
            {
            BigInteger power = scale / q;
            BigInteger sum = 0;
            int qSquared = checked(q * q);
            int n = 0;
            while (true)
            {
            BigInteger term = power / (2 * n + 1);
            if (term.IsZero) break;
            sum += (n % 2 == 0) ? term : -term;
            power /= qSquared;
            n++;
            }
            return (sum, n);
            }

                
            

The program was compiled in Release mode and run using .NET 10.0.12 on x64. Timings can vary according to the processor, operating system, runtime version and background activity.

Hours to Milliseconds Questions and Answers