php中如何四舍五入到最接近的有效数字

发布于 2024-11-03 19:27:10 字数 170 浏览 4 评论 0原文

php 有没有什么巧妙的方法可以四舍五入到最接近的有效数字?

所以:

0->0
9->9
10->10
17->10
77->70
114->100
745->700
1200->1000

Is there any slick way to round down to the nearest significant figure in php?

So:

0->0
9->9
10->10
17->10
77->70
114->100
745->700
1200->1000

?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

要走干脆点 2024-11-10 19:27:10
$numbers = array(1, 9, 14, 53, 112, 725, 1001, 1200);
foreach($numbers as $number) {
    printf('%d => %d'
            , $number
            , $number - $number % pow(10, floor(log10($number)))
            );
    echo "\n";
}

不幸的是,当 $number 为 0 时,这会严重失败,但它确实会产生正整数的预期结果。这是一个纯数学解决方案。

$numbers = array(1, 9, 14, 53, 112, 725, 1001, 1200);
foreach($numbers as $number) {
    printf('%d => %d'
            , $number
            , $number - $number % pow(10, floor(log10($number)))
            );
    echo "\n";
}

Unfortunately this fails horribly when $number is 0, but it does produce the expected result for positive integers. And it is a math-only solution.

一场春暖 2024-11-10 19:27:10

这是一个纯数学解决方案。如果您想要向上或向下舍入,而不仅仅是向下舍入,这也是一个更灵活的解决方案。它适用于 0 :)

if($num === 0) return 0;
$digits = (int)(log10($num));
$num = (pow(10, $digits)) * floor($num/(pow(10, $digits)));

您可以将 floor 替换为 roundceil。实际上,如果您想四舍五入到最接近的值,您可以进一步简化第三行。

$num = round($num, -$digits);

Here's a pure math solution. This is also a more flexible solution if you ever wanted to round up or down, and not just down. And it works on 0 :)

if($num === 0) return 0;
$digits = (int)(log10($num));
$num = (pow(10, $digits)) * floor($num/(pow(10, $digits)));

You could replace floor with round or ceil. Actually, if you wanted to round to the nearest, you could simplify the third line even more.

$num = round($num, -$digits);
后eg是否自 2024-11-10 19:27:10

如果您确实想要一个数学解决方案,请尝试以下操作:

function floorToFirst($int) {
    if (0 === $int) return 0;

    $nearest = pow(10, floor(log($int, 10)));
    return floor($int / $nearest) * $nearest;
}

If you do want to have a mathy solution, try this:

function floorToFirst($int) {
    if (0 === $int) return 0;

    $nearest = pow(10, floor(log($int, 10)));
    return floor($int / $nearest) * $nearest;
}
短叹 2024-11-10 19:27:10

像这样的事情:

$str = (string)$value;
echo (int)($str[0] . str_repeat('0', strlen($str) - 1));

Something like this:

$str = (string)$value;
echo (int)($str[0] . str_repeat('0', strlen($str) - 1));
凉墨 2024-11-10 19:27:10

这完全不是数学问题,但我只是利用刺痛长度来做到这一点......可能有一种更平滑的方法来处理它,但你可以用以下方法完成它

function significant($number){
    $digits = count($number);
    if($digits >= 2){
        $newNumber = substr($number,0,1);
        $digits--;
        for($i = 0; $i < $digits; $i++){
            $newNumber = $newNumber . "0";
        }
    }
    return $newNumber;
}

It's totally non-mathy, but I would just do this utilizing sting length... there's probably a smoother way to handle it but you could acomplish it with

function significant($number){
    $digits = count($number);
    if($digits >= 2){
        $newNumber = substr($number,0,1);
        $digits--;
        for($i = 0; $i < $digits; $i++){
            $newNumber = $newNumber . "0";
        }
    }
    return $newNumber;
}
可可 2024-11-10 19:27:10

基于数学的替代方案:

$mod = pow(10, intval(round(log10($value) - 0.5))); 
$answer = ((int)($value / $mod)) * $mod;

A math based alternative:

$mod = pow(10, intval(round(log10($value) - 0.5))); 
$answer = ((int)($value / $mod)) * $mod;
迎风吟唱 2024-11-10 19:27:10

我知道这是一个旧线程,但我在寻找如何解决这个问题的灵感时阅读了它。这是我想出的:

class Math
{
    public static function round($number, $numberOfSigFigs = 1)
    {
        // If the number is 0 return 0
        if ($number == 0) {
            return 0;
        }

        // Deal with negative numbers
        if ($number < 0) {
            $number = -$number;
            return -Math::sigFigRound($number, $numberOfSigFigs);
        }

        return Math::sigFigRound($number, $numberOfSigFigs);
    }

    private static function sigFigRound($number, $numberOfSigFigs)
    {
        // Log the number passed
        $log = log10($number);

        // Round $log down to determine the integer part of the log
        $logIntegerPart = floor($log);

        // Subtract the integer part from the log itself to determine the fractional part of the log
        $logFractionalPart = $log - $logIntegerPart;

        // Calculate the value of 10 raised to the power of $logFractionalPart
        $value = pow(10, $logFractionalPart);

        // Round $value to specified number of significant figures
        $value = round($value, $numberOfSigFigs - 1);

        // Return the correct value
        return $value * pow(10, $logIntegerPart); 
    }
}

I know this is an old thread but I read it when looking for inspiration on how to solve this problem. Here's what I came up with:

class Math
{
    public static function round($number, $numberOfSigFigs = 1)
    {
        // If the number is 0 return 0
        if ($number == 0) {
            return 0;
        }

        // Deal with negative numbers
        if ($number < 0) {
            $number = -$number;
            return -Math::sigFigRound($number, $numberOfSigFigs);
        }

        return Math::sigFigRound($number, $numberOfSigFigs);
    }

    private static function sigFigRound($number, $numberOfSigFigs)
    {
        // Log the number passed
        $log = log10($number);

        // Round $log down to determine the integer part of the log
        $logIntegerPart = floor($log);

        // Subtract the integer part from the log itself to determine the fractional part of the log
        $logFractionalPart = $log - $logIntegerPart;

        // Calculate the value of 10 raised to the power of $logFractionalPart
        $value = pow(10, $logFractionalPart);

        // Round $value to specified number of significant figures
        $value = round($value, $numberOfSigFigs - 1);

        // Return the correct value
        return $value * pow(10, $logIntegerPart); 
    }
}
骑趴 2024-11-10 19:27:10

虽然这里的函数有效,但我需要非常小的数字的有效数字(将低价值的加密货币与比特币进行比较)。

在 PHP 中将数字格式化为 N 个有效数字 的答案有效,在某种程度上,尽管 PHP 以科学记数法显示非常小的数字,这使得某些人难以阅读。

输入图片这里的描述

我尝试使用 number_format,尽管这需要小数点后的特定位数,这破坏了数字的“有效”部分(如果输入了一组数字),有时返回 0(对于数字小于设定数)。

解决方案是修改该函数以识别非常小的数字,然后对其使用 number_format - 将科学记数法位数作为 number_format 的位数:

function roundRate($rate, $digits)
{
    $mod = pow(10, intval(round(log10($rate))));
    $mod = $mod / pow(10, $digits);
    $answer = ((int)($rate / $mod)) * $mod;
    $small = strstr($answer,"-");
    if($small)
    {
        $answer = number_format($answer,str_replace("-","",$small));
    }
    return $answer;
}

该函数保留有效数字并以易于理解的方式呈现数字- 适合所有人阅读的格式。 对于科学家来说不是最好的,甚至不是长度最一致的“漂亮”数字,但总的来说,它是满足我们需要的最佳解决方案。)

(我知道,这 net/OA0VL.png" rel="nofollow noreferrer">在此处输入图像描述

While the functions here worked, I needed significant digits for very small numbers (comparing low-value cryptocurrency to bitcoin).

The answer at Format number to N significant digits in PHP worked, somewhat, though very small numbers are displayed by PHP in scientific notation, which makes them hard for some people to read.

enter image description here

I tried using number_format, though that needs a specific number of digits after the decimal, which broke the 'significant' part of the number (if a set number is entered) and sometimes returned 0 (for numbers smaller than the set number).

The solution was to modify the function to identify really small numbers and then use number_format on them - taking the number of scientific notation digits as the number of digits for number_format:

function roundRate($rate, $digits)
{
    $mod = pow(10, intval(round(log10($rate))));
    $mod = $mod / pow(10, $digits);
    $answer = ((int)($rate / $mod)) * $mod;
    $small = strstr($answer,"-");
    if($small)
    {
        $answer = number_format($answer,str_replace("-","",$small));
    }
    return $answer;
}

This function retains the significant digits as well as presents the numbers in easy-to-read format for everyone. (I know, it is not the best for scientific people nor even the most consistently length 'pretty' looking numbers, but it is overall the best solution for what we needed.)

enter image description here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文