Avatar billede tofte Juniormester
01. juni 2007 - 16:27 Der er 8 kommentarer og
1 løsning

Formatering af tal

Hej

Jeg er ret ny i php men har et lille problem.

Hvis jeg har et tal som følger :
0.0012345
Er der en måde at formatere tallet på, så det bliver til
1.23E3 altså så jeg kan få "videnskablig" formatering med 2 eller 3 decimaler.

Rasmus
Avatar billede maqhem Nybegynder
01. juni 2007 - 17:45 #1
Nu er der helt sikkert også nemmere måder, men jeg tænkte, det kunne være en sjov udfordring, og da jeg ikke er en haj til PHP, løste jeg det nogenlunde matematisk:

<?php
    function Scientific($num) {
        $cz = 0;
        $b = floor($num);
        $a = $num - $b;
        $o = "";
       
        for($i = 10; floor($a * $i) < 1; $i *= 10) {
            $cz++;
        }
        if($b > 0) {
            $o = $b;
        }
        $nn = round($num * pow(10, $cz + 3));
        return $o . $nn / pow(10, floor(log($nn, 10))) . "E" . ($cz + 1);
    }
    $n = 0.0012345;
    echo Scientific($n);
?>
Avatar billede maqhem Nybegynder
01. juni 2007 - 17:52 #2
Ej den er jo fuld af fejl, jeg prøver lige igen. Øjeblik.
Avatar billede maqhem Nybegynder
01. juni 2007 - 17:55 #3
Nu ved jeg, hvorfor den er så fuld af fejl. Det er fordi, jeg bare har gjort det samme som dig jo. 0.0012345 er ikke det samme som 1.23E3, da 1.23E3 er 1234.5 for lige at gøre det lidt mere præcist, og det stemmer jo slet ikke.
Avatar billede maqhem Nybegynder
01. juni 2007 - 18:01 #4
Vi prøver da lige igen så, og denne gang lidt mere spændende:

<?php
    function Scientific($num, $dig) {
        $cz = 0;
        $b = floor($num);
        $a = $num - $b;
        $o = "";
       
        for($i = 10; floor($a * $i) < 1; $i *= 10) {
            $cz++;
        }
        if(floor($num) == $num || $cz < 2) {
            return $num;
        }
        if($b > 0) {
            $o = $b;
        }
        $nn = round($num * pow(10, $cz + $dig + 1));
        return (floor($num) == $num || $cz < 2) ? $num : ($o . $nn / pow(10, floor(log($nn, 10))) . "E-" . ($cz + 1));
    }
    $n = 0.000123456;
    echo Scientific($n, 3);
?>
Avatar billede maqhem Nybegynder
01. juni 2007 - 18:50 #5
Okay nu er det ved at blive lidt for dårlig en vane, at mine scripts ikke duer.

<?php
    function Scientific($num, $dig) {
        $cz = 0;
        $b = floor($num);
        $a = $num - $b;
     
        for($i = 10; floor($a * $i) < 1; $i *= 10) {
            $cz++;
        }
        if(floor($num) == $num || $cz < 2) {
            $o = $num;
        } else {
            $nn = round($a * pow(10, $cz + $dig + 1));
            $o = (($b > 0) ? ($b * pow(10, $cz)) : "") . $nn / pow(10, floor(log($nn, 10))) . "E-" . ($cz + 1);
        }
        return $o;
    }
    $n = 0.000123456;
    echo Scientific($n, 3);
?>

Nu duer det funktionelt.
Avatar billede maqhem Nybegynder
01. juni 2007 - 19:59 #6
Scriptet er godt nok fejlfrit, men jeg kom til at tænke på, at facit kunne stilles bedre op. Hvis n sættes til 940.0000123456, skal den jo ikke være 94000001.23E-5 men 940+1.235E-5. Og så kom jeg også i tanker om, at 9400000 jo også videnskabeligt kan forkortes til 94E5, så jeg tilføjede lige en parameter mere. mtz definerer, som det er heltallet eller decimalerne, som afrundes videnskabeligt. "int" betyder heltal; "dig" betyder decimaltal; "comb" betyder begge to:

<?php
    function Scientific($num, $dig, $id) {
        $cz = 0;
        $b = floor($num);
        $a = $num - $b;
        if($id == "dig") {
            for($i = 10; floor($a * $i) < 1; $i *= 10) {
                $cz++;
            }
            if(floor($num) == $num || $cz < 2) {
                $o = $num;
            } else {
                $nn = round($a * pow(10, $cz + $dig + 1));
                $o = (($b > 0) ? $b . "+" : "") . $nn / pow(10, floor(log($nn, 10))) . "E-" . ($cz + 1);
            }
        } elseif($id == "int") {
            $num = round($num);
            $cz = floor(log($num, 10));
            for($i = 0; $i < $cz; $i++) {
                $num /= 10;
                if(floor($num) != $num) {
                    $o = $num;
                    break;
                }
            }
            $o /= pow(10, $dig - 1);
            $o = $o . "E" . ($cz + $dig - 1);
        } elseif($id == "comb") {
            $o = Scientific($b, $dig[0], "int") . "+" . Scientific($a, $dig[1], "dig");
        }
        return $o;
    }
    $n = 9400000.0000123456;
    echo "Tal: " . $n;
    echo "<br />";
    echo "Heltal: " . Scientific($n, 1, "int");
    echo "<br />";
    echo "Decimaltal: " . Scientific($n, 3, "dig");
    echo "<br />";
    echo "Kombination: " . Scientific($n, Array(0, 3), "comb");
?>
Avatar billede maqhem Nybegynder
01. juni 2007 - 19:59 #7
Jeg omdøbte variablen mtz til id, lad dig ikke forvirre af dette.
Avatar billede tofte Juniormester
03. juni 2007 - 13:35 #8
Tak for dit svar. Jeg har rettet lidt i det så det dækker mine behov. Men det overordnede er som du beskriver det. Tak for hjælpen.
Avatar billede maqhem Nybegynder
03. juni 2007 - 13:45 #9
Det var så lidt :)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester