PHP 中没有分数类型,只有浮点数,而我们实际开发中由于浮点数精度问题,有时需要使用分数,这个 Fraction 类将会解决这个问题。
(随手写的,如有不足,欢迎指出)
代码如下:
<?php
/**
* 名称:Fraction
* 描述:分数类,用于定义分数、进行分数计算等
* 作者:滑稽mc(HuajiMC@126.com)
* Copyright © 2021 HuajiMC. All Rights Reserved.
*/
class Fraction {
public $nume; //分子
public $deno; //分母
private function __construct() {}
/*
创建方法1:通过整数或浮点数(不准确,不建议使用)创建分数
$number:待转换的数值
*/
private function create1($number) {
if(is_int($number)) {
$this->create2($number,1);
} else if(is_float($number)) {
$this->create2($number * (10 ** 4),10 ** 4);
}
return $this;
}
/*
创建方法2:通过分子分母创建分数
$deno:分母
$nume:分子
*/
private function create2($nume,$deno) {
if(is_float($nume) || is_float($deno)) {
$nume = $nume * (10 ** 4);
$deno = $deno * (10 ** 4);
}
//化简
$divisor = $this->max_divisor($nume,$deno);
$this->nume = $nume / $divisor;
$this->deno = $deno / $divisor;
return $this;
}
/*
求两个数的最大公约数
$a:第一个数
$b:第二个数
*/
public static function max_divisor($a,$b) {
if($a % $b == 0) {
return $b;
} else {
return self::max_divisor($b,$a % $b);
}
}
/*
将分数转换为php数据类型
*/
public function value() {
return $this->nume / $this->deno;
}
public static function __callStatic($method,$args) {
//创建分数
if($method == 'create') {
$name = $method . count($args);
$obj = new self;
return $obj->$name(...$args);
}
}
public function __toString() {
return $this->nume . '/' . $this->deno;
}
/*
分数加法
*/
public static function plus(...$numbers) {
$nume = 0;
$deno = 1;
foreach($numbers as $number) {
$number = $number instanceof self ? $number : self::create($number);
$temp = $deno;
$nume *= $number->deno;
$deno *= $number->deno;
$nume = $nume + $number->nume * $temp;
}
return self::create($nume,$deno);
}
/*
分数减法
*/
public static function subtract(...$numbers) {
$nume = 0;
$deno = 1;
foreach($numbers as $number) {
$number = $number instanceof self ? $number : self::create($number);
$temp = $deno;
$nume *= $number->deno;
$deno *= $number->deno;
$nume = $number->nume * $temp - $nume;
}
return self::create(-$nume,$deno);
}
/*
分数乘法
*/
public static function multiply(...$numbers) {
$nume = 1;
$deno = 1;
foreach($numbers as $number) {
$number = $number instanceof self ? $number : self::create($number);
$nume *= $number->nume;
$deno *= $number->deno;
}
return self::create($nume,$deno);
}
/*
分数除法
*/
public static function divide(...$numbers) {
$result = $numbers[0];
unset($numbers[0]);
foreach($numbers as $number) {
$number = $number instanceof self ? $number : self::create($number);
$temp = $number->nume;
$number->nume = $number->deno;
$number->deno = $temp;
$result = self::multiply($number,$result);
}
return $result;
}
}