0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

インチをcmに変換するだけでは足りない?分数インチ・画面サイズ・JavaScript実装まで整理する

0
Posted at

海外製品の仕様やディスプレイサイズを扱っていると、

27 inch
15.6"
3/8 inch
1 1/2 inch

のような表記をよく見かけます。

インチからcmへの換算自体は単純です。

1 inch = 2.54 cm

したがって、

cm = inch × 2.54

です。

ただし、実際にプログラムで変換処理を作るとなると、

  • 小数インチ
  • 分数インチ
  • " や in の除去
  • 1 1/2 のような帯分数
  • 小数誤差
  • モニターの対角線サイズ
  • 呼び径と実寸の違い

など、単純な掛け算だけでは済まないケースがあります。

この記事では、インチ→cm変換を実装するときに考えておきたいポイントを整理します。

基本式は1 inch = 2.54 cm

まず基準になるのは、

1 inch = 2.54 cm

です。

これは換算の基準値として定義されています。

たとえば、

10 inch

なら、

10 × 2.54
= 25.4 cm

です。

27インチなら、

27 × 2.54
= 68.58 cm

となります。

JavaScriptなら非常に単純です。

function inchToCm(inch) {
  return inch * 2.54;
}

console.log(inchToCm(27));
// 68.58

逆変換は、

inch = cm ÷ 2.54

です。

function cmToInch(cm) {
  return cm / 2.54;
}

console.log(cmToInch(50));
// 19.68503937007874

実際には丸め処理が必要になる

cm→inchのような割り算では、

19.68503937007874

のように長い小数になることがあります。

表示用途なら、

function round(value, digits = 2) {
  const factor = 10 ** digits;
  return Math.round(value * factor) / factor;
}

console.log(round(cmToInch(50), 2));
// 19.69

のように丸めることができます。

ただし、

計算途中で毎回丸めない

方が安全です。

内部ではできるだけ元の精度を維持し、最後の表示段階だけ丸める方が誤差を小さくできます。

小数インチはそのまま変換できる

たとえば15.6インチなら、

15.6 × 2.54
= 39.624 cm

です。

console.log(inchToCm(15.6));
// 39.624

特別な処理は必要ありません。

問題になるのは、

1/2
3/8
5/16

のような分数インチです。

分数インチを小数へ変換する

たとえば、

3/8 inch

なら、

3 ÷ 8
= 0.375 inch

です。

cmへ変換すると、

0.375 × 2.54
= 0.9525 cm

です。

つまり、

3/8 inch
= 0.9525 cm
= 9.525 mm

となります。

同様に、

1/2 inch
= 0.5 inch
= 1.27 cm
1/4 inch
= 0.25 inch
= 0.635 cm

です。

JavaScriptで分数インチを処理する

単純な分数なら、

function fractionToDecimal(value) {
  const [numerator, denominator] = value.split("/").map(Number);

  if (!denominator) {
    throw new Error("Invalid fraction");
  }

  return numerator / denominator;
}

console.log(fractionToDecimal("3/8"));
// 0.375

cmまで変換するなら、

function fractionInchToCm(value) {
  const inch = fractionToDecimal(value);
  return inch * 2.54;
}

console.log(fractionInchToCm("3/8"));
// 0.9525

です。

1 1/2 inch のような帯分数

海外製品では、

1 1/2"

のような表記もあります。

これは、

1 + 1/2
= 1.5 inch

です。

cmへ変換すると、

1.5 × 2.54
= 3.81 cm

となります。

帯分数を処理する場合は、

整数部
分数部

を分けて解析します。

function mixedFractionToDecimal(value) {
  const parts = value.trim().split(/\s+/);

  if (parts.length === 1) {
    if (parts[0].includes("/")) {
      return fractionToDecimal(parts[0]);
    }

    return Number(parts[0]);
  }

  if (parts.length === 2) {
    return Number(parts[0]) + fractionToDecimal(parts[1]);
  }

  throw new Error("Invalid mixed fraction");
}

console.log(mixedFractionToDecimal("1 1/2"));
// 1.5

console.log(mixedFractionToDecimal("2 3/8"));
// 2.375

", in, inch を除去する

実際の入力は、

15.6"
3/8 in
1 1/2 inch

のように単位付きで来ることがあります。

そのままNumber()に渡すと失敗します。

まず単位表記を除去します。

function normalizeInchInput(value) {
  return value
    .toLowerCase()
    .replace(/inches|inch|in/g, "")
    .replace(/"/g, "")
    .trim();
}

たとえば、

console.log(normalizeInchInput('15.6"'));
// 15.6

console.log(normalizeInchInput("3/8 inch"));
// 3/8

です。

小数・分数・帯分数をまとめて処理する

組み合わせると、

function parseInch(value) {
  const normalized = normalizeInchInput(value);

  return mixedFractionToDecimal(normalized);
}

function convertInchToCm(value) {
  return parseInch(value) * 2.54;
}

として、

console.log(convertInchToCm('27"'));
// 68.58

console.log(convertInchToCm("3/8 inch"));
// 0.9525

console.log(convertInchToCm("1 1/2 in"));
// 3.81

のように処理できます。

全角文字も考えるなら正規化する

日本語ユーザー向けのフォームでは、

27
15.6

のような全角数字が入力されることがあります。

その場合はUnicode正規化を使うと便利です。

const normalized = value.normalize("NFKC");

たとえば、

console.log("15.6".normalize("NFKC"));
// 15.6

となります。

入力値の前処理として、

function normalizeInput(value) {
  return value
    .normalize("NFKC")
    .toLowerCase()
    .replace(/inches|inch|in/g, "")
    .replace(/"/g, "")
    .trim();
}

としておくと扱いやすくなります。

Unicodeの引用符にも注意

コピー&ペーストされた文章では、

15.6”

のように、ASCIIの"ではなく、

”
″

などが入ることがあります。

そのため実装では、

.replace(/["”″]/g, "")

のように複数の記号を除去しておくと安定します。

不正入力をどう扱うか

たとえば、

3/0
abc
1 2 3

のような入力は変換できません。

そのため、

const result = parseInch(input);

if (!Number.isFinite(result)) {
  throw new Error("Invalid input");
}

のように検証が必要です。

特に、

3/0

はJavaScriptでは、

3 / 0
// Infinity

になるため注意が必要です。

Floating Pointの誤差

JavaScriptのNumberはIEEE 754の倍精度浮動小数点数です。

そのため、

0.1 + 0.2

が、

0.30000000000000004

になるように、計算結果に小さな誤差が出ることがあります。

インチ換算でも、

cm / 2.54

の結果が長い小数になるのは普通です。

表示値として、

19.69 inch

のように見せたい場合は、

最後に桁数を決めて丸める方がよいでしょう。

toFixed() は文字列を返す

たとえば、

const result = (50 / 2.54).toFixed(2);

console.log(result);
// "19.69"

になります。

注意したいのは、

typeof result
// "string"

という点です。

さらに数値計算を続けるなら、

Number(result)

へ戻す必要があります。

そのため、

計算用の値
表示用の値

を分けると設計しやすくなります。

モニターの27インチは幅68.58cmではない

ここからは実際の用途でよくある誤解です。

27インチディスプレイなら、

27 × 2.54
= 68.58 cm

です。

しかし、この68.58cmは通常、

画面の対角線

です。

横幅ではありません。

16:9の横幅を求める

対角線をd、横をw、縦をhとすると、

w² + h² = d²

です。

16:9なら、

w : h = 16 : 9

なので、

w = d × 16 / √(16² + 9²)
h = d × 9 / √(16² + 9²)

です。

JavaScriptなら、

function screenSize(inch, ratioWidth, ratioHeight) {
  const diagonalCm = inch * 2.54;

  const ratioDiagonal = Math.sqrt(
    ratioWidth ** 2 + ratioHeight ** 2
  );

  return {
    diagonalCm,
    widthCm:
      diagonalCm * ratioWidth / ratioDiagonal,
    heightCm:
      diagonalCm * ratioHeight / ratioDiagonal
  };
}

console.log(screenSize(27, 16, 9));

概算では、

対角線:約68.58cm
横幅:約59.8cm
高さ:約33.6cm

となります。

21:9なら同じ27インチでも形が違う

同じ27インチでも、

16:9
21:9

では画面の横幅と高さが変わります。

つまり、

27 inch = 68.58cm

という情報だけでは、

机に置けるか
横幅が何cmか

は判断できません。

インチとアスペクト比の両方が必要です。

画面サイズと本体サイズも違う

さらに、

画面幅

と、

モニター本体の幅

も同じではありません。

実際の商品には、

  • ベゼル
  • フレーム
  • スタンド
  • 筐体

があります。

そのため、設置スペースを計算するときは、最終的にはメーカーの外形寸法を確認する必要があります。

タイヤの17インチも実寸43.18cmではない

タイヤサイズで、

225/45R17

と書かれている場合、

17はインチです。

17 × 2.54
= 43.18cm

ですが、

タイヤ全体の外径が43.18cm

という意味ではありません。

これはホイールのリム径です。

タイヤ全体の直径には、サイドウォールの高さが加わります。

呼び寸法と実寸を分ける

タイヤ以外にも、

  • 配管
  • ネジ
  • 工具
  • 自転車タイヤ

では、

○インチ

が実測値ではなく、

規格上の呼び寸法

として使われることがあります。

この場合、

1 inch = 25.4mm

だからといって、

「1インチ規格の商品を測れば必ず25.4mm」

とは限りません。

この違いは変換ツールを作るときにも明示した方がよいポイントです。

工具の3/8インチは実寸換算できる

ソケットレンチの差込角などでは、

1/4 inch
3/8 inch
1/2 inch

といった表記があります。

それぞれ、

1/4 inch = 6.35mm
3/8 inch = 9.525mm
1/2 inch = 12.7mm

です。

このように実際の長さとして扱えるケースもあります。

つまり重要なのは、

そのインチ表記が、実寸なのか規格名なのか

を確認することです。

変換ツール側でどこまで責任を持つか

インチ・cm変換ツールを作る場合、

15.6

を、

39.624cm

へ変換する部分は簡単です。

しかしユーザーが本当に知りたいことは、

15.6インチノートPCは横何cm?

かもしれません。

この場合、

15.6 × 2.54

だけを返すと、

「39.624cmが横幅」

と誤解される可能性があります。

ツールUIや説明文では、

ディスプレイのインチ表記は通常、対角線です

と補足すると親切です。

インチ・cmをすぐ相互変換したい場合

整数・小数のインチとcmをそのまま相互変換したい場合は、こちらで確認できます。

単純換算をすぐ確認したい場合や、海外製品の寸法を日本で馴染みのあるcmへ直したい場合に使えます。

入力パーサーを作るならテストケースが重要

分数インチ対応まで実装するなら、最低限、

1
1.5
1/2
3/8
1 1/2
15.6"
3/8 inch
1 1/2

のような入力をテストした方がよいでしょう。

期待結果も固定しておきます。

[
  ["1", 2.54],
  ["1.5", 3.81],
  ["1/2", 1.27],
  ["3/8", 0.9525],
  ["1 1/2", 3.81]
]

変換処理そのものより、

入力の揺れ

でバグが出ることの方が多いです。

数値と表示文字列を分ける

設計としては、

内部値:

3.81

表示値:

3.81 cm

を分離しておく方が扱いやすいです。

たとえば、

function formatCm(value, digits = 2) {
  return `${value.toFixed(digits)} cm`;
}

とすれば、

const cm = convertInchToCm("1 1/2");

console.log(formatCm(cm));
// 3.81 cm

となります。

逆変換で分数表示したい場合

cm→inchでは、

12.7mm
↓
0.5 inch

だけでなく、

1/2 inch

と表示したいことがあります。

この場合、

小数を近い分数へ変換

する処理が必要です。

たとえば工具用途なら、

1/2
1/4
1/8
1/16
1/32

など、特定の分母へ丸める方式が実用的です。

1/16単位へ丸める例

たとえば、

function decimalToFraction(value, denominator = 16) {
  const whole = Math.floor(value);
  const numerator = Math.round(
    (value - whole) * denominator
  );

  return {
    whole,
    numerator,
    denominator
  };
}

ただし、

16/16

になった場合は、

1

へ繰り上げる処理が必要です。

また、

2/4

を、

1/2

へ約分する処理も必要です。

表示形式まで対応すると、単純な単位変換より実装はかなり深くなります。

単位変換では意味まで変換しない

最後に重要なのは、

数値の単位変換と、製品規格の解釈は別

ということです。

たとえば、

27 inch

を、

68.58cm

へ変換することはできます。

しかし、

27インチモニターの横幅 = 68.58cm

とは言えません。

同じように、

1インチ管 = 外径25.4mm

とも限りません。

変換ツールが保証できるのは、

数値としてのインチ
↔
数値としてのcm

です。

その数値が、

対角線
外径
呼び径
本体幅
規格名

のどれなのかは、元データの意味を確認する必要があります。

まとめ

インチからcmへの基本式は、

cm = inch × 2.54

です。

しかし実際に変換機能を実装するなら、

  • 小数インチ
  • 分数インチ
  • 帯分数
  • 単位記号
  • 全角入力
  • 不正入力
  • 浮動小数点誤差
  • 丸め
  • 画面の対角線
  • 呼び寸法と実寸

まで考えると、単純な掛け算以上のテーマになります。

特にUIを作る場合は、

変換した数値が何を意味するか

まで誤解されない設計が重要です。

1 inch = 2.54 cmはシンプルですが、その数字が使われる文脈まで考えると、単位変換は意外と奥が深い処理です。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?