ミリメートルを分数(インチ単位)に変換するphp関数が本当に必要です。
例えば:
16mm = 5/8 インチ
321mm = 12 41⁄64 インチ
PHPの例を高低で検索しましたが、完全に困惑しています。このようなものを構築した親切な魂がそこにあるでしょうか。
助けてくれてどうもありがとう!
簡単な部分は、ミリメートルからインチに変換することです–25.4で割るだけです。難しいのは、最も近い32番目(または16番目、64番目など)を見つけることです。
この回答の最後に、toMixedNumber()と呼ばれる関数を含めます。次のアルゴリズムに従います。
関数の使用は簡単です。
const MM_PER_IN = 25.4;
echo toMixedNumber(14 / MM_PER_IN, 32) . "\n"; // 9/16
echo toMixedNumber(55 / MM_PER_IN, 32) . "\n"; // 2 5/32
echo toMixedNumber(321 / MM_PER_IN, 32) . "\n"; // 12 5/8
echo toMixedNumber(321 / MM_PER_IN, 64) . "\n"; // 12 41/64
興味深いことに、分母が常に2の累乗である場合(あなたの場合のように)、最適化が可能になります。正の分子を持つ適切な2進分数の場合、分子の最下位の「1」ビットの値は、分子と分母のGCDです。
if ($reduce) {
$gcd = $num & -$num;
$num /= $gcd;
$denom /= $gcd;
}
番号がsignedintのビットに1つしかないかどうかをチェックするために、革新的な方法のビットをいじるトリックを採用しました。私のコンピューターでは、関数が約20%高速化されます。(任意のビットの値がより重要なビットのすべての値の除数であり、分母の唯一の「1」ビットが分子のどのビットよりも重要であるため、これは機能します。)ただし、私はそれを含めないことを選択しました。
function toMixedNumber($arg, $denom, $reduce = true) {
$num = round($arg * $denom);
$int = (int)($num / $denom);
$num %= $denom;
if (!$num) {
return "$int";
}
if ($reduce) {
// Use Euclid's algorithm to find the GCD.
$a = $num < 0 ? -$num : $num;
$b = $denom;
while ($b) {
$t = $b;
$b = $a % $t;
$a = $t;
}
$num /= $a;
$denom /= $a;
}
if ($int) {
// Suppress minus sign in numerator; keep it only in the integer part.
if ($num < 0) {
$num *= -1;
}
return "$int $num/$denom";
}
return "$num/$denom";
}