DPI / PPI Calculator — PHP 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 PHP implementation — the same logic the interactive tool runs, in a shareable, citable form.
<?php
/**
* Display pixel-density math (PHP port).
*
* Pure, deterministic, never throws. Non-positive inputs that would cause
* division by zero produce NAN or INF (mirroring JavaScript's IEEE-754
* behavior) rather than throwing — callers should guard with is_finite()
* before display.
*
* Note: PHP 8 raises DivisionByZeroError on a float `/0`. To stay output-
* equivalent with the JavaScript reference (which yields Inf/NaN), every
* division in this module is routed through `safeDiv`.
*
* CosmoDev polyglot showcase port of `dpi-ppi`, ported from
* src/lib/dpi-ppi.ts. Display source — part of CosmoDev's polyglot tool pages.
*/
const MM_PER_INCH = 25.4;
/**
* IEEE-754-style float division.
*
* Returns +/-INF (or NAN for the 0/0 case) when the divisor is zero, instead
* of letting PHP raise DivisionByZeroError. This keeps results byte-for-byte
* equivalent to the JavaScript reference implementation.
*/
function safeDiv(float $n, float $d): float
{
if ($d == 0.0) {
if ($n == 0.0) {
return NAN;
}
return $n > 0.0 ? INF : -INF;
}
return $n / $d;
}
/**
* Diagonal length in pixels: √(w² + h²).
* The sign of the inputs is irrelevant because both terms are squared.
*/
function diagonalPixels(float $w, float $h): float
{
return sqrt($w * $w + $h * $h);
}
/**
* Pixels per inch, given a resolution and a known physical diagonal (inches).
*/
function computePpi(float $w, float $h, float $diagonalInches): array
{
return ['ppi' => safeDiv(diagonalPixels($w, $h), $diagonalInches)];
}
/**
* Physical dimensions of a display (inches and millimeters), derived from a
* resolution and a ppi. The diagonal is recomputed from the derived inch
* dimensions so it stays consistent with the width/height.
*/
function physicalSize(float $w, float $h, float $ppi): array
{
$widthIn = safeDiv($w, $ppi);
$heightIn = safeDiv($h, $ppi);
return [
'widthIn' => $widthIn,
'heightIn' => $heightIn,
'diagonalIn' => diagonalPixels($widthIn, $heightIn),
'widthMm' => $widthIn * MM_PER_INCH,
'heightMm' => $heightIn * MM_PER_INCH,
];
}
/**
* Dot pitch (pixel size) in millimeters per pixel: 25.4 / ppi.
*/
function dotPitch(float $ppi): float
{
return safeDiv(MM_PER_INCH, $ppi);
}
/**
* Integer gcd via Euclid's algorithm, used to reduce aspect ratios. Inputs
* are truncated toward zero (the `(int)` cast truncates) and taken in
* absolute value first, so the sign and fractional part never matter.
*/
function gcd(float $a, float $b): int
{
$x = abs((int) $a);
$y = abs((int) $b);
while ($y !== 0) {
$t = $y;
$y = $x % $y;
$x = $t;
}
return $x;
}
/**
* 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).
*/
function aspectRatio(float $w, float $h): string
{
if (!($w > 0) || !($h > 0)) {
return '-';
}
$g = gcd($w, $h);
if ($g === 0) {
return '-';
}
// Both operands are exact integers and g divides each evenly, so PHP
// returns an int here — the string form is a clean "16", not "16.0".
$wi = (int) $w;
$hi = (int) $h;
return ($wi / $g) . ':' . ($hi / $g);
}
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 →