如何在 PHP 中进行小数和分数之间的转换
How to convert between decimals and fractions in PHP
我正在尝试将数字乘以 2,这些数字要么是整数,要么是分数。我通过 WordPress 上的 ACF 字段作为文本字段动态提取这些数字。但是其中一些动态数字不是分数,而是整数,例如 3 或 1。我想要做的是将数字加倍,因此 3/4 将是 1 1/2。但是当我乘以 3/4 之类的分数时,它会变成 1.5。我使用 fubars 代码让这些数字保留为分数,但后来我 运行 进入了正确分数显示为小数的问题。
当您在份量中单击 6 时,它应该将食谱加倍作为分数。
这是我的模板中处理这些数字的代码片段(我 javascript 只是 hiding/showing 根据服务大小点击的数字):
<?php
$number = get_sub_field('number'); // some numbers are 1/2 and 3/4 and some are 1 or 3
$double = 2;
$result = $number * $double;
?>
<?php echo $result; ?>
是否最好将它们的值设置为小数,但以某种方式使用 jQuery/javascript 将其转换为仅用于前端的分数?
想法?非常感谢!
告诉我。
谢谢!
编辑
对于那些通过 WordPress 使用 ACF 字段的人,这里有一个简单的解决方案。 $number 字段是一个数字 ACF 字段,因此以小数开头。
<!-- Create the function -->
function convert($number) {
<!-- pull in the number field and multiply it by 2 (since we are
doubling -->
$number = $number * 2;
<!-- Create and Array of all the possibilities of fractions (this
instance is cooking measurements -->
$fractions = array(
0625 => '1/16',
1875 => '3/16',
3125 => '5/16',
4375 => '7/16',
5625 => '9/16',
6575 => '11/16',
8125 => '13/16',
875 => '14/16',
9375 => '15/16',
125 => '1/8',
33 => '1/3',
25 => '1/4',
66 => '2/3',
5 => '1/2',
375 => '3/8',
625 => '5/8',
75 => '3/4'
);
<!-- explode the part after the decimal point and convert it to the
fraction above -->
$parts = explode('.', $number);
if(isset($parts[1])) {
echo $parts[0].' '.$fractions[$parts[1]];
} else {
echo $number;
}
}
然后只需在要拉到 WP 模板的 $number 值周围添加 convert() 即可,因此 convert($number)。
当您的数字字段包含小数值时,PHP 实际上会将其视为 string
,而不是 number
,因此需要将其转换为a number
才能用它来进行算术运算。
由于您更新了问题的要求,我修改了我的答案以包含两个函数。我编写了一个函数将小数值转换为小数值,另一个函数将小数值转换为小数值。
您可以在此处查看一个工作示例:https://3v4l.org/ft0ZT
<?php
function fractionToDecimal($fraction)
{
// Split fraction into whole number and fraction components
preg_match('/^(?P<whole>\d+)?\s?((?P<numerator>\d+)\/(?P<denominator>\d+))?$/', $fraction, $components);
// Extract whole number, numerator, and denominator components
$whole = $components['whole'] ?: 0;
$numerator = $components['numerator'] ?: 0;
$denominator = $components['denominator'] ?: 0;
// Create decimal value
$decimal = $whole;
$numerator && $denominator && $decimal += ($numerator/$denominator);
return $decimal;
}
function decimalToFraction($decimal)
{
// Determine decimal precision and extrapolate multiplier required to convert to integer
$precision = strpos(strrev($decimal), '.') ?: 0;
$multiplier = pow(10, $precision);
// Calculate initial numerator and denominator
$numerator = $decimal * $multiplier;
$denominator = 1 * $multiplier;
// Extract whole number from numerator
$whole = floor($numerator / $denominator);
$numerator = $numerator % $denominator;
// Find greatest common divisor between numerator and denominator and reduce accordingly
$factor = gmp_intval(gmp_gcd($numerator, $denominator));
$numerator /= $factor;
$denominator /= $factor;
// Create fraction value
$fraction = [];
$whole && $fraction[] = $whole;
$numerator && $fraction[] = "{$numerator}/{$denominator}";
return implode(' ', $fraction);
}
// Examples
var_dump(fractionToDecimal('1/25')); // 0.04
var_dump(fractionToDecimal('2 3/4')); // 2.75
var_dump(fractionToDecimal('6/4')); // 1.5
var_dump(decimalToFraction(1.375)); // 1 3/8
var_dump(decimalToFraction(3)); // 3
var_dump(decimalToFraction(2.875)); // 2 7/8
您不是将 100 乘以 0.1,而是乘以 0.09999999998
... 当涉及到 (int) 时,它会将数字转换为 4.999
到 4
,因此当使用 (int).
计数时,您的结果 1020636.999999999
变为 1020636
当您关心所涉及的精度时,您应该使用 bcmul() 函数。这是一个 "optional" 扩展,但如果您关心精度,那么很快就会开始需要它。
示例:
multiplier = 100000000;
$value = 0.01020637;
echo bcmul($value, $multiplier, 0);
我正在尝试将数字乘以 2,这些数字要么是整数,要么是分数。我通过 WordPress 上的 ACF 字段作为文本字段动态提取这些数字。但是其中一些动态数字不是分数,而是整数,例如 3 或 1。我想要做的是将数字加倍,因此 3/4 将是 1 1/2。但是当我乘以 3/4 之类的分数时,它会变成 1.5。我使用 fubars 代码让这些数字保留为分数,但后来我 运行 进入了正确分数显示为小数的问题。
当您在份量中单击 6 时,它应该将食谱加倍作为分数。
这是我的模板中处理这些数字的代码片段(我 javascript 只是 hiding/showing 根据服务大小点击的数字):
<?php
$number = get_sub_field('number'); // some numbers are 1/2 and 3/4 and some are 1 or 3
$double = 2;
$result = $number * $double;
?>
<?php echo $result; ?>
是否最好将它们的值设置为小数,但以某种方式使用 jQuery/javascript 将其转换为仅用于前端的分数?
想法?非常感谢!
告诉我。
谢谢!
编辑
对于那些通过 WordPress 使用 ACF 字段的人,这里有一个简单的解决方案。 $number 字段是一个数字 ACF 字段,因此以小数开头。
<!-- Create the function -->
function convert($number) {
<!-- pull in the number field and multiply it by 2 (since we are
doubling -->
$number = $number * 2;
<!-- Create and Array of all the possibilities of fractions (this
instance is cooking measurements -->
$fractions = array(
0625 => '1/16',
1875 => '3/16',
3125 => '5/16',
4375 => '7/16',
5625 => '9/16',
6575 => '11/16',
8125 => '13/16',
875 => '14/16',
9375 => '15/16',
125 => '1/8',
33 => '1/3',
25 => '1/4',
66 => '2/3',
5 => '1/2',
375 => '3/8',
625 => '5/8',
75 => '3/4'
);
<!-- explode the part after the decimal point and convert it to the
fraction above -->
$parts = explode('.', $number);
if(isset($parts[1])) {
echo $parts[0].' '.$fractions[$parts[1]];
} else {
echo $number;
}
}
然后只需在要拉到 WP 模板的 $number 值周围添加 convert() 即可,因此 convert($number)。
当您的数字字段包含小数值时,PHP 实际上会将其视为 string
,而不是 number
,因此需要将其转换为a number
才能用它来进行算术运算。
由于您更新了问题的要求,我修改了我的答案以包含两个函数。我编写了一个函数将小数值转换为小数值,另一个函数将小数值转换为小数值。
您可以在此处查看一个工作示例:https://3v4l.org/ft0ZT
<?php
function fractionToDecimal($fraction)
{
// Split fraction into whole number and fraction components
preg_match('/^(?P<whole>\d+)?\s?((?P<numerator>\d+)\/(?P<denominator>\d+))?$/', $fraction, $components);
// Extract whole number, numerator, and denominator components
$whole = $components['whole'] ?: 0;
$numerator = $components['numerator'] ?: 0;
$denominator = $components['denominator'] ?: 0;
// Create decimal value
$decimal = $whole;
$numerator && $denominator && $decimal += ($numerator/$denominator);
return $decimal;
}
function decimalToFraction($decimal)
{
// Determine decimal precision and extrapolate multiplier required to convert to integer
$precision = strpos(strrev($decimal), '.') ?: 0;
$multiplier = pow(10, $precision);
// Calculate initial numerator and denominator
$numerator = $decimal * $multiplier;
$denominator = 1 * $multiplier;
// Extract whole number from numerator
$whole = floor($numerator / $denominator);
$numerator = $numerator % $denominator;
// Find greatest common divisor between numerator and denominator and reduce accordingly
$factor = gmp_intval(gmp_gcd($numerator, $denominator));
$numerator /= $factor;
$denominator /= $factor;
// Create fraction value
$fraction = [];
$whole && $fraction[] = $whole;
$numerator && $fraction[] = "{$numerator}/{$denominator}";
return implode(' ', $fraction);
}
// Examples
var_dump(fractionToDecimal('1/25')); // 0.04
var_dump(fractionToDecimal('2 3/4')); // 2.75
var_dump(fractionToDecimal('6/4')); // 1.5
var_dump(decimalToFraction(1.375)); // 1 3/8
var_dump(decimalToFraction(3)); // 3
var_dump(decimalToFraction(2.875)); // 2 7/8
您不是将 100 乘以 0.1,而是乘以 0.09999999998
... 当涉及到 (int) 时,它会将数字转换为 4.999
到 4
,因此当使用 (int).
1020636.999999999
变为 1020636
当您关心所涉及的精度时,您应该使用 bcmul() 函数。这是一个 "optional" 扩展,但如果您关心精度,那么很快就会开始需要它。
示例:
multiplier = 100000000;
$value = 0.01020637;
echo bcmul($value, $multiplier, 0);