W poniedziałek wdrażasz dashboard pogodowy. Do środy użytkownik z Toronto zgłasza buga: aplikacja pokazuje temperaturę na zewnątrz jako 284. Endpoint OpenWeatherMap zwrócił wartość w kelwinach (domyślne ustawienie), interfejs spodziewał się stopni Celsjusza, a po drodze nikt nie zadbał o sprawdzenie. Jedno brakujące odejmowanie, jeden niefortunny zrzut ekranu na Twitterze.
Jeśli potrzebujesz tylko dwóch wzorów i chcesz iść dalej:
- Celsjusz na Fahrenheit:
°F = °C × 9/5 + 32 - Fahrenheit na Celsjusz:
°C = (°F − 32) × 5/9 - Celsjusz na Kelwin:
K = °C + 273,15
Te trzy wzory pokrywają mniej więcej 90% tego, czego naprawdę potrzebują programiści. Reszta przewodnika to pozostałe 10%: skąd bierze się 9/5, dlaczego Kelwin nigdy nie jest ujemny, jak sprawić, by system typów odrzucał wywołanie celsiusToFahrenheit(kelvinValue) już na etapie kompilacji, i jak przestać wdrażać buga z Toronto. Możesz też pominąć lekturę i skorzystać z naszego konwertera temperatury, gdy potrzebujesz od razu konkretnej liczby. Jeśli interesują cię jednostki inne niż temperatura, zajrzyj do szerszego kompletnego przewodnika po przeliczaniu jednostek.
Dlaczego temperatura różni się od innych przeliczeń jednostek
Większość przeliczeń jednostek jest trywialnie liniowa wokół zera. Metr to 3,28084 stopy, kropka. Podwójna liczba metrów to podwójna liczba stóp. Zero metrów to zero stóp. Bibliotekę przeliczeniową można zbudować z jednego mnożnika dla pary jednostek i nigdy więcej o tym nie myśleć.
Temperatura łamie ten model: jej skale nie mają wspólnego punktu zerowego. Celsjusz zakotwicza zero w temperaturze zamarzania wody. Fahrenheit zakotwicza zero w mieszaninie solnej z 1724 roku. Kelwin zakotwicza zero w teoretycznej granicy termodynamiki. Aby przejść między dowolnymi dwiema skalami, potrzebujesz zarówno współczynnika skalowania, jak i przesunięcia — temperatura jest transformacją afiniczną, a nie liniową.
Ma to niebezpieczną konsekwencję: wartości temperatury nie są addytywne w taki sam sposób jak wartości długości czy masy. 20°C + 20°C w żadnym fizycznym sensie nie daje 40°C. Nie da się „dodać dwóch pokoi do siebie” i otrzymać cieplejszego pokoju. Można dodać różnicę temperatur do temperatury, ponieważ różnice są liniowe. To rozróżnienie zapracowało sobie na pamięć w incydencie z 2006 roku, kiedy to w Wielkiej Brytanii rejestrator chłodnego łańcucha dostaw szczepionek Medeva pomylił odczyt absolutny z deltą i oznaczył tysiące dawek jako wykraczające poza specyfikację. Wielkości intensywne, takie jak temperatura, wymagają takiej mentalnej barierki: liczby, które dzielą jednostkę, nie dzielą automatycznie tej samej algebry.
Cztery skale temperatury w pigułce
Tylko dwie skale liczą się w codziennym kodzie (Celsjusz, Fahrenheit), trzecia liczy się w czymkolwiek naukowym (Kelwin), a czwarta pojawia się dokładnie w jednym miejscu: amerykańskich podręcznikach termodynamiki i kodzie HVAC, który wciąż się do nich odwołuje.
Celsjusz (°C)
Anders Celsius opublikował swoją skalę w 1742 roku, początkowo z 0° przy wrzeniu i 100° przy zamarzaniu — odwrotnie niż obecnie. Współczesna orientacja, z 0°C w punkcie zamarzania wody i 100°C w punkcie jej wrzenia pod ciśnieniem jednej standardowej atmosfery, pojawiła się wkrótce po jego śmierci. Dziś jest to jednostka pochodna SI dla codziennej temperatury i domyślna skala w każdym kraju z wyjątkiem Stanów Zjednoczonych, Bahamów, Belize, Kajmanów i Liberii.
Redefinicja SI z 2019 roku rygorystycznie powiązała Celsjusza z Kelwinem: 0°C jest teraz zdefiniowane jako dokładnie 273,15 K. Punkt zamarzania wody, niegdyś definicja, jest teraz zmierzoną konsekwencją (mieści się w 0°C z dokładnością do części na milion, ale nie jest już kotwicą).
Fahrenheit (°F)
Daniel Gabriel Fahrenheit zaproponował swoją skalę w 1724 roku. Wybrał 0°F jako punkt zamarzania konkretnej mieszaniny solnej — najniższej temperatury, jaką potrafił niezawodnie odtworzyć podczas zimy w Gdańsku — a 96°F jako temperaturę ciała. Późniejsza rekalibracja względem punktów zamarzania i wrzenia czystej wody przesunęła temperaturę ciała do 98,6°F i umieściła zamarzanie przy 32°F, a wrzenie przy 212°F, co dało rozpiętość 180 stopni.
Fahrenheit utrzymuje się w Stanach Zjednoczonych w prognozach pogody, gotowaniu i medycynie. Rozpiętość 180 stopni między zamarzaniem a wrzeniem (vs. 100 w Celsjuszu) bywa broniona jako oferująca „wyższą rozdzielczość dla temperatur otoczenia” — twierdzenie marginalne, ale wyjaśnia, dlaczego amerykańskie termostaty mają oznaczenia co 1°F, a europejskie co 0,5°C.
Kelwin (K)
William Thomson, lord Kelvin, zaproponował skalę absolutną w 1848 roku. Współczesny kelwin jest podstawową jednostką temperatury w układzie SI. Redefinicja SI z 2019 roku wiąże kelwin z stałą Boltzmanna k_B = 1,380649 × 10⁻²³ J/K dokładnie, czyniąc go wielkością zdefiniowaną, a nie zmierzoną.
Kelwin ma trzy osobliwości, które programiści powinni znać:
- Brak symbolu stopnia. Pisz
300 K, nie300°K. Taka jest konwencja SI od 1967 roku. - Zaczyna się od zera absolutnego.
0 K = −273,15°C. W poprawnych danych nigdy nie powinieneś zobaczyć ujemnej wartości w kelwinach; potraktuj ją jako błąd wejścia. - Ten sam rozmiar stopnia co Celsjusz. Zmiana o 1 K odpowiada zmianie o 1°C. Różnice temperatur są wymienne między tymi skalami; różnią się tylko wartości absolutne, o przesunięcie 273,15.
Kelwin jest właściwym wyborem zawsze, gdy mnożysz lub dzielisz temperatury — promieniowanie cieplne (T⁴), równanie stanu gazu doskonałego, fizyka ciała doskonale czarnego. Dzielenie przez ujemną lub bliską zera wartość w Celsjuszach wysadza fizykę, którą chcesz utrzymać w skończonym zakresie.
Rankine (°R)
William Rankine zaproponował tę skalę w 1859 roku jako odpowiednik Kelwina po stronie Fahrenheita: skalę absolutną, z zerem w zerze absolutnym, ale ze stopniami o rozmiarze Fahrenheita. 0°R = −459,67°F. 491,67°R = 0°C.
Rzadko spotkasz Rankine’a poza amerykańską inżynierią termodynamiczną — obliczeniami HVAC, rafinacją ropy naftowej, analizą spalania w silnikach rakietowych — gdzie matematyka potrzebuje skali absolutnej, a dane wejściowe przychodzą w Fahrenheitach. Konwersja jest mechaniczna: °R = °F + 459,67 lub równoważnie °R = K × 9/5. Większość nowoczesnego oprogramowania inżynierskiego może wewnętrznie pozostać w kelwinach i przeliczać tylko do prezentacji — taką drogę polecam, gdy masz wybór.
Wzory przeliczania temperatury (wszystkie sześć kierunków)
Sześć kierunków, cztery skale, sześć wzorów. W praktyce zapamiętujesz te skoncentrowane na Celsjuszu i komponujesz resztę.
Celsjusz na Fahrenheit i z powrotem
°F = °C × 9/5 + 32
°C = (°F − 32) × 5/9
Współczynnik 9/5 to stosunek rozpiętości obu skal między tymi samymi dwoma fizycznymi punktami odniesienia. Od zamarzania do wrzenia Fahrenheit pokrywa 180 stopni (32 do 212); Celsjusz pokrywa 100 (0 do 100). 180 / 100 = 9/5 = 1,8. Dodatek + 32 to przesunięcie potrzebne do wyrównania zer punktów zamarzania, ponieważ zero Fahrenheita leży 32°F poniżej zera Celsjusza.
Rozwiązany przykład: °F = 25 × 9/5 + 32 = 45 + 32 = 77°F.
Celsjusz na Kelwin i z powrotem
K = °C + 273,15
°C = K − 273,15
Bez skalowania, samo przesunięcie. 273,15 to liczbowa odległość od zera Celsjusza (punktu zamarzania wody) w dół do zera absolutnego, mierzona w stopniach Celsjusza. Ponieważ Kelwin i Celsjusz dzielą ten sam rozmiar stopnia, mnożnika nie ma.
Fahrenheit na Kelwin i z powrotem
K = (°F − 32) × 5/9 + 273,15
°F = (K − 273,15) × 9/5 + 32
Krótszej formy nie ma — potrzebna jest zarówno zmiana skali, jak i zmiana przesunięcia. W kodzie czystsze jest przejście przez Celsjusza: k = cToK(fToC(f)). Mniej napiszesz, bardziej zaufasz, a kompilator i tak zoptymalizuje kompozycję.
Przeliczenia Rankine’a
°R = °F + 459,67
°F = °R − 459,67
°R = K × 9/5
K = °R × 5/9
°R = °C × 9/5 + 491,67
491,67 to 32 × 9/5 + 459,67, czyli wartość w skali Rankine’a odpowiadająca 0°C. W praktyce rzadko będziesz je komponował. Gdy potrzebujesz Rankine’a, traktuj go jak „absolutny bliźniak Fahrenheita” i przejdź przez Fahrenheita lub Kelwina.
Skąd bierze się 9/5? Krótkie wyprowadzenie
Obie skale powiązane są funkcją afiniczną °F = a × °C + b. Aby wyznaczyć a i b, potrzebujesz dwóch znanych punktów kalibracyjnych. Konwencjonalną parą są zamarzanie i wrzenie:
- Zamarzanie:
0°C ↔ 32°F - Wrzenie:
100°C ↔ 212°F
Wstaw obie pary do °F = a × °C + b:
32 = a × 0 + b → b = 32
212 = a × 100 + 32 → a = (212 − 32) / 100 = 180 / 100 = 9/5
I tyle — dwa równania liniowe, dwie niewiadome, a cała konwersja po prostu wypada. Intuicja geometryczna: wyobraź sobie dwa pionowe termometry obok siebie, jeden w Celsjuszu, drugi w Fahrenheitach. Termometr Fahrenheita jest rozciągnięty pionowo (nachylenie 9/5) i przesunięty w górę (przesunięcie 32) względem termometru Celsjusza. Każda inna wartość konwersji leży na tej rozciągniętej i przesuniętej linii.
To samo wyprowadzenie z (0°C, 273,15 K) i (100°C, 373,15 K) daje przeliczenie Celsjusz na Kelwin: nachylenie 1, przesunięcie 273,15. To samo wyprowadzenie z dowolnymi dwoma jednoznacznymi punktami kalibracyjnymi daje dowolną konwersję afiniczną. Matematycznie nic w temperaturze nie jest wyjątkowe — cała złożoność tkwi w konfiguracji z dwoma punktami zakotwiczenia, której inne typy jednostek nie potrzebują.
Punkt przecięcia −40°: użyteczna mnemotechnika
Czy istnieje temperatura, w której Celsjusz i Fahrenheit pokazują tę samą liczbę? Wstaw °C = °F do wzoru konwersji:
°C = °C × 9/5 + 32
°C − °C × 9/5 = 32
°C × (1 − 9/5) = 32
°C × (−4/5) = 32
°C = −40
Czyli −40°C = −40°F. Dokładnie jeden punkt przecięcia, który okazuje się być realną temperaturą, jaką można spotkać w styczniu w Yellowknife, Jakucku albo Fairbanks. To także tania mentalna kontrola: kiedykolwiek szacujesz wzrokowo konwersję C↔F i wynik ląduje blisko −40, obie liczby powinny być sobie bliskie. Jeśli jedna mówi −40°C, a druga −72°F, masz buga w kierunku konwersji.
Pełną listę mnemotechniczną trzymam przyklejoną przy monitorze: zamarzanie (0 / 32), temperatura ciała (37 / 98,6), temperatura pokojowa (20 / 68), wrzenie (100 / 212), −40 (−40 / −40). Pięć punktów pokrywa niemal każdą kontrolę zdrowego rozsądku, której potrzebuję.
Konwersja temperatury w kodzie
Same wzory są trywialne. Poprawne ich wdrożenie w realnej bazie kodu sprowadza się do dwóch rzeczy: niedopuszczenia do tego, by wywołujący przekazał Fahrenheita tam, gdzie chciałeś Celsjusza, oraz do uczynienia zachowania zmiennoprzecinkowego przewidywalnym na granicach (zamarzanie, zero absolutne, temperatury piekarnika). Każdy poniższy przykład jest kompletnym, wykonywalnym programem.
JavaScript / TypeScript
Czysty JavaScript daje od razu funkcjonalne konwersje:
const cToF = (c) => c * 9 / 5 + 32;
const fToC = (f) => (f - 32) * 5 / 9;
const cToK = (c) => c + 273.15;
const kToC = (k) => k - 273.15;
const fToK = (f) => cToK(fToC(f));
const kToF = (k) => cToF(kToC(k));
const cToR = (c) => (c + 273.15) * 9 / 5;
const rToC = (r) => r * 5 / 9 - 273.15;
console.log(cToF(100)); // 212
console.log(fToC(98.6)); // 37
console.log(kToC(300)); // 26.85
TypeScript pozwala uczynić pomylenie jednostek błędem kompilacji dzięki brandowaniu typu liczbowego:
type Scale = 'C' | 'F' | 'K' | 'R';
type Temp<S extends Scale> = number & { readonly __scale: S };
const t = <S extends Scale>(value: number, _scale: S): Temp<S> =>
value as Temp<S>;
const cToF = (c: Temp<'C'>): Temp<'F'> => t(c * 9 / 5 + 32, 'F');
const fToC = (f: Temp<'F'>): Temp<'C'> => t((f - 32) * 5 / 9, 'C');
const indoor = t(22, 'C');
const outdoor = cToF(indoor); // OK: Temp<'F'>
// const broken = cToF(outdoor); // Compile error: Temp<'F'> is not Temp<'C'>
Branded types mają zerowy koszt w runtime i kosztują około dziesięciu linii boilerplate. W zamian bug z Toronto z otwierającego akapitu staje się czerwoną falistą linią w edytorze.
Python
Czyste funkcje działają poprawnie, ale Enum plus dataclass zwracają się przy pierwszym logowaniu temperatury:
from dataclasses import dataclass
from enum import Enum
class Scale(Enum):
C = "°C"
F = "°F"
K = "K"
R = "°R"
@dataclass(frozen=True)
class Temperature:
value: float
scale: Scale
def to(self, target: Scale) -> "Temperature":
c = _to_celsius(self)
return _from_celsius(c, target)
def __str__(self) -> str:
return f"{self.value:.2f}{self.scale.value}"
def _to_celsius(t: Temperature) -> float:
if t.scale is Scale.C: return t.value
if t.scale is Scale.F: return (t.value - 32) * 5 / 9
if t.scale is Scale.K: return t.value - 273.15
if t.scale is Scale.R: return (t.value - 491.67) * 5 / 9
raise ValueError(f"Unknown scale: {t.scale}")
def _from_celsius(c: float, scale: Scale) -> Temperature:
if scale is Scale.C: return Temperature(c, scale)
if scale is Scale.F: return Temperature(c * 9 / 5 + 32, scale)
if scale is Scale.K: return Temperature(c + 273.15, scale)
if scale is Scale.R: return Temperature(c * 9 / 5 + 491.67, scale)
raise ValueError(f"Unknown scale: {scale}")
body = Temperature(37, Scale.C)
print(body.to(Scale.F)) # 98.60°F
print(body.to(Scale.K)) # 310.15K
Jeśli przetwarzasz dane naukowe, w których 0.1 + 0.2 != 0.3 staje się problemem audytowym, zamień float na decimal.Decimal. Cena to szybkość (Decimal jest około 50× wolniejszy) oraz fakt, że 5/9 również nie ma dokładnej reprezentacji dziesiętnej, więc potrzebujesz Decimal(5) / Decimal(9) z kontrolowanym kontekstem. Dla większości pipeline’ów czujnikowych float plus round(value, 2) na granicy wyświetlania wystarczy.
Go
System typów Go pozwala pójść dalej niż TypeScript: nazwany typ float64 nie może być po cichu zmieszany z innym nazwanym typem float64, mimo że dzielą tę samą reprezentację w runtime.
package main
import "fmt"
type Celsius float64
type Fahrenheit float64
type Kelvin float64
type Rankine float64
func (c Celsius) ToFahrenheit() Fahrenheit { return Fahrenheit(c*9/5 + 32) }
func (c Celsius) ToKelvin() Kelvin { return Kelvin(c + 273.15) }
func (f Fahrenheit) ToCelsius() Celsius { return Celsius((f - 32) * 5 / 9) }
func (k Kelvin) ToCelsius() Celsius { return Celsius(k - 273.15) }
func (f Fahrenheit) ToKelvin() Kelvin { return f.ToCelsius().ToKelvin() }
func main() {
room := Celsius(22)
fmt.Printf("%.2f °F\n", room.ToFahrenheit()) // 71.60 °F
fmt.Printf("%.2f K\n", room.ToKelvin()) // 295.15 K
// var bug Fahrenheit = room // compile error
// fmt.Println(room.ToKelvin() + 1) // compile error: Kelvin + untyped int needs Kelvin(1)
}
Koszt to mniej więcej jedna linia na skalę. Korzyść jest taka, że ToFahrenheit nie może przypadkiem przyjąć wartości w kelwinach, a funkcja przyjmująca Celsius odrzuci surowe float64 w miejscu wywołania.
Rust
Wzorzec newtype w Ruście daje te same gwarancje co Go, plus tanie konwersje From/Into:
#[derive(Clone, Copy, Debug, PartialEq)]
struct Celsius(f64);
#[derive(Clone, Copy, Debug, PartialEq)]
struct Fahrenheit(f64);
#[derive(Clone, Copy, Debug, PartialEq)]
struct Kelvin(f64);
impl From<Celsius> for Fahrenheit {
fn from(c: Celsius) -> Self { Fahrenheit(c.0 * 9.0 / 5.0 + 32.0) }
}
impl From<Fahrenheit> for Celsius {
fn from(f: Fahrenheit) -> Self { Celsius((f.0 - 32.0) * 5.0 / 9.0) }
}
impl From<Celsius> for Kelvin {
fn from(c: Celsius) -> Self { Kelvin(c.0 + 273.15) }
}
impl From<Kelvin> for Celsius {
fn from(k: Kelvin) -> Self { Celsius(k.0 - 273.15) }
}
fn main() {
let body = Celsius(37.0);
let body_f: Fahrenheit = body.into();
let body_k: Kelvin = body.into();
println!("{:.2} {:?} {:?}", body.0, body_f, body_k);
// 37.00 Fahrenheit(98.6) Kelvin(310.15)
}
Na to można nałożyć walidację: TryFrom<f64> for Kelvin, który odrzuca wartości ujemne, zwraca Result<Kelvin, TemperatureError> i przesuwa kontrolę do momentu konstrukcji. Nieprawidłowe stany nigdy nie docierają do logiki biznesowej.
SQL (PostgreSQL)
Przechowuj temperatury z ograniczeniami CHECK i wyprowadzaj alternatywne jednostki jako kolumny generowane. Wtedy ujemna wartość w kelwinach jest naruszeniem ograniczenia w momencie wstawiania, a nie cichym bugiem w danych trzy zapytania dalej.
CREATE OR REPLACE FUNCTION c_to_f(c numeric) RETURNS numeric AS $$
SELECT c * 9.0 / 5.0 + 32.0;
$$ LANGUAGE SQL IMMUTABLE;
CREATE OR REPLACE FUNCTION c_to_k(c numeric) RETURNS numeric AS $$
SELECT c + 273.15;
$$ LANGUAGE SQL IMMUTABLE;
CREATE TABLE sensor_readings (
id bigserial PRIMARY KEY,
recorded_at timestamptz NOT NULL DEFAULT now(),
celsius numeric(6, 2) NOT NULL,
fahrenheit numeric(6, 2) GENERATED ALWAYS AS (c_to_f(celsius)) STORED,
kelvin numeric(6, 2) GENERATED ALWAYS AS (c_to_k(celsius)) STORED,
CONSTRAINT kelvin_non_negative CHECK (celsius >= -273.15)
);
INSERT INTO sensor_readings (celsius) VALUES (22.5), (0), (100);
SELECT celsius, fahrenheit, kelvin FROM sensor_readings;
-- 22.50 | 72.50 | 295.65
-- 0.00 | 32.00 | 273.15
-- 100.00| 212.00 | 373.15
-- Rejected at insert time:
-- INSERT INTO sensor_readings (celsius) VALUES (-300);
-- ERROR: new row for relation "sensor_readings" violates check constraint
GENERATED ALWAYS AS ... STORED wymienia odrobinę miejsca na dysku na szybkość zapytań — odczytujesz wartość, nie przeliczasz jej ponownie. Dla wysokowolumenowych tabel IoT zamień STORED na widok, jeśli presja na dysk jest większa niż na opóźnienie odczytu.
Obsługa API pogodowych i IoT
Najczęstszy bug produkcyjny związany z temperaturą to nie błąd we wzorze. To niezgodność jednostek między tym, co zwraca API, a tym, co wyświetla interfejs. Dostawcy, na których najczęściej trafiają programiści:
OpenWeatherMap domyślnie zwraca wartości w kelwinach. Dodaj units=metric, aby otrzymać Celsjusza, lub units=imperial, aby otrzymać Fahrenheita. Jeśli zapomnisz parametru zapytania, dostaniesz kelwiny. Liczby pokroju 284,15 przychodzące w polu o nazwie temp wyprowadziły w pole wystarczająco wielu inżynierów, że warto napisać dla tego test integracyjny.
Open-Meteo domyślnie zwraca Celsjusza i akceptuje temperature_unit=fahrenheit. Brak opcji Kelwina — to nie jest API naukowe.
Tomorrow.io i WeatherAPI domyślnie używają układu metrycznego, ale zwracają obie skale w tej samej odpowiedzi pod różnymi kluczami. Czytaj rzeczywisty klucz, do którego odwołuje się twój kod, a nie sąsiada.
Wzorzec, którego używam dla każdego ingestu pogodowego lub czujnikowego:
type Reading = {
value: number;
scale: 'C' | 'F' | 'K';
source: string;
};
function normalise(raw: Reading): number /* celsius */ {
switch (raw.scale) {
case 'C': return raw.value;
case 'F': return (raw.value - 32) * 5 / 9;
case 'K': return raw.value - 273.15;
}
}
// At ingestion, every reading carries its scale explicitly.
// The UI layer never guesses — it consumes celsius and formats per user preference.
Z tego wynikają dwie zasady:
- Każda granica ingestu rejestruje skalę źródłową. Żadnych gołych liczb przekraczających linie modułów.
- Warstwa wyświetlania to jedyne miejsce, które przelicza na preferowaną przez użytkownika jednostkę.
Podwójna konwersja — gdy dwie warstwy „normalizują” liczbę — to drugi częsty bug. Zespół backendu konwertuje kelwiny na Celsjusza przy zapisie. Zespół frontendu, nieświadomy tego, stosuje ten sam - 273,15 przy odczycie. Użytkownicy widzą temperatury około −251°C. Naprawa to pojedynczy właściciel normalizacji, a nie więcej testów.
W IoT surowe dane z czujnika często przychodzą jako odczyt ADC, który trzeba przeliczyć na temperaturę przez krzywą kalibracyjną (dla termistora NTC 10kΩ oznacza to równanie Steinharta–Harta). Konwersje skal temperatury zachodzą po tym, na już skalibrowanej wartości. Wymieszanie tych dwóch faz to droga do liczb, które wyglądają jak temperatura, ale są przesunięte o 30%.
Typowe pułapki i jak ich unikać
Te sześć pojawia się w realnych bazach kodu produkcyjnego. Sprawdź swoją pod ich kątem.
Użycie wzoru w niewłaściwym kierunku
Typowy objaw: aplikacja, która pokazuje 37°C jako gorączkę u dziecka, a następnie oznacza ją jako stan krytyczny. Co się stało: API zwróciło 37°F, ktoś oznaczył tę wartość jako celsius, ponieważ tak nazywała się kolumna, a logika progu medycznego porównała ją do skali Celsjusza. Zapobiegasz temu, sprawiając, by typ niósł jednostkę, a nie nazwa zmiennej.
Traktowanie temperatury jako wielkości ekstensywnej
averageTemperature ma sens. sumTemperatures nie. Jeśli twoja agregacja SQL ma SUM(temperature_c), coś jest nie tak — prawdopodobnie chcesz AVG, lub w rzadkich przypadkach scałkowaną metrykę degree-day. Temperatura to wielkość intensywna; nie dodawaj dwóch i nie oczekuj sensownego wyniku.
Zaokrąglenia zmiennoprzecinkowe
(37 * 9 / 5) + 32 w JavaScripcie daje 98.60000000000001, a nie 98,6. Każdy język używający IEEE 754 double zachowuje się tak samo. Opcje:
- Wyświetlać z
.toFixed(2)(lub odpowiednikiem w twoim języku) i na tym poprzestać. - Użyć biblioteki dziesiętnej (
decimal.js,Python Decimal,BigDecimal) dla dokładności klasy audytowej. - Przechowywać jako liczby całkowite w decystopniach (
370zamiast37,0) i dzielić tylko na granicy wyświetlania.
Do wyświetlania w UI toFixed(2) to właściwy wybór. Dla systemu billingowego lub regulacyjnego, w którym kumulują się błędy zaokrągleń, używaj typów dziesiętnych.
Ujemne kelwiny w walidacji wejścia
Kelwin z prawa fizyki nie jest ujemny. Treść żądania zawierająca { "tempK": -10 } jest zawsze nieprawidłowa. Egzekwuj to na granicy — JSON schema, Pydantic, Zod, ograniczenie CHECK — a nie głęboko w logice biznesowej. Jedyny wyjątek, układy kwantowe z „ujemną temperaturą absolutną”, nie pojawia się w żadnym API, z którym prawdopodobnie się integrujesz; jeśli już, to wiesz, że tak jest.
Brak etykiet jednostek w UI i logach
Wpis loga czujnik 42: 37 jest bezużyteczny po sześciu miesiącach. Czy to Celsjusz? Fahrenheit? Surowy odczyt ADC? Pisz zawsze czujnik 42: 37°C lub strukturyzuj log jako { "sensor": 42, "value": 37, "unit": "celsius" }. Miejsce na dysku jest tanie; triage produkcyjny o trzeciej w nocy nie jest.
Pomylenie strefy czasowej z temperaturą
Aplikacje podróżnicze wdrażają tego buga: gdy użytkownik przekracza strefę czasową, kod usłużnie przesuwa każde pole z timestampem — w tym odczyty temperatury. Temperatura nie obchodzi stref czasowych. Timestamp odczytu wymaga logiki strefowej; wartość odczytu nie. Trzymaj je w osobnych polach, prowadź przez osobne pipeline’y konwersji.
Skróty rachunkowe na pamięć
Na chwile, gdy nie masz otwartego konwertera.
Celsjusz na Fahrenheit (z grubsza): podwój i dodaj 30. 20°C → 70°F (faktycznie 68). 30°C → 90°F (faktycznie 86). Dokładność do 2–3°F w zakresie 0–40°C, co pokrywa każdą temperaturę odczuwaną poza piecem.
Fahrenheit na Celsjusz (z grubsza): odejmij 30, podziel na pół. 80°F → 25°C (faktycznie 26,7). 60°F → 15°C (faktycznie 15,6). Ten sam zakres dokładności.
Celsjusz na Kelwin: dodaj 273 i zaokrąglij. Tracisz 0,15 K, co jest poniżej precyzji termometru w niemal wszystkim poza laboratorium fizycznym.
Dwie kotwice warte zapamiętania: 20°C = 68°F ≈ 293 K oraz 100°C = 212°F = 373,15 K. Z tych dwóch interpolacja liniowa daje wynik wystarczająco bliski dla każdego oszacowania.
Zasady „na szybko” pokrywają podróże, kuchenne przybliżenia i prognozy pogody. Dla czegokolwiek, co trafia do kodu lub dokumentu regulacyjnego, używaj dokładnych wzorów — albo otwórz nasze darmowe narzędzie do konwersji temperatury i skopiuj precyzyjną wartość.
Tabele referencyjne
Codzienne temperatury
| Kontekst | Celsjusz | Fahrenheit | Kelwin |
|---|---|---|---|
| Domowy zamrażalnik | −18°C | 0°F | 255,15 K |
| Punkt zamarzania | 0°C | 32°F | 273,15 K |
| Lodówka | 4°C | 39°F | 277,15 K |
| Temperatura pokojowa | 20°C | 68°F | 293,15 K |
| Temperatura ciała | 37°C | 98,6°F | 310,15 K |
| Próg gorączki | 38°C | 100,4°F | 311,15 K |
| Upalny letni dzień | 35°C | 95°F | 308,15 K |
| Wrzenie wody | 100°C | 212°F | 373,15 K |
Konwersje kuchenne i piekarnikowe
| Ustawienie piekarnika | Celsjusz | Fahrenheit |
|---|---|---|
| Wolne pieczenie | 125°C | 257°F |
| Pieczenie w cieple | 150°C | 302°F |
| Średnie pieczenie | 175°C | 347°F |
| Standardowe (ciasta) | 180°C | 356°F |
| Pieczenie mięsa | 190°C | 374°F |
| Mocne pieczenie | 200°C | 392°F |
| Wysokie pieczenie | 220°C | 428°F |
| Pizza / skórka chleba | 250°C | 482°F |
Amerykańskie przepisy zaokrąglają 350°F do 175°C lub 180°C w zależności od książki kucharskiej; dokładna wartość to 176,67°C. Każdy wybór działa — domowe piekarniki rzadko utrzymują temperaturę z dokładnością lepszą niż ±5°C.
Naukowe ekstrema
| Zjawisko | Kelwin | Celsjusz |
|---|---|---|
| Zero absolutne (granica teoretyczna) | 0 K | −273,15°C |
| Mikrofalowe promieniowanie tła | 2,725 K | −270,425°C |
| Ciekły hel (wrzenie, 1 atm) | 4,2 K | −268,95°C |
| Przejście nadprzewodnika (YBCO) | 93 K | −180,15°C |
| Ciekły azot (wrzenie) | 77 K | −196,15°C |
| Cień głębokiego kosmosu | ~40 K | ~−233°C |
| Suchy lód (sublimacja) | 194,65 K | −78,5°C |
| Powierzchnia Słońca | 5778 K | 5504,85°C |
| Jądro Słońca | 1,57×10⁷ K | 1,57×10⁷ °C* |
| Plazma w tokamaku (cel ITER) | 1,5×10⁸ K | ~1,5×10⁸ °C* |
*Przy takich wielkościach przesunięcie 273,15 K to błąd zaokrąglenia — Celsjusz i Kelwin są odczytywane praktycznie identycznie.
FAQ
Jaki jest wzór na przeliczenie Celsjusza na Fahrenheita?
Pomnóż wartość w Celsjuszach przez 9/5 (lub 1,8), a następnie dodaj 32: °F = °C × 9/5 + 32. Na przykład 25°C × 1,8 + 32 = 77°F. Mnożnik odzwierciedla stosunek 180:100 między rozpiętościami obu skal od zamarzania do wrzenia, a 32 wyrównuje ich różne punkty zerowe.
Jaki jest wzór na przeliczenie Fahrenheita na Celsjusza?
Odejmij 32 od wartości w Fahrenheitach, a następnie pomnóż przez 5/9: °C = (°F − 32) × 5/9. Dla 72°F obliczenie wygląda tak: (72 − 32) × 5/9 = 40 × 5/9 ≈ 22,22°C. Najpierw odejmij, potem pomnóż — odwrócenie kolejności daje błędną odpowiedź.
W jakiej temperaturze Celsjusz i Fahrenheit są równe?
Dokładnie przy −40 stopniach. Wstawienie °C = °F do wzoru konwersji daje °C = °C × 9/5 + 32, co rozwiązuje się do °C = −40. To jedyna temperatura, w której obie skale wskazują tę samą liczbę, i jest użytecznym punktem orientacyjnym do sprawdzenia zarówno realnych fal mrozu, jak i bugów w kierunku konwersji.
Jak przeliczyć 350°F na Celsjusza do pieczenia?
350°F to mniej więcej 176,67°C. Europejskie przepisy zwykle zaokrąglają to do 180°C, a wiele tabel konwersji amerykańsko-metrycznych używa 175°C. Każda wartość zadziała w domowym piekarniku — stabilność temperatury w tym zakresie jest gorsza niż błąd zaokrąglenia. Skorzystaj z naszego narzędzia do konwersji temperatury, gdy potrzebujesz dokładnych wartości.
Ile to 100°F w Celsjuszu?
100°F ≈ 37,78°C. To nieco powyżej prawidłowej temperatury ciała (37°C / 98,6°F) i jest często oznaczane jako początek stanu podgorączkowego. Wytyczne medyczne traktują 38°C / 100,4°F jako prawdziwy próg gorączki, więc 100°F jest graniczne, ale jeszcze nie klinicznie istotne.
Dlaczego zero absolutne to −273,15°C, a nie po prostu −273?
Ponieważ redefinicja SI z 2019 roku ustaliła stałą Boltzmanna dokładnie, czyniąc −273,15°C precyzyjną obliczoną wartością zera absolutnego, a nie zaokrągloną aproksymacją. Przed 2019 rokiem zero Celsjusza było powiązane z punktem potrójnym wody, a 0,15 wynikało z pomiaru. Teraz jest dokładne z definicji.
Kiedy w kodzie używać Kelwina zamiast Celsjusza?
Zawsze, gdy mnożysz, dzielisz lub podnosisz temperaturę do potęgi — promieniowanie ciała doskonale czarnego (T⁴), obliczenia gazu doskonałego, szybkości reakcji. Kelwin nigdy nie jest ujemny, więc dzielenie pozostaje stabilne. Dla różnic temperatur Celsjusz i Kelwin są wymienne (zmiana o 5 stopni jest taka sama w obu).
Czy Rankine jest jeszcze używany w 2026?
Tak, ale wąsko. Amerykańska inżynieria mechaniczna, HVAC i kosmonautyczna nadal używają Rankine’a do analizy obiegów termodynamicznych, gdy wszystkie pozostałe wejścia są w Fahrenheitach. Poza tymi dziedzinami i poza Stanami Zjednoczonymi jest praktycznie martwy. Jeśli piszesz oprogramowanie ogólnego przeznaczenia, wsparcie Rankine’a to tania polisa, ale rzadko nośna.
Jak przeliczyć temperaturę w zapytaniu SQL?
Wstaw wzór w linii lub użyj kolumny GENERATED ALWAYS AS. Przykład: SELECT celsius * 9.0 / 5.0 + 32.0 AS fahrenheit FROM readings. 9.0 i 5.0 (a nie 9 i 5) wymuszają arytmetykę zmiennoprzecinkową w większości dialektów; dzielenie całkowitoliczbowe po cichu obetnie wynik. Dodaj CHECK (celsius >= -273.15), aby odrzucać bzdurne wartości w momencie wstawiania.
Jaki jest najprostszy sposób przeliczenia Celsjusza na Fahrenheita w pamięci?
Podwój wartość w Celsjuszach i dodaj 30. 22°C × 2 + 30 = 74°F (faktycznie 71,6°F). Dokładność do około 2°F w zakresie 0–30°C, co pokrywa niemal wszystkie odczyty pogodowe i wewnętrzne. Dla odwrotnego kierunku odejmij 30 od Fahrenheita i podziel na pół.
Dlaczego mój konwerter temperatury zwraca 98,599999 dla 37°C?
Ponieważ 9/5 = 1,8 nie da się dokładnie zapisać w binarnym zapisie zmiennoprzecinkowym, więc 37 × 9 / 5 + 32 wychodzi jako 98.60000000000001, a nie 98,6. To zachowanie IEEE 754, a nie bug. Użyj toFixed(2) do wyświetlania lub przejdź na bibliotekę dziesiętną, jeśli precyzja końcówki cyfr ma znaczenie w twojej dziedzinie.
Czy mogę przechowywać temperatury jako liczby całkowite, aby uniknąć problemów zmiennoprzecinkowych?
Tak — przechowuj decyCelsjusze (temperaturę pomnożoną przez 10). 37,0°C staje się 370, 22,5°C staje się 225. Matematyka całkowitoliczbowa jest dokładna, a przez 10 dzielisz dopiero na granicy wyświetlania. Ten wzorzec jest powszechny w systemach wbudowanych i wysokowolumenowych bazach danych szeregów czasowych, w których dysk i CPU mają znaczenie.
Jak obsługiwać liczby bez jednostek w odpowiedzi API?
Nie obsługuj. Każde pole temperatury powinno nieść jawną jednostkę, albo w nazwie pola (temp_celsius, temp_k), albo w siostrzanym polu unit. Jeśli jesteś konsumentem, a API tego nie dostarcza, wyraźnie udokumentuj założenie w kodzie i napisz test kontraktowy, który zepsuje się, gdy domyślna wartość API się zmieni.
Jaki jest punkt wrzenia wody we wszystkich czterech skalach?
100°C = 212°F = 373,15 K = 671,67°R, przy standardowym ciśnieniu atmosferycznym (jedna atmosfera, 101,325 kPa). Ciśnienie ma znaczenie: na wysokości Denver woda wrze około 95°C; na szczycie Everestu bliżej 71°C. Punkt wrzenia jest wielkością zależną od ciśnienia, a nie uniwersalną stałą.
Czy temperatura wpływa na obliczenia zmiennoprzecinkowe inaczej niż inne liczby?
Nie — wartości temperatury zachowują się jak każda inna liczba zmiennoprzecinkowa. Praktyczna pułapka jest taka, że współczynniki 5/9 i 9/5 we wzorach konwersji wprowadzają błąd zaokrąglenia na każdym kroku. Dla wartości w kelwinach w zakresie 200–400 precyzja jest aż nadto wystarczająca. Dla wartości ujemnych w Celsjuszach blisko granicy reprezentowalnych liczb double precyzja również pozostaje w porządku. Prawdziwa pułapka to łańcuchowe konwersje kumulujące małe błędy — przelicz raz i przechowaj formę kanoniczną.