Skip to content

DPI / PPI Calculator — C++ source

Compute screen pixel density (PPI/DPI), dot pitch, physical dimensions, and aspect ratio from any resolution. Solve for PPI from a diagonal, or derive the diagonal from a known PPI - all in your browser.

This is the C++ implementation — the same logic the interactive tool runs, in a shareable, citable form.

// =============================================================================
//  dpi-ppi.cpp — CosmoDev polyglot showcase port of the `dpi-ppi` tool
//  -----------------------------------------------------------------------------
//  Language : C++ (C++17, standard library only)
//  Source:   ported from src/lib/dpi-ppi.ts (the canonical, live TypeScript
//             lib); mirrors src/tool-sources/dpi-ppi/{python.py,rust.rs}
//  License  : display source — part of CosmoDev's polyglot tool pages
//             (dev.cosmolabs.org). Shown verbatim alongside the JS/TS/Go/Rust/
//             Python ports and the other language ports.
//  -----------------------------------------------------------------------------
//  Display pixel-density math. Diagonal length in pixels, pixels-per-inch
//  computed from a known physical diagonal, physical width/height/diagonal in
//  both inches and millimeters, dot pitch in millimeters per pixel, and a
//  reduced aspect ratio — all derived from a pixel resolution.
//
//  Pure, deterministic, side-effect free. A zero divisor does not trap:
//  double division follows IEEE-754, so x / 0.0 yields ±infinity and
//  0.0 / 0.0 yields NaN — callers should guard with std::isfinite before
//  display. (The Python port routes every division through a safe_div wrapper
//  only because Python raises ZeroDivisionError for float division.)
//
//  std::gcd from <numeric> replaces the hand-rolled Euclid of the Python and
//  Rust ports; it computes the same non-negative greatest common divisor.
// =============================================================================

#include <cmath>
#include <numeric>
#include <string>

namespace dpi_ppi {

// Fixed conversion factor between inches and millimeters.
inline constexpr double kMmPerInch = 25.4;

// Pixels-per-inch result.
struct Ppi {
    double ppi;
};

// Physical dimensions of a display, in inches and millimeters.
struct PhysicalSize {
    double width_in;
    double height_in;
    double diagonal_in;
    double width_mm;
    double height_mm;
};

// Diagonal length in pixels: √(w² + h²).
// The sign of the inputs is irrelevant because both terms are squared.
inline double diagonal_pixels(double w, double h)
{
    return std::sqrt(w * w + h * h);
}

// Pixels per inch, given a resolution and a known physical diagonal in inches.
inline Ppi compute_ppi(double w, double h, double diagonal_inches)
{
    return Ppi{diagonal_pixels(w, h) / diagonal_inches};
}

// Derive inches and millimeters from a resolution and a ppi. The diagonal is
// recomputed from the derived inch dimensions so it stays consistent with the
// width/height values.
inline PhysicalSize physical_size(double w, double h, double ppi)
{
    const double width_in = w / ppi;
    const double height_in = h / ppi;
    return PhysicalSize{
        width_in,
        height_in,
        diagonal_pixels(width_in, height_in),
        width_in * kMmPerInch,
        height_in * kMmPerInch,
    };
}

// Dot pitch (pixel size) in millimeters per pixel: 25.4 / ppi.
inline double dot_pitch(double ppi)
{
    return kMmPerInch / ppi;
}

// Reduced aspect ratio as "w:h" (e.g. "16:9").
// Returns "-" when either side is not a positive number (this also covers
// NaN, since every comparison with NaN is false). The truncating casts
// assume finite inputs — the w > 0 / h > 0 guard has already rejected NaN
// and negatives, and real display resolutions are far below the i64 range.
inline std::string aspect_ratio(double w, double h)
{
    if (!(w > 0.0) || !(h > 0.0)) {
        return "-";
    }
    const auto wi = static_cast<long long>(std::trunc(w));
    const auto hi = static_cast<long long>(std::trunc(h));
    const auto g = std::gcd(wi, hi);  // non-negative; |wi| == wi, |hi| == hi here
    if (g == 0) {
        return "-";
    }
    return std::to_string(wi / g) + ":" + std::to_string(hi / g);
}

}  // namespace dpi_ppi

Also available in 13 other languages

Every CosmoDev tool ships its pure logic in TypeScript (web) and Go (CLI), with authored implementations in a dozen-plus languages — the same contract, ported. Compare all languages side by side →